첫 자막만 안 나올 때

인코딩은 제대로 고쳤는데 첫 번째 자막 하나만 안 뜹니다. 두 번째부터는 멀쩡합니다. 파일 맨 앞에 붙은 눈에 안 보이는 세 바이트 때문입니다.

급하면 이것만. 자막 변환기에 파일을 놓고 대상 인코딩을 UTF-8 로 고르세요 — 목록에 UTF-8 (BOM 포함) 도 있는데 그건 아닙니다. 그냥 UTF-8 이 BOM 없는 쪽입니다.

BOM 이 뭔가

BOM(Byte Order Mark)은 파일 맨 앞에 붙는 표식 바이트입니다. 글자가 아니라 "이 파일은 이 인코딩입니다" 라고 알려 주는 꼬리표입니다. 화면에는 아무것도 안 보이지만 파일 안에는 분명히 들어 있습니다.

인코딩BOM 바이트필요한가
UTF-8EF BB BF필요 없음 — 선택 사항
UTF-16 LEFF FE사실상 필수 — 바이트 순서를 알려야 함
UTF-16 BEFE FF사실상 필수
CP949 · Shift_JIS 등없음개념 자체가 없음

UTF-16 은 글자 하나를 두 바이트로 쓰는데 그 두 바이트의 순서가 두 가지라서, 어느 쪽인지 알려 주려고 BOM 이 생겼습니다. UTF-8 은 바이트 순서라는 게 아예 없습니다. 그래서 UTF-8 의 BOM 은 원래 쓸 데가 없는 물건인데, "이 파일은 UTF-8 입니다" 라는 표시로 윈도우가 즐겨 붙이면서 퍼졌습니다.

왜 첫 자막만 사라지나

SRT 파일의 시작은 이렇게 생겼습니다.

1
00:00:01,000 --> 00:00:04,000
안녕하세요

맨 앞 1 은 자막 번호입니다. 플레이어는 "숫자만 있는 줄"을 보고 자막 블록이 시작됐다고 판단합니다. 그런데 BOM 이 붙으면 파일의 첫 줄이 숫자 1 이 아니라 <BOM>1 이 됩니다.

EF BB BF 31 0D 0A      ← BOM + "1" + 줄바꿈
         ^^ 여기부터가 진짜 내용

BOM 을 아는 플레이어는 조용히 건너뜁니다. 모르는 플레이어는 그 줄을 "숫자가 아닌 뭔가" 로 읽고 첫 블록을 통째로 버립니다. 그래서 첫 자막 하나만 안 나오고 두 번째부터는 멀쩡한, 묘한 증상이 됩니다.

오래된 스마트TV·셋톱박스·차량용 플레이어·일부 DivX 계열 기기가 여기 걸립니다. PC 플레이어(VLC·mpv·PotPlayer)는 대부분 잘 처리하기 때문에, PC 에서는 멀쩡한데 TV 에서만 첫 줄이 빠지는 일이 생깁니다.

포맷마다 다릅니다

포맷BOM이유
SRT붙이지 마세요 맨 앞이 자막 번호라 정면으로 걸립니다
WebVTT괜찮습니다 규격이 BOM 을 허용하고, 파서가 떼어 내도록 정해져 있습니다
SMI안 붙이는 쪽이 안전 맨 앞이 <SAMI> 태그라 덜 치명적이지만, 태그 인식에 실패하는 구현이 있습니다
ASS · SSA붙이지 마세요 맨 앞 [Script Info] 를 섹션 머리말로 못 알아보는 경우가 있습니다

자막 변환기는 이걸 알고 있어서, 자막 파일에 BOM 이 붙는 대상 인코딩을 고르면 경고를 띄웁니다. WebVTT 로 내보낼 때는 띄우지 않습니다 — 규격상 문제가 없기 때문입니다.

내 파일에 BOM 이 있는지 보기

눈으로는 알 수 없습니다. 메모장으로 열어도 아무 표시가 없습니다. 확인하는 방법은 둘입니다.

  1. 변환기의 미리보기. 파일을 올리고 미리보기를 누르면 아래쪽에 헥스 덤프가 뜹니다. 첫 세 바이트가 EF BB BF 면 BOM 이 있는 것입니다.
  2. 파일 크기. 같은 내용을 BOM 있는 쪽과 없는 쪽으로 저장하면 정확히 3바이트 차이가 납니다. 비교할 짝이 있을 때만 쓸 수 있는 방법입니다.

자막 변환기 열기

어디서 붙었나

대부분 저장한 프로그램이 붙였습니다. 사람이 일부러 넣는 경우는 없습니다.

프로그램기본 동작
윈도우 메모장 (옛 버전) 인코딩을 "UTF-8" 로 고르면 BOM 을 붙였습니다
윈도우 메모장 (Win10 1903 이후) 기본이 BOM 없는 UTF-8. 목록에 "UTF-8(BOM)" 이 따로 있습니다
엑셀 CSV 내보내기 한글이 깨지지 말라고 일부러 붙입니다
메모장++ · VS Code 선택 가능. 상태 표시줄에 "UTF-8" / "UTF-8 with BOM" 으로 구분해 보여 줍니다

옛날에 받아 둔 자막을 메모장으로 한 번 열었다 저장한 적이 있다면 그때 붙었을 가능성이 큽니다. 열어 보기만 해서는 안 붙고, 저장해야 붙습니다.

UTF-16 은 또 다른 이야기

UTF-16 은 BOM 을 떼면 안 됩니다. 떼는 순간 플레이어가 바이트 순서를 알 수 없어 글자가 전부 깨집니다. 다만 UTF-16 자막 자체가 권할 만한 선택이 아닙니다.

ASCII 영역 글자마다 00 바이트가 끼어 있어서, UTF-16 을 모르는 플레이어는 파일을 "널 바이트가 섞인 이상한 것" 으로 보고 거부합니다. 자막을 UTF-16 으로 저장할 이유는 실질적으로 없습니다 — BOM 없는 UTF-8 이 가장 넓게 통합니다.

떼는 법

  1. 자막 변환기에 파일을 끌어다 놓습니다.
  2. 행에 뜬 원본 인코딩이 UTF-8 인지 봅니다. BOM 이 있으면 감지 신뢰도가 높게 뜹니다 — BOM 자체가 확실한 단서이기 때문입니다.
  3. 대상 인코딩에서 UTF-8 을 고릅니다. UTF-8 (BOM 포함) 이 아니라 그냥 UTF-8 입니다.
  4. 전체 변환 → 저장. 파일이 정확히 3바이트 줄어듭니다.

자막이 여러 개면 자막용 설정 적용 버튼이 한 번에 맞춰 줍니다 — BOM 없는 UTF-8 + CRLF 줄바꿈 + charset 선언 갱신까지 같이 겁니다.

자주 묻는 것

BOM 을 떼면 한글이 깨지지 않나요?

안 깨집니다. BOM 은 글자가 아니라 꼬리표라서, 떼어 내도 본문 바이트는 한 글자도 변하지 않습니다. UTF-8 은 BOM 없이도 스스로를 설명할 수 있는 인코딩입니다 — 바이트 패턴만 보면 UTF-8 인지 아닌지 거의 확실하게 알 수 있습니다.

그럼 BOM 은 왜 있나요?

UTF-16·UTF-32 에서는 바이트 순서를 알리는 실제 쓸모가 있습니다. UTF-8 에서는 "이 파일은 UTF-8" 이라는 신호 정도이고, 윈도우 쪽 프로그램이 ANSI 와 UTF-8 을 빠르게 구분하려고 쓰는 관행입니다. 엑셀이 CSV 에 BOM 을 붙이는 것도 같은 이유입니다 — 안 붙이면 한글을 CP949 로 읽어 버립니다.

첫 자막이 아니라 전체가 깨집니다

그건 BOM 문제가 아니라 인코딩 문제입니다. 자막 글자가 깨질 때를 보세요. BOM 은 첫 블록 하나만 건드립니다.

WebVTT 로 바꾸면 BOM 을 신경 안 써도 되나요?

규격상으로는 그렇습니다. 다만 WebVTT 는 웹 브라우저(<track>) 쪽 포맷이라 TV·셋톱박스 지원이 SRT 보다 좁습니다. 기기에 넣을 자막이라면 BOM 없는 UTF-8 SRT 가 가장 안전한 조합입니다.

파일이 서버로 올라가나요?

아니요. 변환은 전부 브라우저 안에서 일어나고, 파일을 받는 서버 자체가 없습니다. 이 도구는 HTML 파일 하나가 전부라 소스 전체를 그대로 읽어 확인하실 수 있습니다.

더 읽을 거리