IT

YouTube 대본을 자동으로 웹 브라우저 콘솔에서 추출하는 방법

esmile1 2025. 1. 21. 23:45

YouTube 대본을 자동으로 웹 브라우저 콘솔에서 추출하는 방법

유튜브 동영상의 대본을 자동으로 추출하고 저장할 수 있는 JavaScript 스크립트를 소개합니다. 이 스크립트는 OpenAI API를 활용하여 동영상의 오디오를 텍스트로 변환합니다. 아래는 이 스크립트를 사용하는 방법과 주요 기능에 대한 설명입니다.


주요 기능

  1. 현재 보고 있는 유튜브 동영상의 URL을 자동으로 감지.
  2. 동영상 제목과 작성자를 페이지에서 직접 가져옴.
  3. 오디오 URL을 추출하고 다운로드.
  4. OpenAI의 Whisper 모델로 오디오를 텍스트로 변환.
  5. 변환된 텍스트를 로컬 파일로 저장.

사용 방법

1. 사전 준비

  • OpenAI API 키가 필요합니다. OpenAI 계정에서 API 키를 발급받아야 합니다.

2. 코드 실행

  1. 유튜브 동영상 페이지로 이동합니다.
  2. 브라우저 개발자 도구(Developer Console)를 엽니다:
    • Windows: F12 또는 Ctrl + Shift + J
    • Mac: Cmd + Option + J
  3. 아래 코드를 복사하여 콘솔에 붙여넣습니다.
  4. your-openai-api-key 부분을 본인의 OpenAI API 키로 대체합니다.
  5. 콘솔에 transcribe()를 입력하고 Enter를 누릅니다.

코드

class YouTubeTranscriber {
    constructor() {
        // Replace with your OpenAI API key
        this.OPENAI_API_KEY = 'your-openai-api-key';
    }

    async transcribeVideo(videoUrl = null) {
        try {
            if (!videoUrl) {
                videoUrl = window.location.href;
                if (!videoUrl.includes('youtube.com/watch')) {
                    throw new Error('Please run this script on a YouTube video page');
                }
            }

            console.log('🎬 Starting transcription for current video...');

            const videoId = this.extractVideoId(videoUrl);
            if (!videoId) throw new Error('Invalid YouTube URL');

            console.log('📝 Getting video details...');
            const videoInfo = await this.getVideoInfo(videoId);
            console.log(`📺 Video Title: ${videoInfo.title}`);

            console.log('🎵 Extracting audio URL...');
            const audioUrl = await this.getAudioUrl(videoId);

            console.log('⬇️ Downloading audio...');
            const audioBlob = await this.downloadAudio(audioUrl);

            console.log('🎯 Transcribing audio...');
            const transcript = await this.transcribeAudio(audioBlob);

            console.log('💾 Saving transcript...');
            this.saveTranscript(transcript, videoInfo.title);

            console.log('✅ Transcription completed successfully!');
            return transcript;
        } catch (error) {
            console.error('❌ Error:', error.message);
            throw error;
        }
    }

    extractVideoId(url) {
        const regExp = /^.*((youtu.be\\\\/)|(v\\\\/)|(\\\\/u\\\\/\\\\w\\\\/)|(embed\\\\/)|(watch\\\\?))\\\\??v?=?([^#&?]*).*/;
        const match = url.match(regExp);
        return (match && match[7].length === 11) ? match[7] : null;
    }

    async getVideoInfo(videoId) {
        try {
            const title = document.querySelector('h1.ytd-video-primary-info-renderer')?.textContent?.trim()
                      || document.title.replace(' - YouTube', '');
            const author = document.querySelector('ytd-channel-name yt-formatted-string')?.textContent?.trim();

            if (title) {
                return { title, author };
            }
        } catch (e) {
            console.log('Falling back to API for video info...');
        }

        const response = await fetch(`https://noembed.com/embed?url=https://www.youtube.com/watch?v=${videoId}`);
        const data = await response.json();
        return {
            title: data.title || `video_${videoId}`,
            author: data.author_name
        };
    }

    async getAudioUrl(videoId) {
        return `https://www.yt-download.org/api/button/mp3/${videoId}`;
    }

    async downloadAudio(url) {
        const response = await fetch(url);
        return await response.blob();
    }

    async transcribeAudio(audioBlob) {
        const formData = new FormData();
        formData.append('file', audioBlob, 'audio.mp3');
        formData.append('model', 'whisper-1');

        const response = await fetch('<https://api.openai.com/v1/audio/transcriptions>', {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${this.OPENAI_API_KEY}`
            },
            body: formData
        });

        if (!response.ok) {
            throw new Error(`Transcription failed: ${response.statusText}`);
        }

        const result = await response.json();
        return result.text;
    }

    saveTranscript(text, videoTitle) {
        const blob = new Blob([text], { type: 'text/plain' });
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `${videoTitle.replace(/[^a-zA-Z0-9]/g, '_')}_transcript.txt`;
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);
    }
}

console.clear();
console.log(`
🎥 YouTube Transcriber Console Tool
----------------------------------
To transcribe the current video, simply type:

transcribe()

The script will automatically use the current video URL.
`);

window.transcribe = async () => {
    if (!window.location.hostname.includes('youtube.com')) {
        console.error('❌ Please run this script on a YouTube video page');
        return;
    }

    if (!window.location.pathname.includes('/watch')) {
        console.error('❌ Please navigate to a YouTube video page first');
        return;
    }

    const transcriber = new YouTubeTranscriber();
    try {
        const transcript = await transcriber.transcribeVideo();
        console.log('\\\\n📄 Transcript Preview (first 500 characters):');
        console.log('------------------------------------------');
        console.log(transcript.slice(0, 500) + '...');
        console.log('\\\\n✅ Full transcript has been downloaded to your computer.');
    } catch (error) {
        console.error('❌ Failed to transcribe video:', error.message);
    }
};

console.log('%c Ready to transcribe current video! ', 'background: #28a745; color: white; padding: 5px; border-radius: 5px;');

if (window.location.hostname.includes('youtube.com') && window.location.pathname.includes('/watch')) {
    console.log('%c Current video detected! Type transcribe() to start ', 'background: #007bff; color: white; padding: 5px; border-radius: 5px;');
} else {
    console.log('%c Please navigate to a YouTube video page first ', 'background: #dc3545; color: white; padding: 5px; border-radius: 5px;');
}


30단계 세분화된 사용 방법

  1. OpenAI 계정 생성 및 로그인.
  2. OpenAI API 키 발급받기.
  3. 유튜브 동영상 페이지로 이동.
  4. 브라우저 개발자 도구 열기 (F12 또는 Ctrl+Shift+J).
  5. 제공된 코드를 복사.
  6. 콘솔 창에 코드 붙여넣기.
  7. 코드 내 your-openai-api-key를 본인의 API 키로 대체.
  8. Enter 키를 눌러 코드 실행.
  9. 콘솔에서 transcribe() 입력 후 Enter.
  10. 현재 페이지가 유효한 유튜브 동영상인지 확인 메시지 출력.
  11. 동영상 URL 자동 감지 및 확인.
  12. URL에서 동영상 ID 추출.
  13. 페이지에서 동영상 제목 및 작성자 정보 가져오기 시도.
  14. 실패 시 API를 통해 정보 가져오기 시도.
  15. 오디오 다운로드 URL 생성.
  16. 오디오 파일 다운로드 시작.
  17. 다운로드된 오디오 데이터를 Blob 형식으로 저장.
  18. Whisper 모델을 사용하여 오디오 텍스트 변환 요청 생성.
  19. OpenAI 서버에 변환 요청 전송.
  20. 응답 상태 확인 및 에러 처리.
  21. Whisper 모델이 반환한 텍스트 데이터 수신.
  22. 변환된 텍스트 데이터 미리보기 출력(첫 500자).
  23. 텍스트 데이터를 Blob으로 변환하여 다운로드 준비.
  24. 텍스트 파일 이름 설정(동영상 제목 기반).
  25. 다운로드 링크 생성 및 DOM에 추가.
  26. 다운로드 링크 클릭 이벤트 트리거하여 파일 저장 시작.
  27. 다운로드 완료 후 링크 DOM에서 제거 및 메모리 해제.
  28. 콘솔에 성공 메시지 출력 및 전체 프로세스 완료 알림.
  29. 에러 발생 시 상세 오류 메시지 출력 및 디버깅 지원 제공.
  30. 필요 시 다른 동영상으로 이동하여 반복 실행.

이 스크립트는 간단한 명령어 하나로 유튜브 대본 추출 작업을 자동화하며, 사용자는 기술적 지식 없이도 쉽게 사용할 수 있습니다!