Communitygithub.com

Lumos12345/비디오-텍스트-추출

로컬 비디오/오디오에서 타임스탬프가 포함된 가사/자막을 추출합니다: whisper 전사 + 하드서브(화면에 내장된) 텍스트 OCR.

비디오-텍스트-추출란 무엇인가요?

이 스킬은 로컬 미디어 파일(MP4, M4S, MKV, M4A, MP3)에서 타임스탬프가 포함된 가사 또는 자막 파일을 생성합니다. 주로 소프트 자막 트랙이 없지만 화면에 가사가 내장된 비디오(하드서브)나 오디오만 있는 경우를 처리합니다. Bilibili/YouTube 다운로드 파일, 노래방/AMV/뮤직비디오 등에 유용하며, LRC 또는 SRT 형식의 출력을 지원합니다. 이 스킬은 파이프라인 방식으로 작동합니다: 먼저 ffprobe로 파일을 검사하고, 소프트 자막이 있으면 직접 추출합니다. 그렇지 않으면 비디오에 하드서브가 있는 경우 OCR(Tesseract + vision 모델 하이브리드)을 사용하고, 오디오만 있는 경우 faster-whisper로 음성 인식합니다. 이 스킬은 guitar-tabs 스킬과 연계되어 LRC 파일을 코드 악보 생성에 직접 전달할 수 있습니다. 주의할 점은 M4S 파일이 일반적으로 비디오 전용이므로 오디오 파일을 별도로 찾아야 하며, whisper가 노래 가사를 잘못 인식할 수 있으므로 화면 텍스트가 있다면 OCR 결과를 우선시해야 합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add Lumos12345/video-text-extraction

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

비디오 / 오디오 텍스트 추출

로컬 미디어 파일(.mp4, .m4s, .mkv, .m4a, .mp3)에서 타임스탬프가 포함된 전사 파일 또는 가사 파일을 생성합니다. 다운로드한 비디오에 소프트 자막 트랙이 없지만 화면에 내장된(하드서브) 텍스트가 있는 일반적인 경우와, 오디오만 있는 경우를 처리합니다.

사용 시기

  • "이 비디오에서 가사/자막을 추출하고 각 줄의 시작 시간을 표시해줘."
  • "이 오디오를 타임스탬프와 함께 전사해줘."
  • 다운로드한 Bilibili/YouTube .m4s/.m4a 파일; 노래방/AMV/뮤직비디오 등 가사가 영상에 렌더링된 경우.
  • .lrc 또는 .srt 스타일 출력이 필요한 모든 요청.

0단계 — 항상 먼저 검사

ffprobe -v quiet -print_format json -show_streams -show_format FILE | python3 -m json.tool

알아야 할 핵심 사항:

  • 존재하는 스트림. Bilibili의 .m4s는 종종 비디오 전용입니다(오디오는 별도의 .m4s/.m4a에 있음). 오디오 스트림이 없으면 같은 폴더에서 재생 시간이 일치하는 동반 오디오 파일을 찾으세요.
  • 소프트 자막? ffprobe ... -select_streams s — 자막 스트림이 있으면 직접 추출하고(ffmpeg -i FILE -map 0:s:0 out.srt), 모든 OCR/whisper 작업을 건너뜁니다. 이것이 가장 빠른 방법입니다.
  • 재생 시간. 비디오에 오디오가 없을 때 올바른 오디오 파일을 매칭하는 데 사용합니다.
  • 제목/크레딧 카드는 자막 영역이 아닙니다. 프레임 ~0은 종종 실제 가사 자막과는 다른 위치와 글꼴로 큰 제목 + 연주자 오버레이를 가지고 있습니다. 여기서 크롭 좌표를 유추하면 모든 가사를 놓치는 영역이 생성됩니다. 대신 노래 중간(긴 가사 줄이 보이는) 프레임을 샘플링하세요. 그리고 노래/아티스트 이름이 필요하면 제목 카드는 따로 읽으세요.
  • 전사하기 전에 어떤 노래인지 확인하세요. 파일 이름과 제목 카드가 사용자가 부르는 곡명과 다를 수 있습니다. 오디오/가사가 예상하는 이름과 일치하지 않으면 전체 전사를 생성하기 전에 말하고, 비디오가 여러 곡 중 하나이면 실제로 전사한 곡을 명시하세요.

1단계 — 텍스트 소스 결정 (우선순위)

  1. 소프트 자막 스트림 → 직접 추출. 완료.
  2. 화면에 내장된 텍스트 (하드서브) → 프레임 OCR (3단계). 공식적이고 철자가 올바른 텍스트를 제공합니다. 비디오에 가사/자막이 보이면 항상 이것을 선호하세요.
  3. 오디오 전용, 화면 텍스트 없음 → whisper 전사 (2단계).

화면 텍스트와 오디오 전사가 모두 존재하면 단어는 OCR을 사용하고, 타이밍/방향은 whisper를 사용하세요 — OCR 텍스트는 철자가 정확하고, whisper는 타이밍 그리드를 정확히 맞추지만 노래 가사를 심하게 잘못 인식합니다(예: "petals"를 "pedophiles"로, 노래 모음을 "fry right"로 들음). 서로 교차 확인하세요.

2단계 — 오디오 전사 (whisper)

한 번 설치 (중국 본토 HF 미러 수정은 references/whisper-setup.md 참조):

uv venv /tmp/wvenv
/tmp/wvenv/bin/python -m pip install faster-whisper

16kHz 모노 WAV 추출, 선택적으로 노멀라이즈:

ffmpeg -y -i AUDIO -af "loudnorm=I=-16:TP=-1.5:LRA=11,highpass=f=80" -ar 16000 -ac 1 -c:a pcm_s16le /tmp/song.wav

전사 (scripts/transcribe.py 스크립트 사용):

HF_HUB_DISABLE_XET=1 HF_ENDPOINT=https://hf-mirror.com \
  /tmp/wvenv/bin/python scripts/transcribe.py /tmp/song.wav medium
  • medium 모델이 가장 좋은 균형점입니다. large-v3는 더 정확하지만 CPU에서 느립니다.
  • CPU(int8)에서 medium은 약 2.5분짜리 노래를 몇 분 안에 전사합니다. 프로세스는 모델 로드 중에 RSS가 낮게 유지되다가 실제 전사 시 약 1.4GB RSS로 증가합니다 — 로드 중에 당황하여 종료하지 말고, 대신 /proc/<pid>/status VmRSS를 확인하세요.
  • 노래에 VAD 필터링을 사용하지 마세요. vad_filter=True는 조용하거나 잔향이 있는 보컬 라인을 삭제하여 3분짜리 노래를 몇 개의 세그먼트로 줄일 수 있습니다. 전체 트랙을 전사하세요.
  • 작동하는 "노래" 튜닝(VAD 없음): beam_size=5, condition_on_previous_text=True, 온도 폴백 [0.0,0.2,0.4,0.6,0.8,1.0], no_speech_threshold=0.8, log_prob_threshold=-1.5, compression_ratio_threshold=2.8, word_timestamps=True, hallucination_silence_threshold=1.5. (기본값은 전체 구문을 삭제하고 악기 간격에 침묵-환각을 출력합니다.)

3단계 — 화면 내장 텍스트 OCR (고가치 경로)

전체 플레이북: references/hardsub-ocr.md. 요약:

  1. sudo 없이 tesseract 설치 — .deb 파일을 프리픽스에 추출(자세한 내용은 참조 문서 참조). liblept.so.5 및 libarchive.so.13에 대한 심볼릭 링크 수정이 문서화되어 있습니다.
  2. 텍스트 영역 찾기: vision_analyze로 한 프레임을 읽고 자막 영역의 픽셀 좌표를 요청하세요. 뮤직비디오에서 자막은 보통 왼쪽 아래에 있습니다 — 추측하지 마세요.
  3. 프레임을 조밀하게 추출: ffmpeg -i SRC -vf fps=2 /tmp/frames/f_%04d.png (2fps → 약 0.5초 해상도; 프레임 N은 t = N/2초에 위치).
  4. 영역을 크롭하고, 2~3배 확대하고, 그레이스케일로 변환한 후 각 프레임에 OCR 적용 (--psm 6 또는 --psm 7).
  5. 중복 제거: 같은 줄이 반복되는 연속 프레임 = 하나의 가사 줄; 첫 번째 깨끗한 읽기가 시작 시간을 제공합니다.
  6. 저대비 텍스트: vision_analyze로 폴백. Tesseract는 밝은/사진 배경 위의 흐린 세리프 텍스트에 실패합니다. 비전 모델이 이를 안정적으로 읽습니다 — Tesseract가 쓰레기를 반환하는 프레임에 비전 모델을 사용하세요. 이 하이브리드(Tesseract 대량 처리 + 비전 부분 채움)가 프로덕션 패턴입니다.

출력

사용자가 가사 + 타임스탬프를 요청하면 .lrc([mm:ss.xx]line)를 생성하고, 그렇지 않으면 일반 MM:SS text를 생성합니다. 사용자가 지정한 경로에 저장합니다(일반적으로 WSL에서 Windows 바탕 화면, 예: /mnt/c/Users/<user>/Desktop/).

연계: 여기서 생성한 .lrc는 guitar-tabs 스킬이 LRC 동기화 코드 차트/줄별 코드 정렬을 위해 정확히 입력으로 필요로 하는 것입니다. 가사-후-타브 요청이 하나의 작업으로 들어오면 .lrc를 유지하고 guitar-tabs에 직접 전달하세요(scripts/chord_analyze.py는 <audio> <lyrics.lrc>를 받아 가사 줄당 코드를 출력합니다). 두 스킬은 연결됩니다: video-text-extraction → 타임스탬프 가사 → guitar-tabs → 연주 악보.

함정

  • .m4s는 보통 비디오 전용입니다. 오디오가 있다고 가정하지 마세요. 재생 시간으로 동반 오디오 파일을 매칭하세요.
  • 노래 보컬에 대해 whisper 철자를 신뢰하지 마세요. 가능하면 화면 텍스트와 대조하세요.
  • VAD는 조용한 보컬을 죽입니다 — 2단계 참조.
  • Tesseract는 정확한 크롭이 필요합니다. 수직으로 약 100픽셀만 벗어나도 노이즈를 반환합니다. 먼저 비전으로 좌표를 얻으세요.
  • Tesseract의 공유 라이브러리 의존성은 하나씩 나타납니다. 실행할 때마다 다른 error while loading shared libraries: X로 죽습니다 — liblept.so.5, 그다음 libarchive.so.13, 그다음 libgif.so.7 등. 포기하지 말고 명령어 하나씩 설치하지 마세요: 전체 목록을 한 번에 다운로드하고(참조 문서 참조), 추출한 후 ldd … | grep "not found"로 한 번에 아직 누락된 모든 것을 확인하세요. 추가 주의사항 두 가지: 최신 Ubuntu에서 libarchive13은 후보가 없습니다(libarchive13t64 사용), 그리고 liblept5가 실제 liblept.so.5.0.4를 포함하는 패키지입니다 — -dev 패키지는 매달린 심볼릭 링크만 제공합니다.
  • 짧거나 깨진 OCR 읽기는 종종 OCR 문제가 아니라 크롭 문제입니다. --psm이나 임계값을 조정하기 전에, 크롭된 영역 자체에 대해 vision_analyze를 사용하세요. 비전도 텍스트를 보지 못하면 크롭이 잘못된 것입니다. 이 한 번의 확인으로 불필요한 필터 튜닝을 많이 절약할 수 있습니다.
  • export / 파이프가 있는 터미널 명령어는 승인이 필요할 수 있습니다. tesseract 환경 변수를 .sh 스크립트로 묶고 인라인 export ...; tesseract ... 대신 bash script.sh를 실행하세요.
  • 중국 본토에서 HuggingFace는 느리거나 차단됩니다. 항상 HF_ENDPOINT=https://hf-mirror.com AND HF_HUB_DISABLE_XET=1(xet 백엔드가 미러에 대해 401 오류를 반환함)을 설정하세요.
  • 모델 다운로드가 실제로 진행 중인지 확인하세요. 약 5MB RSS와 0 CPU jiffies에서 멈춘 faster-whisper 실행은 모델을 가져오는 데 멈춘 것입니다; 실제 실행은 약 1.4GB RSS로 증가합니다. 맹목적으로 종료하거나 기다리지 말고 /proc/<pid>/status(VmRSS)를 검사하세요.

관련 스킬