개발 취재 노트
Playwright로 화면 녹화해서 영상을 만들었더니 소리가 하나도 없다
AI 캐릭터들이 쇼츠 영상을 만드는 프로젝트(personaverse)에서, 캐릭터 컷아웃을 배경 클립 위에 얹는 "버튜버" 포맷을 만들던 중이었다. HTML 화면을 헤드리스 브라우저에 띄우고 그걸 통째로 화면 녹화해서 영상을 뽑는 파이프라인인데, 완성본을 재생해보니 분명 소리가 있는 배경 클립인데도 영상에는 소리가 하나도 없었다.
결론
이 Playwright 녹화 파이프라인은 화면만 담으므로 원본 오디오는 후처리로 넣는다.
<video>의 muted를 풀어도 녹화물에 오디오 트랙이 생기는 구조가 아니었다.
지연은 결과물의 컷 시각 - 원본의 같은 컷 시각으로 측정한다. raw - scene으로 구한 1초는 끝
여유시간까지 포함해 과했고, 같은 컷을 세 지점에서 비교하니 실제 지연은 0.27초였다. 이 측정 방식을
코드로 자동화해 정밀하게 재니 0.25초로 나왔다. 이 값을 적용해 다시 합성했다
. 다만 세션에는 이 뒤에 사용자가 소리를 직접 들어
싱크를 확인한 기록이 없다.
encode.py 원문이 아닌 예제다. raw.webm은 무음 녹화, clip.mp4는 원본이다. 250은 이 사례에서
자동 측정으로 적용해 확인한 지연(밀리초)이며, 자신의 영상에서 측정한 값으로 바꾼다.
ffmpeg -i raw.webm -i clip.mp4 -filter_complex "[1:a:0]adelay=250:all=1,apad[a]" -map 0:v:0 -map "[a]" -c:v libx264 -c:a aac -shortest output.mp4
-map은 녹화 영상과 원본 첫 오디오를 선택한다(문서). adelay는 전 채널 지연, apad·-shortest는 영상 끝까지 무음 보충이다(필터 문서).
상황
이 프로젝트의 렌더 엔진은 캐릭터 컷아웃과 배경 영상을 올린 HTML 페이지를 헤드리스 크로미움으로
열고, Playwright로 화면을 녹화하는 자체 파이프라인(record.py)이다. 그 결과물을 encode.py/
make.py가 후처리한다. 브라우저는 배경 영상 자동재생을 보장하기 위해
--autoplay-policy=no-user-gesture-required 옵션으로 띄워져 있었다.
증상
캐릭터 컷아웃 + 배경 클립 + 말풍선 자막으로 된 "버튜버" 포맷을 v5까지 다듬어 오던 중, 완성본을 재생해보니 영상 소리가 전혀 녹음되어 있지 않았다. 배경으로 쓴 클립 자체에는 분명히 소리가 있었는데도 결과물에는 반영되지 않았다.
원인
record.py가 화면만 녹화하므로 배경 <video>의 muted를 풀어도 오디오는 담기지 않는다.
해결
engine.js에서 재생 시작 시 클립을 0초로 리셋해 자막과 원점을 맞췄다.make.py의raw - scene계산은 폐기한다. 대신 원본과 녹화물에서 **같은 장면 전환이 일어나는
시각**을 찾아 그 차이를 지연으로 쓴다. 손으로 확인할 때는 의심 지점 근처에서
ffmpeg -ss <시각> -i <영상> -frames:v 1 frame.png로 정지 프레임을 뽑고, 컷이 걸리는 정확한
시각이 나올 때까지 -ss 값을 좁혀가며 두 영상을 비교한다
(-ss/-frames:v 옵션 문서). 이렇게 세 지점
(1.47->1.73초, 2.47->2.73초, 25.67->25.93초)을 비교하니 오프셋은 모두 0.27초로 일치했다
.
- 이 비교를 코드로 자동화해 렌더마다 장면 전환을 스스로 찾아 지연을 계산하게 했다. 같은 사례에서
정밀하게 재니 0.25초로 나왔고, 이 값으로 다시 합성했다. 다만 영상이
작은 플레이어 영역에 들어가고 흰 배경·정지 캐릭터가 프레임 대부분을 차지한 다른 편에서는 raw 기반
컷 검출이 실패해, 최종본에서 직접 오프셋을 재고 수동값을 넣었다.
encode.py에는 이 지연(초 단위)을 넘겨 AAC로 합성한다. 예제의 adelay 값은 초x1,000(밀리초)이다.
- 기존 도구는
python video-engine/make.py --scene scene.json --skip-record --clip-audio-delay 0.15로 조절한다. 장면 경로·지연은 교체한다. 값을 줄이면 소리가 앞당겨진다.
덤 - 리드타임 계산은 또 틀렸다
1초 지연과 자막 일치만으로 성공이라 판단했으나 소리는 밀렸다. 작은 배경 영상에서는 자동 컷 검출도 실패해 최종본에서 직접 측정했다.
취재 후기 - 음소거를 풀어도 소리가 안 들어오는 이유
장면 전환으로 다시 측정해 오디오를 합친다.