안녕하세요! 오늘은 영상 편집자나 콘텐츠 제작자에게 꼭 필요한 영상 처리 자동화 기술을 공유하려고 합니다.
노트북LM이나 PPT로 만든 슬라이드 영상을 블로그 포스팅용 이미지로 변환하거나, 유튜브의 '챕터(타임라인)' 기능을 만들 때 아주 유용한 도구입니다.
1. 왜 이 기술이 필요한가요?
- 시간 절약: 10분짜리 영상에서 슬라이드 20장을 수동으로 캡처하려면 꽤 많은 시간이 걸리지만, 이 코드는 단 몇 초 만에 해결합니다.
- 정확도: 눈으로 확인하기 힘든 미세한 화면 전환 시점도 프레임 단위로 계산해냅니다.
- 콘텐츠 재활용: 해설 영상을 토대로 블로그 글을 쓰거나 교육 자료를 만들 때, 핵심 슬라이드 이미지를 즉시 확보할 수 있습니다.
2. 준비물
이 코드를 실행하려면 아래 두 가지가 필요합니다.
- Python: 파이썬 공식 홈페이지에서 설치 가능합니다.
- FFmpeg: 영상 처리의 '맥가이버 칼'이라 불리는 도구입니다. 설치 후 '환경 변수'에 등록되어 있어야 합니다.
3. 전체 파이썬 코드 (완성본)
이 코드는 크게 두 가지 일을 합니다.
- ffprobe를 사용해 장면이 바뀌는 정확한 타임라인을 텍스트 파일로 저장합니다.
- ffmpeg를 사용해 화면이 변하는 순간의 이미지를 PNG 파일로 추출합니다.
import subprocess
import os
import datetime
def process_video_slides(video_path, output_dir='output_slides', threshold=0.02):
"""
영상에서 장면 전환을 감지하여 이미지 추출 및 타임라인을 기록합니다.
:param video_path: 분석할 영상 파일 경로
:param output_dir: 결과물이 저장될 폴더
:param threshold: 장면 전환 감도 (0.01 ~ 0.1) - 낮을수록 미세한 변화도 감지
"""
# 1. 저장 폴더 생성
if not os.path.exists(output_dir):
os.makedirs(output_dir)
timeline_file = os.path.join(output_dir, 'timeline.txt')
image_pattern = os.path.join(output_dir, 'slide_%03d.png')
print(f"\n[작업 시작] 분석 파일: {video_path}")
print("-" * 50)
# 2. ffprobe를 이용한 장면 전환 타임라인 추출
# scene 필터가 설정한 threshold 이상일 때의 시간값(pkt_pts_time)만 가져옵니다.
print("> 1단계: 장면 전환 타임라인 분석 중...")
probe_cmd = [
'ffprobe', '-v', 'error',
'-show_entries', 'frame=pkt_pts_time',
'-of', 'default=noprint_wrappers=1:nokey=1',
'-f', 'lavfi',
f"movie={video_path},select='gt(scene,{threshold})'"
]
try:
raw_output = subprocess.check_output(probe_cmd, universal_newlines=True).strip()
timestamps = [ts for ts in raw_output.split('\n') if ts]
except subprocess.CalledProcessError as e:
print(f"타임라인 분석 실패: {e}")
return
# 3. ffmpeg를 이용한 슬라이드 이미지 추출
# 가변 프레임 레이트(-vsync vfr)를 적용하여 조건에 맞는 프레임만 저장합니다.
print("> 2단계: 슬라이드 이미지 추출 중...")
extract_cmd = [
'ffmpeg', '-y', '-i', video_path,
'-vf', f"select='gt(scene,{threshold})',setpts=N/FRAME_RATE/TB",
'-vsync', 'vfr',
image_pattern
]
try:
# 진행 상황은 생략하고 백그라운드에서 실행
subprocess.run(extract_cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
print(f"이미지 추출 실패: {e}")
return
# 4. 결과 리포트 작성 (timeline.txt)
print("> 3단계: 타임라인 파일 생성 중...")
with open(timeline_file, 'w', encoding='utf-8') as f:
f.write(f"=== 영상 슬라이드 추출 리포트 ===\n")
f.write(f"대상 파일: {video_path}\n")
f.write(f"추출 일시: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write("-" * 40 + "\n")
for i, ts in enumerate(timestamps):
seconds = float(ts)
# 초 단위를 사람이 보기 편한 HH:MM:SS 포맷으로 변환
time_fmt = str(datetime.timedelta(seconds=round(seconds, 2))).split('.')[0]
f.write(f"슬라이드 {i+1:03d} | 위치: {ts.ljust(8)}초 | 타임코드: [{time_fmt}]\n")
print("-" * 50)
print(f"[완료] 총 {len(timestamps)}개의 장면이 추출되었습니다.")
print(f"[결과 저장] {os.path.abspath(output_dir)}")
# 사용 예시
if __name__ == "__main__":
# 분석하고 싶은 영상 파일명을 적어주세요 (확장자 포함)
MY_VIDEO = 'bible_commentary_01.mp4'
if os.path.exists(MY_VIDEO):
# threshold 값을 조정하여 감도를 조절할 수 있습니다 (기본 0.02)
process_video_slides(MY_VIDEO, threshold=0.02)
else:
print(f"파일을 찾을 수 없습니다: {MY_VIDEO}")
4. 핵심 기술 포인트 설명 (알고리즘)
① 장면 전환 감지 필터 (select='gt(scene,0.02)')
FFmpeg의 가장 강력한 기능 중 하나입니다. 이전 프레임과 현재 프레임을 비교하여 변화량(0.0~1.0)을 수치화합니다.
- 0.02는 화면의 약 2%가 변했을 때를 뜻합니다.
- 슬라이드가 바뀔 때는 화면 전체가 변하므로 보통 0.01~0.03 사이의 값을 쓰면 아주 정확하게 잡아냅니다.
② ffprobe vs ffmpeg
- ffprobe: 영상을 실제로 건드리지 않고 '데이터'만 읽어옵니다. 여기서는 슬라이드가 바뀌는 정확한 시간(초) 정보를 얻기 위해 사용했습니다.
- ffmpeg: 실제 영상 데이터를 가공합니다. 여기서는 바뀐 장면을 이미지 파일(.png)로 저장하는 역할을 합니다.
③ 사람이 읽기 편한 타임코드 변환
파이썬의 datetime.timedelta 모듈을 사용해 84.23초 같은 데이터를 00:01:24와 같은 형식으로 변환했습니다. 이 정보는 유튜브 설명란의 타임스탬프로 바로 활용할 수 있습니다.
5. 결과 확인하기
스크립트를 실행하면 output_slides 폴더에 다음과 같이 깔끔하게 정리된 결과물이 나타납니다.
- slide_001.png, slide_002.png...: 캡처된 고화질 이미지
- timeline.txt: 각 슬라이드의 위치 정보
슬라이드 001 | 위치: 0.000000초 | 타임코드: [0:00:00]
슬라이드 002 | 위치: 125.4500초 | 타임코드: [0:02:05]
...
마치며
이제 수동 캡처의 고통에서 벗어나세요!
이 파이썬 스크립트만 있으면 아무리 긴 강의 영상도 슬라이드별로 깔끔하게 정리할 수 있습니다.
특히 해설 영상을 만드시는 분들이나 온라인 강사분들에게 이 코드가 큰 도움이 되길 바랍니다.
'디자인 인사이트 > 동영상 만들기' 카테고리의 다른 글
| [Python] 이미지 워터마크 완벽 제거: OpenCV 인페인팅과 좌표 설정법 (0) | 2026.02.04 |
|---|---|
| [Python] PDF 워터마크 제거 완벽 가이드 (배경색 자동 감지) (0) | 2026.02.04 |
| "열심히 만들었는데 소리가 작대요ㅠㅠ" 유튜브가 좋아하는 '최종 음량' 맞추는 법 (리미터 & LUFS) (0) | 2026.01.22 |
| "속삭일 땐 안 들리고, 웃을 땐 귀가 터져요" 들쑥날쭉한 목소리를 꽉 잡아주는 '컴프레서' 사용법 (0) | 2026.01.22 |
| "비싼 마이크 샀는데 왜 목소리가 먹먹하죠?" 내 목소리를 꿀보이스로 만드는 'EQ 보정'의 마법 (0) | 2026.01.22 |
댓글