자막 스타일링
자막은 휴대폰에서 소리를 끈 상태, 움직이는 영상 위, 앱 버튼 아래에서 약 2초 안에 읽힙니다. 아래 모든 기본값은 그 독자를 위한 것입니다. 사용자가 편집기를 사용 중이라면 그 편집기에서 작업하세요. 숫자는 어디서나 동일합니다. 편집기가 없으면 references/ffmpeg-burn-in.md의 ffmpeg 레시피를 사용하세요.
기본값
사용자나 해당 스타일 가이드가 달리 지시하지 않는 한 이 값을 사용하세요.
| 설정 | 기본값 | 이유 |
|---|---|---|
| 큐당 줄 수 | 최대 2줄 | 세 번째 줄은 피사체를 가리고 제때 읽히지 않습니다. |
| 줄당 문자 수 | 가로 16:9: 42자; 세로 9:16: 안전 폭에 맞게 (약 64px에서 32자, 72px에서 28자, 혼합 대소문자 기준) | 긴 줄은 눈의 이동을 강요하고 세로 화면에서는 프레임을 벗어납니다. |
| 읽기 속도 | 초당 최대 17자 (분당 약 160~180단어) | 방송 관행; WCAG는 속도를 설정하지 않으므로 이것이 작업 표준입니다. |
| 큐 지속 시간 | 최소 1초, 최대 6초 | 1초 미만은 깜빡임처럼 보이고, 6초 초과는 시청자가 다시 읽게 됩니다. |
| 큐 간격 | 0 또는 최소 2프레임 | 1프레임 간격은 번쩍임처럼 읽힙니다. |
| 위치 | 하단 중앙, 안전 영역 내; 1080x1920에서 텍스트는 하단 420px(높이의 22%) 위에 유지 | TikTok과 Reels 모두를 커버합니다. 하단 1/3에 얼굴, 내장 자막 또는 앱 UI가 있을 때는 상단으로 이동하세요. |
| 크기, 문장 자막 | 가로: 프레임 높이의 4.5 | 팔 길이 거리에서 읽을 수 있으며, 위 줄 길이가 900px 안전 폭에 여전히 맞습니다. |
| 크기, 강조된 짧은 자막 (1~3단어) | 1080x1920에서 약 140~150px, 혼합 대소문자 기준 줄당 최대 약 14자, 대문자 기준 11자 | 이는 자막이 아니라 그래픽 요소입니다. |
| 색상 | 70#F2F2F2, 또는 3 | 움직이는 영상에 대한 대비를 프레임별로 측정할 수 없습니다. 판은 WCAG 4.5:1을 보장합니다. |
| 글꼴 | 하나의 굵은 산세리프체(볼드 또는 세미볼드); 동영상에서 두 패밀리 이상 사용 금지 | 얇은 두께는 압축 후 사라집니다. |
| 단어 하이라이트(가라오케) | 활성 단어에만 하나의 악센트 색상 사용, 4.5:1 대비 충족 필수 | "강조"를 위한 두 번째 색상은 시청자가 의미를 찾도록 만듭니다. |
렌더링 전에 맞춤 확인. 혼합 대소문자로 된 굵은 Arial 계열 산세리프체는 문자당 글꼴 크기의 평균 0.44(공백 포함, 측정 기준)입니다. 대문자는 평균 0.55, 좁은 글꼴은 약 0.35입니다. 따라서 줄의 너비는 대략 문자 수 x 계수 x 글꼴_px이며, 이는 프레임이 아닌 안전 폭(1080x1920에서 900px, 가로에서 너비의 90%)에 맞아야 합니다. 96px에서 27자의 혼합 대소문자 줄은 약 27 x 0.44 x 96 = 1,140px로, 전체 1080px 프레임보다 넓습니다. 계수는 측정된 글꼴의 평균값이므로(주의사항 참조) 렌더링된 프레임으로 확인하세요.
플랫폼 픽셀 안전 영역과 모든 캔버스에 대한 안전 상자 도출 방법은 references/platform-safe-zones.md에 있습니다. 세로 동영상에 자막을 배치하기 전에 읽어보세요.
워크플로
-
실제 타이밍에서 시작. 자막에는 세그먼트 또는 단어 시간이 포함된 대본이 필요합니다. 대본이 없으면 만들 자막이 없으므로 그렇게 말하거나 먼저 대본을 만드세요. 단어를 지어내지 마세요.
-
편집 시간에 맞게 시간 재조정. 대본은 소스 파일을 기준으로 시간이 지정됩니다. 트리밍, 컷 또는 속도 변경 후에는 각 큐를 타임라인에 맞게 이동 및 조정하세요(주의사항 참조).
-
큐로 분할. 절(clause) 경계에서 분할: 구두점 뒤, 접속사와 전치사 앞. 관사를 명사에서, 이름을 성에서, 숫자를 단위에서 분리하지 마세요. 두 가지 가능한 분할 중 두 줄 길이가 가장 비슷해지는 것을 선택하세요.
-
읽기 속도 적용. 초당 17자를 초과하는 큐는 분할하거나 그 이후의 무음 구간으로 확장하세요. 유형을 줄여 맞추지 마세요.
-
화자 및 소리 표시. 화자가 바뀌면 줄 시작에
-를 붙이거나(처음에는 대괄호 안에 이름 표시) 의미 있는 비음성(non-speech)을 대괄호로 표시하세요:[문 닫힘],[긴장된 음악]. 오디오에서 잘린 채우기 단어는 자막에 넣지 마세요. -
스타일 및 배치 기본값과 이 캔버스의 안전 상자를 사용하여 적용.
-
파일 확인 후 보고된 모든 오류 수정:
python scripts/check_captions.py captions.srt --fps 30 --max-chars 32이 스크립트는 줄 수, 줄 길이, 초당 문자 수, 지속 시간, 간격 및 중복을 확인하며 오류가 있으면 0이 아닌 종료 코드를 반환합니다. 기계 보고서를 보려면
--json을 추가하세요. 기본 줄 제한은 32자(세로 및 접근성 수치)입니다. 가로 자막의 경우--max-chars 42를 전달하세요. -
설정이 아닌 렌더링된 프레임 확인: 첫 번째 큐, 가장 긴 큐, 가장 복잡한 배경 위의 큐. 클리핑이 없고, 앱 UI 아래에 있지 않으며, 휴대폰 크기에서 텍스트를 읽을 수 있는지 확인하세요.
-
두 가지 모두 제공: 소셜용 내장(burned-in) 버전과 접근성 및 플랫폼 업로드용 사이드카
.srt또는.vtt파일(사용자가 하나만 요청하지 않은 경우).
주의사항
- 좁은 글꼴에서 너비 추정이 잘못됩니다. 평균 글리프 너비 추정이 3배 이상 차이가 날 수 있습니다. 한 오버플로 검사에서는 실제로 1080px 프레임에서 270px 너비로 렌더링되는 줄이 각 측면에서 127px 벗어난다고 보고했습니다. 추정치를 만족시키기 위해 유형을 줄이면 1080x1920에서 강조 스타일이 약 150px을 요구하는 곳에 76px 자막이 생성되어 휴대폰에서 읽기에 너무 작았습니다. 프레임을 렌더링하고 측정하세요.
- 대본 시간은 소스 기준입니다. 클립이 소스 시작 후 12.4초에서 시작한다면 각 큐에서 12.4초를 빼고 클립의 타임라인 시작 시간을 더하세요. 2배 속도에서는 지속 시간이 절반이 되므로 큐가 1초 미만으로 떨어질 수 있습니다. 기존 큐 경계를 유지하지 말고 다시 분할하세요.
- ffmpeg는 SRT를 픽셀이 아닌 288라인 그리드로 굽습니다.
subtitles=file.srt:force_style=...에서FontSize와MarginV는 384x288 스크립트를 기준으로 측정되므로FontSize=24는 1080라인 비디오에서 90px 글꼴로, 1920라인 비디오에서 160px 글꼴로 렌더링됩니다.FontSize = px * 288 / frame_height로 변환하거나,PlayResX와PlayResY가 비디오 크기와 같아 단위가 픽셀이 되는 ASS 파일을 작성하세요(레시피가 그렇게 합니다). - ASS에서 판(plate)은 OutlineColour를 사용합니다.
BorderStyle=3에서 상자 색상은BackColour가 아닌OutlineColour에서 오며, ASS 색상은&HAABBGGRR이며 알파00은 불투명입니다.&H40000000은 75% 불투명도의 검정입니다. - 인라인 색상 변경은 ASS 판을 깨뜨립니다.
BorderStyle=3줄 내부의{\c...}하이라이트는 색상 실행별로 별도의 상자를 그리며, 반투명 상자가 겹쳐 어두운 이음새가 생깁니다. 자체 레이어에 보이지 않는 텍스트로 판을 그리고 그 위 레이어에 보이는 텍스트를 배치하세요(레시피가 방법을 보여줍니다). - 누락된 글꼴은 조용히 실패합니다. libass는 오류 없이 다른 글꼴로 대체됩니다. ffmpeg 로그에서
fontselect:줄을 확인하거나fontsdir=를 전달하세요. - Windows 경로는 자막 필터를 깨뜨립니다. 드라이브 콜론을 이스케이프하세요:
subtitles='C\:/clips/subs.srt'. - 노래 가사는 구절 단위로 시간이 지정됩니다. 음악 아래 음성 인식은 단어를 놓치고(한 테스트에서 17개 중 4개 손실) 단어 시간이 아닌 구절 시간을 반환합니다. 오디오와 대조하지 않고 단어별 가라오케를 만들지 마세요.
- 프리셋은 활성 단어를 두 곳 이상에서 색칠할 수 있습니다. 한 편집기의 네온 프리셋은 하이라이트 색상과 글로우 모두에서 하이라이트를 그렸으므로 존재하지 않는 필드만 재정의하면 오류 없이 아무것도 변경되지 않았습니다. 색상을 전달하는 모든 필드를 실제 이름으로 재정의하고 렌더링된 프레임에서 확인하세요.