Whisper API로 유튜브 영상 자동 자막 요약 만들기

1시간짜리 강의 영상, 받아쓰기 3시간 걸리던 게 2분으로 줄었다

한때는 1시간짜리 온라인 강의를 보면서 중요한 내용을 필기하는 데 2~3시간씩 썼다. 그 과정이 너무 비효율적이라 문득 AI를 써보면 어떨까 생각했다. 마침 OpenAI에서 나온 Whisper API를 발견했는데, 이게 생각보다 훨씬 정확하고 빠르더라.

Whisper는 음성을 텍스트로 변환하는 AI 모델인데, 한국어 인식률이 꽤 괜찮다. 유튜브 영상에서 음성을 추출해 Whisper에 넘긴 뒤, GPT로 핵심만 요약하면 1시간짜리 영상 내용이 2분 만에 텍스트로 정리된다. 직접 해보니 전체 과정을 자동화하는 코드가 꽤 직관적이라 바로 공유하려 한다.



1. Whisper API 개요와 비용 구조

OpenAI Whisper API는 음성 파일을 텍스트로 변환하는 STT(Speech-To-Text) 서비스다. 한국어를 포함해 100개 이상의 언어를 지원한다. 요금은 오디오 1분당 약 $0.006으로, 1시간짜리 영상이라도 약 360원 정도밖에 안 든다. 비용 대비 처리 속도와 정확도 면에서 현존하는 STT 서비스 중 손에 꼽힌다.

로컬에서 Whisper 모델을 직접 돌리는 오픈소스 버전도 있다. 하지만 GPU 없는 일반 PC에서는 속도가 너무 느려서 1시간 분량 영상을 처리하는 데 20~30분이 걸렸다. 반면 API는 클라우드에서 1~2분 안에 끝내, 시간 대비 비용 차이가 압도적이다. 다만, API를 쓸 때도 긴 문장이나 전문 용어가 섞인 영상에서는 종종 오타가 나서 수동 교정이 필요했다. 또, 호출 지연이 간헐적으로 발생해 대량 작업 시에는 대기 시간이 쌓일 수 있다.

2. 개발 환경 준비 및 패키지 설치

  • Python 버전: 3.10 이상
  • 필수 외부 프로그램: ffmpeg (오디오 변환용, 별도 설치 필요)
  • 핵심 패키지: openai, yt-dlp, python-dotenv
  • 필요 API 키: OpenAI API 키
pip install openai yt-dlp python-dotenv

ffmpeg는 파이썬 패키지가 아니라 시스템 프로그램이라 따로 깔아야 한다. Windows라면 winget install ffmpeg 명령어로 쉽게 설치 가능하다. 설치 후 터미널을 재시작하고 ffmpeg -version으로 버전이 정상 출력되는지 꼭 확인해야 한다. 이걸 안 하면 오디오 추출 단계에서 아무런 알림 없이 실패하는 경우가 많아 골치 아프다.

3. 유튜브 다운로드 → 음성 추출 → 텍스트 변환 → 요약 전체 코드

1단계: 유튜브 영상에서 오디오만 추출

유튜브 영상을 통째로 받으면 용량이 너무 커서 저장 공간 잡아먹는 게 부담스러웠다. Whisper는 음성 데이터만 처리하니까 영상 전체가 아니라 오디오 트랙만 mp3 형식으로 뽑는 게 훨씬 낫다. yt-dlp 라이브러리는 이걸 한 줄로 해결한다는 점이 꽤 편리했다.

import yt_dlp
import os

def download_audio(youtube_url: str, output_path: str = "audio.mp3") -> str:
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": output_path.replace(".mp3", ""),
        "postprocessors": [{
            "key": "FFmpegExtractAudio",
            "preferredcodec": "mp3",
            "preferredquality": "128",  # 음성 인식용은 128kbps로 충분
        }],
        "quiet": True,
    }
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.download([youtube_url])
    print(f"오디오 추출 완료: {output_path}")
    return output_path

2단계: Whisper API로 음성을 텍스트로 변환

Whisper API가 처리할 수 있는 파일 크기 제한이 25MB로 꽤 빡빡했다. 저음질 128kbps mp3로 뽑아도 1시간 분량이면 약 55MB가 넘어서 바로 올릴 수 없었다. 그래서 저는 파일을 자동으로 10분 단위로 쪼개서 변환하는 방법을 썼다. 이런 분할 작업을 안 하면 애초에 API 호출에서 막힌다.

import os
import math
from openai import OpenAI
from dotenv import load_dotenv
from pydub import AudioSegment  # pip install pydub

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def transcribe_audio(audio_path: str) -> str:
    file_size_mb = os.path.getsize(audio_path) / (1024 * 1024)

    # 25MB 이하면 바로 변환
    if file_size_mb < 24:
        with open(audio_path, "rb") as f:
            result = client.audio.transcriptions.create(
                model="whisper-1",
                file=f,
                language="ko"  # 한국어 명시하면 정확도 향상
            )
        return result.text

    # 25MB 초과 시 10분 단위로 분할 처리
    print(f"파일 크기 {file_size_mb:.1f}MB — 분할 처리 시작")
    audio = AudioSegment.from_mp3(audio_path)
    chunk_ms = 10 * 60 * 1000  # 10분
    chunks = math.ceil(len(audio) / chunk_ms)
    full_text = []

    for i in range(chunks):
        start = i * chunk_ms
        end = min((i + 1) * chunk_ms, len(audio))
        chunk = audio[start:end]
        chunk_path = f"chunk_{i}.mp3"
        chunk.export(chunk_path, format="mp3")

        with open(chunk_path, "rb") as f:
            result = client.audio.transcriptions.create(
                model="whisper-1", file=f, language="ko"
            )
        full_text.append(result.text)
        os.remove(chunk_path)
        print(f"  [{i+1}/{chunks}] 변환 완료")

    return " ".join(full_text)

3단계: 변환된 텍스트를 GPT로 핵심 요약

Whisper로 받은 긴 스크립트를 GPT-4o-mini에 넘겨 핵심 내용을 정리하는 과정이다. 저는 여기서 단순 요약이 아니라, '구조화된 핵심 요점'을 뽑아내는 데 집중했다. 구체적으로는 '핵심 주제', '주요 내용(5줄 이내)', '기억할 키워드' 세 파트로 나눠 달라고 명령문을 짰는데, 의외로 이 부분에서 GPT가 중복되거나 쓸데없는 정보를 포함하는 경우가 꽤 있었다.

첨부한 코드를 보면, 긴 텍스트를 한꺼번에 처리하지 않고 앞부분 6000자까지만 넣는 게 핵심이다. 토큰 제한 때문에 어쩔 수 없는 선택인데, 이 때문에 긴 강의는 뒷부분 내용이 누락되는 문제가 있다. 이 점은 나중에 분할해서 요약하는 로직을 따로 만들어야 할 듯하다. 텍스트 파일로 결과를 저장하고 나면, 언제든 꺼내 볼 수 있는 편집된 '강의 노트'가 완성된다.

from openai import OpenAI

def summarize_transcript(transcript: str) -> str:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "당신은 강의 내용을 정리하는 전문 편집자입니다."},
            {"role": "user", "content": f"""다음 강의 스크립트를 아래 형식으로 정리하세요.
## 핵심 주제
## 주요 내용 (5줄 이내)
## 기억할 키워드

[스크립트]:
{transcript[:6000]}"""}  # 토큰 한도 고려해 앞부분 우선 처리
        ],
        temperature=0.3
    )
    return response.choices[0].message.content

# 전체 파이프라인 실행
if __name__ == "__main__":
    url = "https://www.youtube.com/watch?v=여기에_영상_ID"
    audio_file = download_audio(url)
    transcript = transcribe_audio(audio_file)
    summary = summarize_transcript(transcript)

    with open("lecture_notes.txt", "w", encoding="utf-8") as f:
        f.write("=== 전체 스크립트 ===n")
        f.write(transcript + "nn")
        f.write("=== AI 요약 ===n")
        f.write(summary)

    print("완료! lecture_notes.txt 저장됨")
    os.remove(audio_file)  # 임시 오디오 파일 삭제

4. 직접 맞은 에러 2가지와 해결법

에러 ① FileNotFoundError: ffmpeg — 환경변수 미등록

ffmpeg를 설치했는데도 FileNotFoundError: ffmpeg가 계속 발생했다. 원인은 단순했다. 설치 자체는 제대로 됐지만, 윈도우 시스템 환경변수 PATH에 ffmpeg bin 폴더 경로를 직접 등록하지 않아서였다. 터미널을 껐다 켜는 정도로는 해결되지 않았다. 직접 [시스템 속성] → [환경변수] → [Path]에 경로를 추가하고 터미널을 완전히 종료 후 재실행해야 했다. winget으로 설치하면 이 과정을 자동으로 처리하지만, 수동 설치 후에는 반드시 확인이 필요하다.

이 부분 때문에 한참 시간을 잡아먹었는데, 설치가 끝났다고 바로 작동하는 건 아니라는 점을 체감하게 됐다. 환경변수 설정은 특히 윈도우 초보자에게 헷갈리는 부분이라, 꼼꼼히 체크하는 편이 낫다.

에러 ② 한국어 인식률이 낮을 때 — language 파라미터 누락

처음엔 language 파라미터를 빼고 실행했다. Whisper가 자동으로 언어를 감지하지만, IT 강의처럼 한국어와 영어가 섞인 영상에서 가끔 영어로 인식해버리는 일이 자주 벌어졌다. 그 결과 한국어 부분이 이상하게 로마자로 음역되어 나오는 상황이 생겼다. 저는 한국어 정확도가 너무 떨어져서 당혹스러웠다. language="ko"를 명시하자 인식률이 확실히 개선됐다. 한국어 영상 처리할 때는 이 언어 코드를 꼭 지정해야 한다는 점을 체감했다.

5. 실전 활용 시나리오와 비용 계산

Whisper API를 직접 써보면서 어디에 쓸 만한지, 비용이 얼마나 나오는지 정리했다. 특히 비용 부분은 예상보다 저렴한 편이었는데, 영상 길이에 따라 비용과 처리 시간이 꽤 직관적으로 늘어났다.

활용 시나리오 영상 길이 Whisper 비용 처리 시간
온라인 강의 노트 자동 생성 60분 약 360원 약 90초
회의 녹음 자동 요약 30분 약 180원 약 45초
유튜브 인터뷰 자막 추출 20분 약 120원 약 30초

제가 가장 크게 느낀 변화는 강의를 들을 때마다 손으로 받아쓰던 수고가 사라졌다는 점이다. 영상이 재생되는 동안 자동으로 스크립트가 만들어지고, 영상이 끝나면 요약 파일이 완성된다. 다만, 모바일 환경에서 가끔 메뉴가 꼬여서 작업 흐름이 끊기는 문제가 있었는데, 이 부분은 꾸준히 개선이 필요할 듯하다. 그래도 남은 시간에는 내용 이해와 복습에 집중할 수 있어서 전반적인 학습 효율은 확실히 올랐다.