[Python+FFmpeg] 내 마음대로 설계하는 자동 영상 제작 스크립트 만들기

2026. 2. 4.

 

단순한 슬라이드 쇼를 넘어, 내가 지정한 시간에 정확히 효과가 나타나는 영상을 만들고 싶으신가요?

오늘은 커스텀 타임라인 파일을 읽어 복합적인 효과(줌, 자막, 페이드 등)를 자동으로 입혀주는 파이썬 시스템을 만들어 보겠습니다.

1. 우리가 사용할 타임라인 데이터 형식 (timeline.csv)

메모장이나 엑셀에서 다음과 같이 작성합니다. (시간은 슬라이드 시작 시간입니다.)

00:00, slide_01.png, zoom(0, 10), fade(0, 1), text(2, 5, "요한복음 21장 해설")
00:10, slide_02.png, zoom(0, 8), text(0, 8, "예수님의 사랑과 회복")
00:18, slide_03.png, zoom(0, 12), fade(0, 1)
00:30, slide_03.png
  • 설명: 시간, 파일명, 효과1(시작, 유지), 효과2...
  • 효과 종류: zoom(줌), fade(페이드), text(자막) 등을 자유롭게 배치합니다.

2. 파이썬 자동화 코드 (완성본)

이 코드는 타임라인을 한 줄씩 읽어 각 슬라이드별로 효과가 적용된 개별 클립을 생성한 뒤, 마지막에 하나로 합쳐 오디오를 입힙니다.

import subprocess
import os
import re

def parse_effect(effect_str):
    """효과 문자열 분석: 예 'text(2, 5, "내용")' -> ['text', '2', '5', '내용']"""
    match = re.match(r"(\w+)\((.*)\)", effect_str.strip())
    if match:
        name = match.group(1)
        args = [arg.strip().replace('"', '') for arg in match.group(2).split(',')]
        return name, args
    return None, None

def create_video_from_timeline(timeline_path, audio_path, output_name):
    with open(timeline_path, 'r', encoding='utf-8') as f:
        lines = [line.strip().split(', ') for line in f if line.strip()]

    temp_clips = []

    for i in range(len(lines) - 1):
        # 1. 정보 추출
        start_time_str = lines[i][0]
        next_time_str = lines[i+1][0]
        img_file = lines[i][1]
        effects = lines[i][2:]

        # 시간 계산 (분:초 -> 초)
        m, s = map(int, start_time_str.split(':'))
        curr_sec = m * 60 + s
        m, s = map(int, next_time_str.split(':'))
        next_sec = m * 60 + s
        duration = next_sec - curr_sec

        # 2. FFmpeg 필터 조합 (이미지 효과 쌓기)
        filter_chains = [f"scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2"]

        for eff in effects:
            name, args = parse_effect(eff)
            if name == 'zoom':
                # zoom(시작시간, 유지시간)
                z_start, z_dur = float(args[0]), float(args[1])
                filter_chains.append(f"zoompan=z='min(zoom+0.0015,1.5)':d={duration*25}:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':s=1920x1080")

            elif name == 'text':
                # text(시작시간, 유지시간, 내용)
                t_start, t_dur, t_content = float(args[0]), float(args[1]), args[2]
                filter_chains.append(f"drawtext=text='{t_content}':fontfile=font.ttf:fontsize=60:fontcolor=white:x=(w-text_w)/2:y=h-150:enable='between(t,{t_start},{t_start+t_dur})'")

            elif name == 'fade':
                # fade(시작시간, 유지시간)
                f_start, f_dur = float(args[0]), float(args[1])
                filter_chains.append(f"fade=t=in:st={f_start}:d={f_dur}")

        # 3. 개별 클립 생성
        clip_name = f"temp_clip_{i}.mp4"
        vf_string = ",".join(filter_chains)

        cmd = [
            'ffmpeg', '-y', '-loop', '1', '-i', img_file,
            '-vf', vf_string, '-t', str(duration),
            '-c:v', 'libx264', '-pix_fmt', 'yuv420p', clip_name
        ]
        subprocess.run(cmd)
        temp_clips.append(clip_name)

    # 4. 클립 합치기 및 오디오 믹싱
    with open('concat_list.txt', 'w') as f:
        for clip in temp_clips:
            f.write(f"file '{clip}'\n")

    final_cmd = [
        'ffmpeg', '-y', '-f', 'concat', '-safe', '0', '-i', 'concat_list.txt',
        '-i', audio_path, '-c:v', 'copy', '-c:a', 'aac', '-shortest', output_name
    ]
    subprocess.run(final_cmd)

    # 임시 파일 삭제 (선택 사항)
    # for clip in temp_clips: os.remove(clip)
    # os.remove('concat_list.txt')

# 실행
create_video_from_timeline('timeline.csv', 'commentary.mp3', 'final_bible_study.mp4')

3. 코드의 핵심 동작 원리 (블로그 설명용)

① 정교한 파싱 (Parsing)

사용자가 입력한 text(2, 5, "제목") 같은 커스텀 형식을 파이썬의 정규표현식(Regex)을 이용해 [효과 이름, 시작 시간, 유지 시간, 내용]의 리스트로 분리합니다. 이를 통해 마치 프로그래밍 언어처럼 효과를 명령할 수 있습니다.

② 필터 체이닝 (Filter Chaining)

FFmpeg의 필터는 콤마(,)로 연결하여 여러 효과를 동시에 줄 수 있습니다.

  • 이미지 크기를 맞추고(scale/pad) ➔ 화면을 키우고(zoompan) ➔ 자막을 넣고(drawtext) ➔ 부드럽게 나타나게(fade) 하는 과정을 파이썬이 문자열로 자동 생성합니다.

③ 타임라인 기반 자동 계산

사용자는 슬라이드가 바뀌는 시점만 00:10, 00:18처럼 적으면, 코드가 자동으로 '다음 시간 - 현재 시간'을 계산하여 각 장면의 지속 시간을 설정합니다. 수동으로 길이를 조절할 필요가 전혀 없습니다.

④ 클립 단위 생성 방식

전체 영상을 한 번에 인코딩하면 수식이 너무 복잡해져 에러가 날 확률이 높습니다. 이 코드는 장면별로 작은 MP4 파일을 먼저 만든 뒤 합치는 방식을 사용하여 매우 안정적이고 중간에 수정하기도 쉽습니다.


4. 활용 팁

  • 자막 위치: drawtexty 값을 조절하여 자막을 상단, 중앙, 하단으로 바꿀 수 있습니다.
  • 줌 속도: zoom+0.0015 숫자를 높이면 더 빠르게 화면이 커집니다.
  • 폰트: font.ttf 파일이 코드와 같은 폴더에 있어야 자막이 정상적으로 출력됩니다.

마치며

이제 엑셀이나 메모장에 타임라인만 적으세요. 나머지는 파이썬이 알아서 화려한 효과와 함께 영상을 만들어낼 것입니다. 복잡한 영상 편집 프로그램 대신, 데이터 기반의 자동화 편집으로 생산성을 극대화해 보세요!


 

댓글