JSON 자막과 기록문
하나의 형식이 아니라 여러 형식입니다. JSON은 음성 인식 엔진, 동영상 사이트, 자막 사이트가 자막과 기록문을 넘겨줄 때 쓰이며, 도구마다 모양이 다릅니다. Subtitld는 자체 형식을 Whisper가 쓰는 모양으로 저장하며, 자막이 가진 모든 것을 담습니다. 그리고 열 가지가 넘는 다른 도구가 쓰는 파일도 엽니다.
한눈에 보기
| 확장자 | .json |
|---|---|
| 미디어 타입 | application/json |
| 사양 | JSON 자체: RFC 8259와 ECMA-404. 각 도구의 모양은 제각각입니다. |
| 시간 정밀도 | Subtitld: 초 단위, 밀리초까지. 다른 도구: 밀리초, 초, 100나노초 단위 틱, 또는 "1.400s" 같은 텍스트. |
| 텍스트 인코딩 | UTF-8 |
| 스타일 | Subtitld: 텍스트가 유지하는 태그. 유튜브: 굵게, 기울임, 밑줄, 색. 나머지: 없음. |
| 위치 지정 | Subtitld: 텍스트 안의 {\an8}. 유튜브: 창. 빌리빌리: 위치 값. |
| 화자 | Subtitld의 speaker; 음성 인식 서비스는 자체 표기를 씁니다 |
| 컨테이너 안 | 없음 |
Subtitld JSON의 구조
Subtitld가 저장하는 것, 자막 하나 기준입니다.
{
"language": "en-us",
"segments": [
{
"id": 0,
"start": 23.0,
"end": 24.5,
"text": "You're a jerk, Thom.",
"speaker": "Celia"
}
],
"text": "You're a jerk, Thom."
}
| 요소 | 의미 |
|---|---|
"language" |
프로젝트의 언어, Subtitld 방식으로 표기(en-us) |
"segments" |
자막 목록, 순서대로 |
"id" |
번호, 0부터 시작하며, Whisper가 번호를 매기는 방식과 같음 |
"start", "end" |
초 |
"text" |
태그(<i>, {\an8})와 줄바꿈(\n)이 포함된 텍스트 |
"speaker", "translations" … |
자막이 가진 그 밖의 것: 화자, 언어별 번역, 더빙 |
끝의 "text" |
모든 텍스트를 한 줄로. 텍스트만 원하는 도구용. 다시 읽지 않습니다. |
Whisper 모양을 일부러 따랐습니다. OpenAI의 Whisper가 쓰는 모양이므로, Whisper의 세그먼트를 읽는 도구는 Subtitld 파일을 읽을 수 있습니다. Subtitld는 Whisper 파일을 열 때 디코딩 통계와 단어별 시간은 빼고 읽습니다.
Subtitld가 여는 파일
도구마다 JSON은 키로 자신을 밝힙니다. Subtitld는 다음을 엽니다.
| 도구 | Subtitld가 가져오는 것 |
|---|---|
| Subtitld, OpenAI Whisper | 모든 필드(Subtitld의 것); 텍스트와 언어(Whisper의 것) |
| whisper.cpp | 세그먼트, 그리고 두 채널을 구분할 때의 화자 |
| WhisperX | 세그먼트와 화자 |
YouTube(.json3, yt-dlp가 저장하는 형식) |
텍스트, 굵게, 기울임, 밑줄, 색, 위치 |
Bilibili(.bcc) |
텍스트와 위치 |
| AssemblyAI, Deepgram, AWS Transcribe, Rev.ai, Google Speech-to-Text, Azure Speech, Speechmatics | 단어, 화자, 언어를 자막으로 만든 것 |
| Amara | 텍스트, 기울임, 굵게, 밑줄, 상단의 자막 |
다른 JSON 파일이면 그렇다고 알립니다. 올바른 JSON이 아니면 줄과 열을 알려 어디서 잘못되었는지 보여 줍니다.
기록문을 자막으로
음성 인식 서비스는 단어와 시간, 또는 긴 발화 덩어리를 넘겨줍니다. Subtitld는 품질 검사 패널이 허용하는 범위 안에서 이를 자막으로 만듭니다. 글자 수, 줄 수, 초 단위입니다. 자막은 다음에서 끝납니다.
- 화자가 바뀌거나 발화가 1초 넘게 멈출 때;
- 다음 문장이 한 줄을 넘길 때, 문장이 끝나는 곳에서;
- 가득 찼을 때: 적당히 찬 상태를 만드는 마지막 문장부호에서, 없으면 두 단어 사이에서.
단어 시간이 없는 발화 덩어리는 그 부분의 길이에 따라 시간을 나누어 같은 방식으로 처리합니다.
한계를 먼저 정하세요. 자막은 파일을 여는 순간에 만들어집니다. 기록문을 열기 전에 품질 검사 패널의 한계를 바꾸면 더 길거나 짧은 자막을 얻을 수 있습니다.
화자와 언어
서비스는 화자에 0, spk_1, SPEAKER_02, S3 같은 번호를 붙입니다. Subtitld는 처음 말하는 순서대로 A, B, C …라고 부릅니다. Subtitld가 화자를 이름 짓는 방식과 같습니다. 파일이 이름을 붙여 둔 화자, 예를 들어 Rev.ai가 그렇게 하는 경우, 그 이름을 유지합니다.
프로젝트의 언어는 파일에서 옵니다. 코드(en_us, pt)나 이름(English, Whisper가 그렇게 하도록 설정되었을 때 쓰는 이름)으로, 없으면 파일 이름에서 옵니다. 예를 들어 video.en.json3처럼요. 프로젝트 언어와 같은 파일은 프로젝트의 국가를 유지합니다. pt-br 프로젝트의 pt 파일은 pt-br로 남습니다.
YouTube의 json3
YouTube 플레이어가 읽고, yt-dlp가 .json3으로 저장하는 형식입니다. 밀리초 단위의 텍스트 이벤트이며, 굵게, 기울임, 밑줄, 색을 위한 펜과, 자막이 놓일 위치를 위한 창을 가집니다. 자동 자막은 한 줄씩 이어서 올라오며, 각 줄은 다음 줄이 나올 때까지 보입니다. Subtitld는 각 줄을 다음 줄이 시작할 때까지의 자막으로 만듭니다.
Bilibili의 BCC
Bilibili 플레이어가 읽는 형식이며, Subtitld가 저장하는 JSON 중 다른 하나입니다.
{
"font_size": 0.4,
"font_color": "#FFFFFF",
"background_alpha": 0.5,
"background_color": "#9C27B0",
"Stroke": "none",
"body": [
{
"from": 23.0,
"to": 24.5,
"location": 2,
"content": "You're a jerk, Thom."
}
]
}
시간은 초이고, content는 일반 텍스트이며, 줄은 \n으로 나뉩니다. 상단의 모양은 Bilibili 자체 파일이 담는 것이며, Subtitle Edit도 같은 모양을 씁니다.
한 번에 한 자막만. 같은 순간에 보이는 자막은 하나의 항목이 되며, 각 텍스트는 한 줄씩 차지합니다. 그래서 타임라인에 겹침이 없습니다. location은 항상 2, 즉 아래 가운데입니다. Bilibili 플레이어가 자막을 다른 곳에 놓는 데 이 값을 쓴다는 것은 알려져 있지 않습니다.
Subtitld의 JSON
- 모든 자막의 텍스트, 서식, 위치
- 화자, 번역, 더빙
- 밀리초 단위의 시작과 끝
- 프로젝트의 언어
- 단어 시간과 서비스가 각 단어에 가진 확신도
- Whisper의 디코딩 통계
- 유튜브의 글꼴, 크기, 외곽선, 배경
- BCC: 서식, 위치, 원문 옆의 번역
Subtitld의 것을 보존하려면 .usfx 프로젝트로 저장하세요.
내보내기
내보내기를 누른 다음 자막을 선택하면 두 가지가 나옵니다.
- JSONSubtitld 방식: 현재 프로젝트 전체, 모든 자막과 모든 필드.
- BCCBilibili 방식: 원문, 번역, 또는 둘 다. 번역은 원문 아래에 놓입니다. 화자 이름은 빼거나 텍스트 앞에 씁니다. 원하면 시간을 옮길 수 있습니다.
알아두면 좋은 사실
JSON의 표준인 2017년의 RFC 8259는 시스템 간에 주고받는 JSON이 UTF-8이어야 한다고 규정합니다.
Azure 기록문의 초당 틱 수입니다. 시간을 100나노초 단위로 셉니다.
YouTube 플레이어가 지속 시간을 적지 않은 json3 자막을 보여 주는 초 수입니다.
관련 형식
Subtitld에서 동영상과 함께 열고, 파형에서 시간을 다시 맞춰 보세요.