콘텐츠로 이동

SRT 파일로 자막 만들기

This content is for v0.4. Switch to the latest version for up-to-date documentation.

이 레시피를 마치면 .srt나 .vtt 파일을 자막(caption) 트랙으로 가져와 스타일을 입힐 수 있습니다. 파일은 엔진이 파싱하므로 브라우저, Node.js, Python이 같은 파일에서 같은 큐를 읽습니다.

다음과 같은 자막 파일이 있다고 합시다.

talk.srt
1
00:00:00,300 --> 00:00:02,000
Every frame is rendered on the GPU.
2
00:00:02,200 --> 00:00:04,000
The same project, in every target.

alpha2/captions의 parseCaptions는 WebAssembly로 된 엔진의 파서로 이 파일을 읽고, captionTrack은 큐를 트랙으로 감쌉니다.

import init, * as wasm from "alpha2/wasm";
import { captionTrack, parseCaptions } from "alpha2/captions";
await init();
const text = await (await fetch("/talk.srt")).text();
const { rows, skipped } = parseCaptions(wasm, text, "srt"); // .vtt 파일이면 "webvtt"
const style = {
font_family: "Hanken Grotesk",
font_size: 0.055,
background: { color: "#000000b3", padding: 0.3 },
};
const tracks = rows.map((cues, i) => captionTrack(`subs-${i}`, "Subtitles", cues, style));
project.timeline.tracks.push(...tracks);
  • rows의 한 행은 트랙 하나에 들어갈 큐입니다. 한 행의 큐는 서로 겹치지 않으므로, 큐가 겹치는 파일은 행이 여러 개 나옵니다. 행마다 자막 트랙을 하나씩 추가하십시오.
  • skipped는 파서가 읽지 못한 블록 수입니다. 마크업(<b>, <i>, WebVTT 태그)은 버립니다.
  • 타임스탬프는 정확하게 변환됩니다. 1ms는 120틱이므로 00:00:00,300은 36000이 됩니다.

이렇게 만든 트랙을 사진 위에 얹은 프로젝트입니다.

{
"schema_version": 1,
"id": "captions-srt",
"name": "Captions from SRT",
"settings": {
"width": 1280,
"height": 720,
"frame_rate": {
"num": 30,
"den": 1
},
"sample_rate": 48000
},
"sources": [
{
"id": "forest",
"locator": "asset://forest",
"kind": "image"
}
],
"timeline": {
"tracks": [
{
"id": "picture",
"name": "Picture",
"kind": "video",
"clips": [
{
"id": "photo",
"source_id": "forest",
"timeline_range": {
"start": 0,
"end": 540000
},
"source_range": {
"start": 0,
"end": 540000
}
}
],
"transitions": []
},
{
"id": "subs",
"name": "Subtitles",
"kind": "caption",
"clips": [],
"captions": {
"style": {
"font_family": "Hanken Grotesk",
"font_size": 0.055,
"background": {
"color": "#000000b3",
"padding": 0.3
}
},
"cues": [
{
"timeline_range": {
"start": 36000,
"end": 240000
},
"text": "Every frame is rendered on the GPU."
},
{
"timeline_range": {
"start": 264000,
"end": 480000
},
"text": "The same project, in every target."
}
]
}
}
]
}
}

자막 트랙은 kind: "caption"이고, 클립 없이 style과 cues를 담은 captions 객체를 가집니다. 생략한 스타일 필드는 기본값을 따릅니다. 가운데 정렬, position 0.5, 0.92에 아래쪽 가운데(anchor 0.5, 1)를 맞추고, 흰색, 그림 짧은 변의 0.05인 font_size, max_width 0.9에서 줄바꿈합니다. 여기서는 폰트와 조금 더 큰 크기, 그리고 background를 더했습니다. background는 줄마다 뒤에 깔리는 상자이며, padding은 폰트 크기에 대한 비율입니다.

박스를 깔면 어떤 그림 위에서도 자막이 잘 읽힙니다. outline은 그림을 덜 가리면서 같은 효과를 냅니다. 글리프 둘레에 띠를 그려 글자 뒤에 깔며, width는 폰트 크기에 대한 비율입니다(최대 0.5).

{
"schema_version": 1,
"id": "captions-outline",
"name": "Outlined captions",
"settings": {
"width": 1280,
"height": 720,
"frame_rate": {
"num": 30,
"den": 1
},
"sample_rate": 48000
},
"sources": [
{
"id": "wall",
"locator": "asset://wall",
"kind": "image"
}
],
"timeline": {
"tracks": [
{
"id": "picture",
"name": "Picture",
"kind": "video",
"clips": [
{
"id": "photo",
"source_id": "wall",
"timeline_range": {
"start": 0,
"end": 300000
},
"source_range": {
"start": 0,
"end": 300000
}
}
],
"transitions": []
},
{
"id": "subs",
"name": "Subtitles",
"kind": "caption",
"clips": [],
"captions": {
"style": {
"font_family": "Hanken Grotesk",
"font_size": 0.08,
"font_weight": 700,
"position": {
"x": 0.5,
"y": 0.85
},
"outline": {
"color": "#000000",
"width": 0.12
}
},
"cues": [
{
"timeline_range": {
"start": 36000,
"end": 144000
},
"text": "Every frame"
},
{
"timeline_range": {
"start": 144000,
"end": 240000
},
"text": "is rendered live."
}
]
}
}
]
}
}

이 스타일은 굵기를 bold로, 크기를 조금 크게 하고, 폰트 크기의 0.12 너비인 검은 outline을 두르며, 텍스트를 조금 위로 올립니다(position 0.5, 0.85). 트랙의 모든 큐는 이 한 스타일로 그려집니다. 자막 트랙에는 style이 하나뿐입니다.

터미널 창
alpha2-host export --project captions.json \
--asset forest=forest.jpg \
--font HankenGrotesk.ttf \
--out captions.mp4

기본 범위는 타임라인에서 마지막으로 보이는 것이 끝나는 지점까지이며, 자막 큐도 포함합니다.