사이드프로젝트 slecs

숏폼 자막 4줄 확장

목차

자막 4줄 지원이랑 BGM atrim 필터 대체 작업을 동시에 처리했다. 둘 다 오래 묵혀뒀던 작업인데, 이번에 한 번에 밀었음.


왜 자막이 4줄이어야 했나

기존 코드는 자막을 3줄까지만 렌더링하도록 하드코딩돼 있었다. 짧은 숏폼 영상에서는 보통 3줄이면 충분하다고 생각했는데, 실제로 영상 소재를 돌려보니까 발화 속도가 느리거나 문장이 길게 끊기는 케이스에서 4줄짜리 자막 타이밍이 필요한 상황이 생겼다. 3줄로 자르면 타이밍 단위가 이상해지거나 자막 블록 하나가 너무 길어지는 문제가 있었음.

4줄로 늘리는 건 구조적으로 크게 바꿀 게 없을 것 같았지만, 실제로 보면 자막 위치 계산 로직이랑 텍스트 렌더링 박스 크기 계산이 줄 수에 종속돼 있어서 같이 손봐야 했다. 특히 줄 수가 늘어나면 전체 자막 블록의 높이가 커지고, 그게 영상 하단 여백이나 다른 요소와 겹칠 수 있어서 레이아웃 검증을 같이 해야 했음.

숏폼 자막 작업을 하면서 느끼는 건, "몇 줄"이라는 단순한 숫자가 사실 영상 가독성 UX의 핵심 변수라는 거다. 너무 많으면 시청자 눈이 산만해지고, 너무 적으면 텍스트가 빽빽해지거나 타이밍이 어색해진다. 4줄이 당장의 상한선이지만, 나중에 가면 줄 수를 콘텐츠 유형별로 동적으로 제어하는 구조를 고민해볼 여지가 있다.


BGM -ssatrim 필터로 대체한 이유

이게 사실 더 중요한 변경이었다. 기존에는 BGM 오디오 파일을 시작 지점부터 자를 때 FFmpeg의 -ss 입력 옵션을 사용하고 있었는데, 이 방식은 몇 가지 문제가 있다.

-ss를 입력 파일 앞에 붙이는 방식은 FFmpeg가 해당 타임스탬프까지 빠르게 seek하는 방식이라, 오디오 파일의 경우 정확한 프레임 단위 컷이 보장되지 않는다. 특히 인코딩된 오디오에서는 seek 위치가 키프레임 단위로 snap되기 때문에, 원하는 정확한 시작점에서 자막이나 영상 타이밍과 sync가 어긋나는 경우가 생길 수 있다.

atrim 필터는 필터 그래프 안에서 오디오 스트림을 샘플 단위로 정확하게 잘라내기 때문에, 이런 seek 부정확성 문제가 없다. 필터 체인으로 처리되기 때문에 이후 다른 오디오 필터(afade, volume, amix 등)와 자연스럽게 연결되는 이점도 있음.

# 기존 방식 — -ss 입력 옵션으로 seek
ffmpeg_cmd = [
    "ffmpeg",
    "-ss", str(bgm_start),
    "-i", bgm_path,
    ...
]

# 변경 후 — atrim 필터로 정확한 컷
audio_filter = f"atrim=start={bgm_start},asetpts=PTS-STARTPTS"

asetpts=PTS-STARTPTS를 같이 붙이는 게 중요한데, atrim 이후 타임스탬프를 0부터 재정렬하지 않으면 이후 필터나 mux 단계에서 타이밍이 꼬이는 경우가 있다. 이 부분을 놓치면 BGM 시작이 영상보다 늦게 붙거나 싱크가 밀리는 증상이 나타남.


두 작업을 한 커밋에 묶은 배경

두 이슈가 사실 독립적인 문제다. 자막 줄 수 문제는 렌더링 로직 쪽이고, BGM 필터 문제는 FFmpeg 파이프라인 쪽이라서 서로 직접 연관은 없다. 다만 둘 다 auto_shorts.py 한 파일 안에서 처리되는 작업이고, 영상 하나를 완성하는 파이프라인 흐름 안에서 연속으로 테스트가 필요했기 때문에 같이 묶어서 검증하는 게 더 효율적이었다.

큰 팀이었다면 커밋을 분리하는 게 맞지만, 지금은 단일 파일에서 빠르게 반복 검증하는 사이클이 더 중요한 상황이라 판단했음. 이런 트레이드오프는 팀 규모랑 코드 리뷰 방식에 따라 달라진다.

변경 항목 기존 변경 후
자막 최대 줄 수 3줄 4줄
BGM 시작점 처리 -ss 입력 옵션 atrim 필터
오디오 컷 정확도 키프레임 snap 샘플 단위 정밀 컷

FFmpeg 파이프라인은 옵션 하나 위치 바꾸는 것만으로도 결과가 완전히 달라지기 때문에, 이런 류의 수정은 항상 실제 출력물로 눈으로 확인하는 게 기본이다. 다음 작업도 이 파이프라인 위에서 계속 쌓이는 구조라 기반을 탄탄하게 잡아두는 게 맞다고 봤음.

끝.

댓글 0

첫 댓글 달아줘.