블로그로 돌아가기

SRT 자막 파일 번역, 타이밍 깨지지 않게 하는 방법

SRT 자막 파일을 번역하면서 타이밍을 지키는 법이에요. 일반 번역기가 타임스탬프를 망가뜨리는 이유, 망가뜨리지 않는 네 가지 방법, 번역문이 20~35% 길어져 읽기 속도가 깨지는 이유까지 정리했어요.

2026년 9월 20일
Sablate Team

SRT 파일을 번역하면서 타이밍을 지키려면, 파일을 산문처럼 통째로 다루는 도구 대신 자막 형식 자체를 인식하는 도구를 쓰세요. 형식을 인식하는 도구는 블록 번호, 타임스탬프 줄, 텍스트를 세 가지 별개의 요소로 읽어서 그중 텍스트만 번역하고, 나머지 두 가지는 원래 모습 그대로 다시 써요.

깨진 번역 자막 파일은 결국 다 같은 실수에서 비롯돼요. 어떤 줄이 구조를 떠받치고 있는지 알 리 없는 범용 번역기에 파일 전체를 통째로 넣은 거예요.

SRT를 번역하면 왜 타이밍이 깨질까요?

SRT 블록은 네 부분으로 이루어져 있는데, 그중 언어인 부분은 딱 하나예요:

2
00:00:04,120 --> 00:00:06,480
The timings live on the line above.
A translator must never touch it.

번호는 큐를 식별해요. 밀리초를 쉼표로 구분하고 --> 화살표를 쓰는 타임스탬프 줄은 타이밍이에요. 텍스트는 자막 내용이고요. 빈 줄은 블록이 끝났다는 걸 파서에게 알려주는 구분자예요.

범용 번역기에게는 이 네 가지가 모두 담긴 문서 하나로만 보여요. 00:00:04,120 --> 00:00:06,480을 문법 요소로 취급할 이유가 없으니, 보통 다음 세 가지가 한꺼번에 잘못돼요:

  1. 큐가 합쳐져요. 블록 사이의 빈 줄은 산문 번역기에게 그냥 공백일 뿐이라, 이게 왕복 과정에서 살아남지 못하면 큐 두 개가 문단 하나로 합쳐져요. 그 지점 이후로는 모든 게 오디오와 어긋나 버려요.
  2. 블록이 다시 번호 매겨지거나 순서가 바뀌어요. 문단을 다시 흘리는 과정에서 번호가 뒤섞이고, 어떤 파서는 파일을 아예 거부하는가 하면 어떤 파서는 조용히 번호를 다시 매기면서 큐를 밀어버려요.
  3. 타임스탬프 형식이 바뀌어요. 화살표 주위에 공백이 생기거나, 쉼표가 마침표로 바뀌거나, 밀리초 자릿수를 채우는 방식이 달라지는 것만으로도 그 줄은 더 이상 파싱할 수 없게 돼요.

번역기와 전혀 상관없는 네 번째 실패 유형도 있어요. 인코딩이에요. 강세 문자나 비라틴 문자가 든 파일을 UTF-8이 아니라 Latin-1이나 Windows-1254로 저장하면, 그 파일을 여는 플레이어 중 절반에서 글자가 깨진 글자로 보여요. 모든 자막 파일을 UTF-8로 저장하면 이 문제는 완전히 사라져요.

이런 문제의 특징은, 망가진 파일도 훑어볼 때는 대체로 멀쩡해 보인다는 점이에요. 텍스트는 맞는 언어로 되어 있고, 타임스탬프도 그대로 있어서 딱히 눈에 띄는 게 없어요. 문제는 플레이어가 이걸 파싱하려 할 때 터지거나, 더 나쁘게는 파싱은 되는데 재생이 2초씩 어긋나는 식으로 나타나요.

SRT를 번역하는 네 가지 방법

빠른 순서부터 통제력이 높은 순서까지:

  1. Subtitle Edit — 무료, 오픈소스, 번역 기능 내장, 로컬에서 실행.
  2. 형식을 인식하는 온라인 번역기 — 파일을 올리면 번역된 파일을 받아요.
  3. 엄격한 프롬프트를 쓰는 LLM — 용어 통제력이 가장 뛰어나지만 검증이 필요해요.
  4. 번역을 레이어로 다루는 데스크톱 앱 — 타임라인 하나에서 여러 언어를 만들어요.

네 가지 방법 모두 제대로 쓰면 타임스탬프를 그대로 지켜요. 차이는 비용, 프라이버시, 그리고 몇 개 언어를 만들어내느냐에 있어요.

방법 1: Subtitle Edit

무료 답이자, 대부분의 사람이 가장 먼저 시도해야 할 방법이에요.

Subtitle Edit은 오픈소스이고, Windows, macOS, Linux에서 실행되며, 메모리 안에서 텍스트만 바꿔치기하고 블록 구조는 애초에 건드리지 않는 자동 번역 기능을 갖추고 있어요. 엔진도 여러 개 제공해요 — 키가 있다면 DeepL과 Google, 직접 호스팅한다면 LibreTranslate, 그리고 Ollama, llama.cpp나 OpenAI 호환 엔드포인트를 통한 로컬 모델까지요.

  1. Subtitle Edit에서 .srt 파일을 열어요.
  2. Auto-Translate를 선택하고 엔진과 대상 언어를 골라요.
  3. 원문과 번역이 나란히 보이는 목록 화면에서 결과를 검토해요.
  4. UTF-8로 새 파일로 저장해요.

알아둘 만한 건 로컬 모델 경로예요. API 키도 필요 없고 아무것도 기기 밖으로 나가지 않아서, 이 글에서 다루는 방법 중 무료이면서 동시에 프라이버시까지 지키는 유일한 방법이에요. 다만 작은 로컬 모델은 유럽 언어 쌍에서 DeepL보다 눈에 띄게 번역 품질이 떨어져서, 편집을 더 많이 해야 한다는 게 절충점이에요.

방법 2: 형식을 인식하는 온라인 번역기

파일을 올리고, 언어를 고르고, 결과를 내려받아요. DeepL.srt를 문서 형식으로 받아들여서 구조가 그대로 살아있는 번역된 .srt를 돌려줘요. 몇 개까지 처리할 수 있는지는 요금제에 따라 달라져요. 자막 번역만 전문으로 하는 사이트 몇 곳도 똑같은 방식으로 작동해요.

파일 하나를 언어 하나로 옮길 때는 가장 빠른 방법이고, 별다른 설정 없이도 주요 유럽 언어 쌍에서는 네 가지 방법 중 품질이 가장 좋아요.

쓰기 전에 알아둘 점이 두 가지 있어요. 파일이 업로드되기 때문에, 아직 공개되지 않은 편집본이나 클라이언트의 영상, 녹음된 내부 회의처럼 기밀이 필요한 내용에는 맞지 않는 방법이에요. 그리고 문서 번역기는 용어를 전혀 통제할 수 없어요. 제품명, 등장인물 이름, 전문 용어까지 다른 모든 것과 함께 번역돼 버리는데, 이름만큼은 절대 그러면 안 되는 부분이죠.

방법 3: 엄격한 프롬프트를 쓰는 LLM

네 가지 방법 중 용어 통제력이 가장 뛰어나요. 번역하지 말아야 할 항목을 모델에게 직접 지시할 수 있기 때문이에요. 동시에 파일을 조용히 손상시킬 가능성이 가장 큰 방법이기도 해서, 검증 단계는 선택 사항이 아니에요.

실제로 작동하는 프롬프트예요:

Translate the subtitle text below from English into German.

Rules:
- Output exactly the same number of subtitle blocks as the input.
- Copy every block number and every timecode line unchanged, character for character.
- Translate only the subtitle text lines.
- Keep the blank line between blocks.
- Do not merge, split, reorder or renumber blocks.
- Do not translate these terms: [list product and character names here]
- Keep each translated line roughly the length of the original.

두 시간짜리 영화를 통째로 붙여넣지 말고, 블록 50개에서 100개씩 나눠서 작업하세요. 입력이 길어질수록 모델이 큐를 합치고 블록을 빠뜨리기 시작하는데, 그것도 아무 말 없이 그렇게 해요.

그다음엔 검증하세요. 이 한 줄짜리 명령어가 두 파일의 타임스탬프 줄 개수를 세줘요:

grep -c " --> " original.srt translated.srt

두 숫자는 반드시 같아야 해요. 번역본 쪽 숫자가 더 적다면 블록이 합쳐진 거고, 합쳐진 지점 이후의 모든 큐가 지금 틀어져 있는 상태예요. LLM으로 번역할 때마다 이 점검을 매번 실행하세요.

방법 4: 파일이 아니라 레이어로 번역하기

위의 세 가지 방법은 모두 같은 구조를 갖고 있어요. 파일 하나가 있고, 그걸로 또 다른 파일 하나를 만들어요. 언어 여덟 개를 원한다면 이 과정을 여덟 번 반복하고 파일 여덟 개를 관리해야 해요.

데스크톱 앱은 그 대신 타임라인 하나만 유지할 수 있어요. Sablate에서 번역은 새 작업이 아니라 기존 전사 결과에 추가되는 레이어예요 — 큐 경계는 한 번만 만들어지고 모든 언어가 그걸 그대로 물려받기 때문에, 타이밍 문제가 두 번째로 불거질 일이 없어요. 각 레이어는 자기만의 스타일과 문자 체계 폰트를 따로 가지는데, 캡션 폰트에 없는 문자 체계가 필요한 언어가 나오는 순간 이게 중요해져요.

번역 경로는 두 가지예요. Argos는 내 기기에서 오프라인으로 실행되고 어디로도 아무것도 보내지 않아요. 본인의 API 키가 있으면 DeepL, OpenAI, Claude도 쓸 수 있어요. 오프라인 경로에 대해 솔직히 짚고 넘어갈 점 하나: Argos는 한쪽이 영어인 언어 쌍 위주로 패키지를 내놓기 때문에, 터키어에서 독일어로 가는 것 같은 조합은 직접 연결되는 패키지가 없어서 영어를 중간 경유지로 거쳐 조합돼요. 작동은 하지만, 터키어→독일어 줄은 터키어→영어 줄보다 살짝 더 딱딱하게 읽혀요.

무료 요금제는 최대 10분 영상의 작업 하나당 오프라인 번역 레이어 1개까지 지원해요. 무제한 레이어, 클라우드 엔진, 모든 언어를 한 번에 내보내는 기능은 Pro에 포함돼 있어요. Windows나 Mac용으로 다운로드해서 뭔가 결정하기 전에 파일 하나부터 직접 번역해 보세요.

어떤 방법을 써야 할까요?

방법비용오프라인 실행용어 통제적합한 상황
Subtitle Edit무료가능, 로컬 모델로부분적파일 하나, 어떤 언어 쌍이든
온라인 문서 번역기무료 요금제, 이후 유료불가능불가능유럽 언어 쌍에서 가장 빠르고 좋은 결과
엄격한 프롬프트를 쓰는 LLM모델에 따라 다름가능, 로컬 모델로가능전문 용어, 이름, 사내 용어집
Sablate무료 요금제, Pro는 $29 한 번 결제가능가능하나의 전사 결과에서 여러 언어로

"파일 하나뿐이고 예산은 없어요." Subtitle Edit이에요. 무료이고, 이 목록에서 형식 작업에 가장 뛰어난 자막 도구이며, 타이밍을 깨뜨리지 않아요.

"독일어 번역 품질이 가장 좋아야 하고 파일은 민감하지 않아요." 문서 번역기예요. 영어에서 독일어로 옮길 때 DeepL의 결과물이 여기서 가장 손이 덜 가요.

"영상이 기밀이에요." 로컬 모델을 쓰는 Subtitle Edit이나 Sablate의 오프라인 경로예요. 업로드하는 방식은 아무리 품질이 좋아도 제외돼요.

"같은 영상을 여섯 개 언어로 내보내야 해요." 파일이 아니라 레이어예요. 파일 단위 방법은 여섯 배로 늘어나지만 레이어 기반 작업 방식은 그렇지 않아요. 다국어 작업 방식은 어떤 언어든 작업을 시작하기 전에 대본이 왜 꼼꼼한 교정을 받을 만한지 설명해요.

타이밍이 다시 깨지지 않게 하는 법

시간을 아껴주는 순서대로 정리한 세 가지 습관이에요.

번역할 때마다 블록 개수를 확인하세요. 위의 grep 명령어는 2초면 끝나고, 훑어봐서는 절대 눈에 띄지 않는 유일한 실패 유형을 잡아내요. 번역본의 블록 수가 원본보다 적다면 그건 항상 깨진 파일이에요.

읽기 속도는 전사 직후가 아니라 번역 직후에 확인하세요. 타이밍은 그대로 남았지만 텍스트 길이는 그대로가 아니었어요. 영어를 스페인어나 프랑스어로 옮기면 보통 20~25% 더 길어지고 독일어는 최대 35%까지 늘어나는데, 이게 전부 똑같은 초 안에 들어가야 해요. 여유로운 14 CPS 줄이 타임스탬프는 하나도 움직이지 않은 채 17.5 CPS 줄이 돼버려요 — 읽기 속도 기준에서 이럴 때 뭘 해야 하는지 다루는데, 답은 언제나 단어나 길이를 바꾸는 것이지 싱크를 바꾸는 게 절대 아니에요.

원본 대본을 마스터로 유지하세요. 뭔가를 번역하기 전에 이름, 전문 용어, 문장부호를 원본에서 먼저 바로잡으세요. 원본에서 고친 성씨는 모든 언어에서 고쳐지지만, 나중에 고치는 같은 성씨는 언어마다 한 번씩 편집해야 하고, 그 편집은 서로 어긋나기 시작해요.

이 중 무엇이든 영상에 구워 넣을 거라면, 그건 가장 마지막에 하세요. 구워 넣은 영상의 읽기 속도는 영구히 고정되고, 내보내는 형식이 시청자가 언어를 바꿀 수 있는지 여부 자체를 결정해요.

영상이 아니라 파일을 번역하세요. 이미 값을 치른 타임라인은 그대로 두고, 그 위에 놓인 단어에 공을 들이고, 내보내기 전에 블록 개수를 확인하세요.