비디오 분석 — 보이는 것, 말해지는 것
당신은 직접 비디오나 오디오를 입력받지 않습니다. 비디오에서 추출된 이미지와 오디오 트랜스크립트를 읽습니다. 아래 모든 과정은 비디오를 이 두 가지 형태로 변환한 후, 과장하지 않고 읽는 방법을 알려줍니다.
파일 위치 — 소유자의 엄격한 규칙
모든 추출 자료는 비디오 파일 옆에 하나의 작업 폴더에 저장됩니다:
<비디오 폴더>\<비디오 이름>.analysis\ — 절대 스크래치패드, 임시 디렉토리, 프로젝트 폴더에 저장하지 마십시오.
소유자는 해당 비디오 작업이 끝나면 이 폴더를 삭제하여 디스크 공간을 확보합니다.
스스로 삭제하지 마십시오. 정리 요청을 받으면 trash 스킬을 사용하여 정확히 그 폴더를 휴지통으로 보내십시오(rm 사용 금지). 당신이 작성한 분석 결과물(인도물)은 프로젝트가 원하는 곳에 위치해야 하며, .analysis 폴더 안에 두지 마십시오. 그래야 폴더를 비워도 가치 있는 내용이 손실되지 않습니다.
1. 도구 (머신당 한 번)
python ~/.claude/skills/video-analysis/scripts/setup_tools.py --check # 확인
python ~/.claude/skills/video-analysis/scripts/setup_tools.py # 누락된 항목 설치
다음을 pip --user로 설치합니다: imageio-ffmpeg(ffmpeg 바이너리 번들 — 시스템 ffmpeg, 관리자 권한, winget/choco 불필요), Pillow, numpy, faster-whisper, 그리고 Whisper small 모델을 캐싱합니다(유일한 네트워크 접근; 이후는 완전 오프라인). 종료 코드 0 = 준비 완료.
셀프 테스트(합성 비디오, 9개 검사, --full은 Whisper 포함):
python ~/.claude/skills/video-analysis/scripts/selftest.py
2. 추출
python ~/.claude/skills/video-analysis/scripts/extract_video.py "<비디오 경로>" --language ko
몇 분 이상의 비디오는 백그라운드에서 실행하십시오: 트랜스크립션은 CPU에서 실시간의 약 5배 속도로 실행됩니다(15분 비디오는 약 3분 소요). 옵션: --interval 5(프레임 간격(초); 빠르게 움직이는 화면은 2, 말하는 사람 위주는 10-15 사용), --model small(medium = 더 좋지만 3배 느림), --skip-frames, --skip-transcript, --at HH:MM:SS[.mmm](반복 가능, 정확한 순간의 전체 해상도 프레임 — 3d단계에서 사용).
<비디오>.analysis\에 생성: frames\(매 간격마다), sheets\(3x3 접촉 시트, 각 이미지에 mm:ss가 노란색으로 표시됨), keyframes.txt + keysheets\(시각적으로 변경된 프레임만 — 슬라이드/화면 변경), audio.wav, transcript.txt([mm:ss] 텍스트) + transcript.json, at\, manifest.json. 재실행 시 완료된 단계는 건너뛰고 계속 진행합니다. 매개변수 변경 또는 다른 비디오는 **거부(종료 코드 3)**되어 출력이 혼합되지 않습니다. 종료 코드 1 = 처리 실패, 2 = 잘못된 입력.
3. 읽기 — 다음 순서대로
a. 전체 트랜스크립트를 먼저 (transcript.txt). 강의와 데모에서 결정적인 내용(숫자, 규칙, 예외, 실제 방법)은 화면이 아닌 음성에 있는 경우가 매우 많습니다.
b. 키프레임 시트 (keysheets\) — 각각의 다른 슬라이드/화면을 한 번씩 확인합니다.
c. 접촉 시트 (sheets\) — 모두 순서대로 보면서 키프레임 사이에서 움직이는 것(커서, 그림, 업데이트되는 차트)을 추적합니다.
d. 음성이 가리키는 곳을 확대: 화자가 "여기", "이 양초", "...을 보세요"라고 말할 때, 첫 번째 실행과 동일한 옵션으로 --at <타임스탬프>를 다시 실행하고(그렇지 않으면 매니페스트 검사가 종료 코드 3으로 거부), 해당 전체 해상도 프레임을 읽습니다. 시트는 셀당 640px로 차트 레이블이나 작은 텍스트를 읽기에는 너무 작습니다.
e. 분석 작성(4단계).
4. 보고 — 세 가지를 분리하여 유지
각 구간에 대해 타임스탬프를 인용하고 모든 진술을 다음 중 하나로 표시하십시오:
- 화면에 표시 — 이미지가 실제로 보여주는 것(슬라이드 텍스트, 차트, 주석, UI).
- 음성으로 말해짐 — 음성이 말하는 것(인용 또는 가까운 의역,
[mm:ss]포함). - 추론 — 둘을 연결하는 당신의 해석. 결코 '보이거나 들린 것'으로 제시하지 마십시오.
항상 포함할 내용:
- 쓰여진 것과 말해진 것 사이의 차이(예: 슬라이드에는 한 가지가 쓰여 있고 음성은 실제로 중요한 규칙을 추가하거나 모순됨);
- 한 번만 표시된 것(단일 데모 예시는 설명일 뿐 증거가 아님);
- 한계점: 프레임은 N초마다 샘플링되므로 짧은 이벤트를 놓칠 수 있음; 프레임의 스탬프는 인덱스 × 간격이므로 근사치(± 간격의 절반, 가변 프레임 레이트 녹화에서는 더 큼); 키프레임 중복 제거로 작은 편집이 숨겨질 수 있음; Whisper는 이름과 전문 용어를 잘못 표기할 수 있음(이미지와 대조 확인); 어조, 감정, 음악, 화자 식별 또는 움직임은 신뢰할 수 없음.
5. 이후
작업 폴더 경로와 크기(추출 종료 시 출력됨)를 사용자에게 알려주십시오. 사용자가 해당 비디오 작업이 완료되었다고 말할 때까지 그대로 두십시오. 그런 다음 trash 스킬로 휴지통에 버리십시오.
알려진 문제점 (스크립트에서 이미 처리됨)
faster_whispermodel.transcribe("<경로>")는 최신 PyAV에서TypeError: open() got an unexpected keyword argument 'metadata_errors'를 발생시킵니다. 스크립트는 ffmpeg로 16kHz 모노 PCM16 WAV를 추출하고 float32 배열을 대신 전달합니다.imageio-ffmpeg는 ffmpeg는 포함하지만 ffprobe는 포함하지 않습니다: 지속 시간과 오디오 존재 여부는 ffmpeg 자체 배너에서 읽습니다.select='gt(scene,N)'+showinfo를 통한 장면 감지는-loglevel error에서 아무것도 출력하지 않습니다. 키프레임은 대신 썸네일 차이를 사용합니다.