* 목차 *

2026년 8월 13일 목요일

[바이브 코딩] Vrew 로고 없이 100% 자막·원어민 음성 고화질 동영상 만들기 - 단일 HTML 웹앱 제작법

💡 한 줄 요약

구글 슬라이드 PDF와 영문 대본만 넣으면 외부 툴의 로고 워터마크 없이 슬라이드 화면과 원어민 음성을 고화질로 자동 합성하여 MP4 동영상으로 저장해 주는 바이브 코딩 웹앱 제작 가이드입니다!

🎬 Vrew 워터마크 로고 고민 끝! 나만의 동영상 저장 웹앱 제작

구글 슬라이드를 PDF로 다운받고 Vrew(브루)에서 대본을 붙여넣어 동영상을 만들다 보면 첫 화면이나 영상 구석에 워터마크 로고가 노출되어 아쉬움이 남을 때가 있습니다.

이러한 불편함을 해결하기 위해 바이브 코딩(Vibe Coding)으로 구글 슬라이드 PDF와 영문 대본을 올리면, 브라우저가 영어로 동화를 읽어주는 동시에 깔끔한 고화질 슬라이드와 오디오를 100% 원본 그대로 녹화하여 MP4 영상으로 저장해 주는 웹앱을 직접 완성했습니다!

📊 타사 편집 프로그램(Vrew 등) vs 바이브 코딩 제작 웹앱 비교 표

구분 / 기능 항목 타사 영상 편집 프로그램 (Vrew 등) 바이브 코딩 순수 슬라이드 제작 웹앱 (추천 ⭐️)
워터마크 / 로고 노출 무료 플랜 이용 시 오프닝/엔딩 및 구석에 서비스 워터마크 노출 외부 로고나 UI 없이 100% 깔끔한 순수 슬라이드 화면만 저장
웹 브라우저 실행 방식 별도 프로그램 설치 및 클라우드 서버 렌더링 대기시간 발생 프로그램 설치 0개! 단일 HTML 파일로 브라우저에서 즉시 실행
음성-슬라이드 동기화 자막 구간 길이를 수동으로 일일이 맞추어야 함 TTS 낭독 완료 이벤트(`onend`)로 슬라이드 전환 시점 자동 동기화

✨ 완성본 웹앱을 생성한 핵심 프롬프트

아래 프롬프트를 제미나이나 클로드에 입력하면 동일하게 완벽 구동되는 순수 슬라이드 동영상 제작 웹앱 코드를 얻을 수 있습니다.

✨ [복사용] 고화질 키즈 동화책 MP4 영상 제작기 생성 프롬프트

"너는 전문 프론트엔드 웹 개발자야. 별도 서버나 프로그램 설치 없이 브라우저에서 단일 HTML 파일로 작동하는 [고화질 키즈 영어 동화책 MP4 영상 제작기]를 작성해 줘.

[주요 요구사항]
1. 입력: 구글 슬라이드 PDF 파일 업로드(pdf.js CDN 사용) + 슬라이드별 영문 대본 텍스트 영역(textarea).
2. 렌더링: Canvas 스케일 3.0 이상 고해상도로 슬라이드를 선명하게 렌더링할 것.
3. 오디오 & 동기화: Web Speech API(en-US, rate 0.85)로 슬라이드별 대본을 읽어주고, 낭독 종료 시점(onend)에 맞춰 자동으로 다음 슬라이드로 전환할 것.
4. 녹화 및 다운로드: MediaRecorder 및 navigator.mediaDevices.getDisplayMedia를 활용해 탭 오디오와 30 FPS Canvas 화면을 결합 녹화하고, 종료 시 MP4/WebM 동영상 다운로드 버튼을 띄울 것.
5. 디자인: 외부 버튼이나 UI가 녹화 화면에 들어가지 않고, 캔버스 슬라이드 영역과 오디오만 선명하게 합성되도록 모던한 레이아웃을 구축해 줘!"

💻 단일 HTML 웹앱 전체 소스 코드

위 프롬프트로 완성된 전체 소스 코드입니다. 복사하여 바탕화면에 index.html 파일로 저장한 뒤 사용하세요.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>고화질 키즈 영어 동화책 MP4 제작기 (완전판)</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>
  <style>
    body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f4f7f6; margin: 0; padding: 20px; }
    .container { max-width: 1100px; margin: 0 auto; background: white; padding: 25px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
    h1 { text-align: center; color: #2c3e50; }
    .guide-box { background: #eef7fe; border-left: 5px solid #3498db; padding: 12px 15px; margin-bottom: 20px; border-radius: 4px; font-size: 14px; line-height: 1.5; color: #2c3e50; }
    .input-section { display: flex; gap: 20px; margin-bottom: 20px; }
    .input-box { flex: 1; display: flex; flex-direction: column; }
    label { font-weight: bold; margin-bottom: 8px; color: #34495e; }
    textarea { height: 120px; padding: 10px; border: 1px solid #ccc; border-radius: 6px; resize: none; }
    input[type="file"] { padding: 8px; border: 1px solid #ccc; border-radius: 6px; }
    .controls { text-align: center; margin: 20px 0; }
    button { padding: 12px 22px; font-size: 15px; font-weight: bold; border: none; border-radius: 6px; cursor: pointer; margin: 0 5px; }
    .btn-play { background: #2ecc71; color: white; }
    .btn-stop { background: #e74c3c; color: white; }
    .btn-download { background: #8e44ad; color: white; display: none; animation: pulse 1.5s infinite; }
    @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } }
    #viewer-container { text-align: center; background: #111; padding: 10px; border-radius: 8px; margin-top: 10px; display: flex; justify-content: center; align-items: center; }
    canvas { max-width: 100%; height: auto; box-shadow: 0 0 15px rgba(0,0,0,0.8); border-radius: 4px; }
    .status { text-align: center; margin-top: 15px; font-weight: bold; font-size: 16px; color: #2980b9; }
  </style>
</head>
<body>

<div class="container">
  <h1>📚 고화질 순수 슬라이드 동영상 제작기</h1>
  
  <div class="guide-box">
    📌 <strong>사용 방법</strong><br>
    재생 버튼 클릭 시 나타나는 팝업창에서 <strong>[현재 탭]</strong> 선택 ➔ 하단의 <strong>'탭 오디오 공유'</strong> 체크박스를 반드시 켠 후 공유를 누르세요.<br>
    동영상 파일에는 외부 UI 없이 <strong>슬라이드 화면과 원어민 음성이 깨끗하게 합성</strong>되어 저장됩니다.
  </div>

  <div class="input-section">
    <div class="input-box">
      <label>1. 구글 슬라이드 PDF 파일 업로드</label>
      <input type="file" id="pdf-file" accept="application/pdf">
    </div>
    <div class="input-box">
      <label>2. 슬라이드별 영문 대본 (줄바꿈으로 구분)</label>
      <textarea id="script-text" placeholder="Slide 1 English text
Slide 2 English text
Slide 3 English text..."></textarea>
    </div>
  </div>

  <div class="controls">
    <button class="btn-play" onclick="startPresentation()">▶ 고화질 슬라이드 녹화 시작</button>
    <button class="btn-stop" onclick="stopPresentation()">⏹ 정지</button>
    <button id="download-btn" class="btn-download" onclick="downloadVideo()">💾 MP4 동영상 다운로드</button>
  </div>

  <div id="viewer-container">
    <canvas id="pdf-render"></canvas>
  </div>
  
  <div class="status" id="status-text">PDF 파일과 대본을 입력한 후 재생 버튼을 누르세요.</div>
</div>

<script>
  pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js';

  let pdfDoc = null;
  let currentPage = 1;
  let lines = [];
  let isPlaying = false;
  
  let mediaRecorder = null;
  let recordedChunks = [];
  let recordedBlob = null;
  let displayStream = null;
  let animFrameId = null;

  const canvas = document.getElementById('pdf-render');
  const ctx = canvas.getContext('2d');

  document.getElementById('pdf-file').addEventListener('change', function(e) {
    const file = e.target.files[0];
    if (file) {
      const fileReader = new FileReader();
      fileReader.onload = function() {
        const typedarray = new Uint8Array(this.result);
        pdfjsLib.getDocument(typedarray).promise.then(pdf => {
          pdfDoc = pdf;
          renderPage(1);
          document.getElementById('status-text').innerText = `총 ${pdf.numPages}페이지 PDF가 로드되었습니다.`;
        });
      };
      fileReader.readAsArrayBuffer(file);
    }
  });

  // 3.0 스케일 (고해상도 렌더링)
  function renderPage(num) {
    if (!pdfDoc) return;
    pdfDoc.getPage(num).then(page => {
      const scale = 3.0;
      const viewport = page.getViewport({ scale: scale });
      canvas.height = viewport.height;
      canvas.width = viewport.width;

      const renderContext = {
        canvasContext: ctx,
        viewport: viewport
      };
      page.render(renderContext);
    });
  }

  // 캔버스 검은 화면 방지를 위한 연속 렌더링 루프
  function keepCanvasAlive() {
    if (isPlaying) {
      ctx.fillStyle = "rgba(0,0,0,0.0001)";
      ctx.fillRect(0, 0, 1, 1);
      animFrameId = requestAnimationFrame(keepCanvasAlive);
    }
  }

  async function startPresentation() {
    if (!pdfDoc) {
      alert("PDF 파일을 먼저 업로드해 주세요.");
      return;
    }
    const rawText = document.getElementById('script-text').value.trim();
    if (!rawText) {
      alert("영문 대본을 입력해 주세요.");
      return;
    }

    lines = rawText.split('\n').filter(line => line.trim() !== '');
    
    try {
      displayStream = await navigator.mediaDevices.getDisplayMedia({
        video: true,
        audio: true
      });
    } catch (err) {
      alert("화면/오디오 공유가 취소되었습니다.");
      return;
    }

    const audioTrack = displayStream.getAudioTracks()[0];
    const canvasStream = canvas.captureStream(30);
    const videoTrack = canvasStream.getVideoTracks()[0];

    const combinedTracks = [videoTrack];
    if (audioTrack) {
      combinedTracks.push(audioTrack);
    }
    const recordStream = new MediaStream(combinedTracks);

    currentPage = 1;
    isPlaying = true;
    recordedChunks = [];
    document.getElementById('download-btn').style.display = 'none';

    keepCanvasAlive();

    let options = { mimeType: 'video/webm;codecs=vp9' };
    if (MediaRecorder.isTypeSupported('video/mp4')) {
      options = { mimeType: 'video/mp4' };
    }

    try {
      mediaRecorder = new MediaRecorder(recordStream, options);
    } catch (e) {
      mediaRecorder = new MediaRecorder(recordStream);
    }

    mediaRecorder.ondataavailable = function(e) {
      if (e.data.size > 0) {
        recordedChunks.push(e.data);
      }
    };

    mediaRecorder.onstop = function() {
      const mime = mediaRecorder.mimeType || 'video/mp4';
      recordedBlob = new Blob(recordedChunks, { type: mime });
      document.getElementById('download-btn').style.display = 'inline-block';
    };

    mediaRecorder.start();
    playSlide(0);
  }

  function playSlide(index) {
    if (!isPlaying || index >= pdfDoc.numPages || index >= lines.length) {
      finishPresentation();
      return;
    }

    currentPage = index + 1;
    renderPage(currentPage);

    const currentText = lines[index] || "";
    document.getElementById('status-text').innerText = `[${currentPage} / ${pdfDoc.numPages} 슬라이드] 낭독 및 고화질 녹화 진행 중...`;

    if (currentText.trim() !== '') {
      const utterance = new SpeechSynthesisUtterance(currentText);
      utterance.lang = 'en-US';
      utterance.rate = 0.85;

      utterance.onend = function() {
        if (isPlaying) {
          setTimeout(() => { playSlide(index + 1); }, 1500);
        }
      };
      window.speechSynthesis.speak(utterance);
    } else {
      setTimeout(() => { playSlide(index + 1); }, 3000);
    }
  }

  function finishPresentation() {
    isPlaying = false;
    window.speechSynthesis.cancel();

    if (animFrameId) {
      cancelAnimationFrame(animFrameId);
    }

    if (mediaRecorder && mediaRecorder.state !== 'inactive') {
      mediaRecorder.stop();
    }

    if (displayStream) {
      displayStream.getTracks().forEach(track => track.stop());
    }

    document.getElementById('status-text').innerText = "🎉 슬라이드쇼 재생 및 녹화가 성공적으로 완료되었습니다! 아래 버튼을 눌러 저장하세요.";
  }

  function stopPresentation() {
    finishPresentation();
    document.getElementById('status-text').innerText = "재생 및 녹화가 수동 정지되었습니다.";
  }

  function downloadVideo() {
    if (!recordedBlob) return;
    const url = URL.createObjectURL(recordedBlob);
    const a = document.append ? document.createElement('a') : document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    a.download = 'storybook_clean_hd_video.mp4';
    document.body.appendChild(a);
    a.click();
    setTimeout(() => {
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    }, 100);
  }
</script>

</body>
</html>
  

💡 초보자를 위한 바이브 코딩 실전 사용 방법

📋 고화질 슬라이드 동영상 녹화 3단계 순서

  1. 위 소스 코드를 복사하여 바탕화면에 동영상제작.html 파일로 저장한 뒤 더블클릭해 웹 브라우저에서 실행합니다.
  2. 구글 슬라이드에서 다운받은 PDF 파일과 슬라이드별 영문 대본을 각각 입력창에 업로드합니다.
  3. [▶ 고화질 슬라이드 녹화 시작] 버튼 클릭 ➔ 팝업창에서 [현재 탭] 선택 및 하단 '탭 오디오 공유' 체크 ➔ 슬라이드 낭독 완료 후 생성되는 [💾 MP4 동영상 다운로드] 버튼을 클릭해 워터마크 없는 깨끗한 영상 파일을 보관하세요!

🎯 에디터 한줄평

타사 편집 프로그램의 워터마크 로고 노출 걱정 없이, 내 브라우저에서 100% 무료로 깔끔한 원어민 낭독 슬라이드 동영상을 직접 제작해 보세요!

📚 바이브 코딩 슬라이드 동영상 제작 가이드

구글 슬라이드 PDF와 영문 대본을 활용하여 워터마크 없는 고화질 동영상 웹앱을 제작하고 활용해 보세요.