MKV(Matroska) 컨테이너 실전 활용 | EBML·다중 자막·FFmpeg 리먹스
이 글의 핵심
MKV는 Matroska 계열 중 가장 유연한 일반 컨테이너—EBML·트랙·챕터·부가 데이터를 실무 FFmpeg 패턴으로 묶었습니다.
들어가며
MKV(Matroska Video)는 EBML(Extensible Binary Meta Language)을 뼈대로 한 오픈 사양 컨테이너로, 여러 오디오·자막·챕터·첨부 파일을 한 파일에 의미 있게 묶는 것에 강합니다. 블루레이 리핑, 팟캐스트 아카이브, 다국어 강의 녹화, 자막 제작 워크플로처럼 “한 콘텐츠에 선택지가 많은 패키지”가 필요할 때 MP4보다 표현력에서 유리한 경우가 많습니다.
이 글을 읽으면
- EBML·Segment·Cluster의 역할을 한 장면으로 설명할 수 있습니다
- 다중 오디오·자막·챕터를 맵·메타데이터와 함께 다루는 명령을 복사해 쓸 수 있습니다
- MKV vs MP4/WebM을 유연성 vs 호환성 축으로 선택할 수 있습니다
- 자주 막히는 플레이어 이슈를 원인별로 줄일 수 있습니다
목차
컨테이너 개요
역사 및 개발 배경
Matroska는 MCF 등 기존 포맷을 대체하려는 목적으로 2000년대에 설계된 오픈 컨테이너이며, EBML로 확장 가능한 요소 트리를 표현합니다.
주요 마일스톤:
- 2002: Matroska 프로젝트 시작
- 2010: WebM (Matroska 부분집합) 발표
- 2026: 블루레이 리핑, 아카이브 표준
기술적 특징
| 항목 | 설명 |
|---|---|
| 기반 | EBML (Extensible Binary Meta Language) |
| 트랙 | 비디오, 오디오, 자막 독립 트랙 |
| 코덱 | H.264, HEVC, AV1, FLAC, AC3, ASS 등 광범위 |
| 메타데이터 | Tags, Chapters, Attachments |
| 확장자 | .mkv (비디오), .mka (오디오), .mks (자막) |
MKV vs MP4 vs WebM
| 특징 | MKV | MP4 | WebM |
|---|---|---|---|
| 코덱 지원 | 거의 모든 코덱 | H.264/HEVC + AAC 중심 | VP8/VP9/AV1 + Opus |
| 다중 트랙 | 매우 강함 | 제한적 | 제한적 |
| 챕터 | 풍부 | 제한적 | 제한적 |
| 브라우저 지원 | 낮음 | 최고 | 높음 |
| 용도 | 아카이브 | 범용 배포 | 웹 배포 |
내부 구조
EBML과 Matroska 요소
EBML은 가변 길이 정수(VINT)로 요소 ID·크기를 인코딩해, 앞에서 순차 스캔하며 트리를 복원합니다.
구조:
MKV 파일
├─ EBML Header
│ ├─ DocType: "matroska"
│ └─ DocTypeVersion: 4
├─ Segment
│ ├─ SeekHead (인덱스)
│ ├─ Info
│ │ ├─ TimestampScale: 1000000
│ │ ├─ Duration: 300.0s
│ │ └─ Title: "영화 제목"
│ ├─ Tracks
│ │ ├─ Video Track
│ │ │ ├─ CodecID: V_MPEG4/ISO/AVC
│ │ │ └─ Width: 1920, Height: 1080
│ │ ├─ Audio Track 1 (한국어)
│ │ │ ├─ CodecID: A_AAC
│ │ │ └─ Language: kor
│ │ ├─ Audio Track 2 (영어)
│ │ │ └─ Language: eng
│ │ └─ Subtitle Track (한국어)
│ │ ├─ CodecID: S_TEXT/ASS
│ │ └─ Language: kor
│ ├─ Tags
│ │ ├─ TITLE: "영화 제목"
│ │ ├─ ARTIST: "감독"
│ │ └─ DATE: "2026"
│ ├─ Chapters
│ │ ├─ Chapter 1: 00:00:00 "오프닝"
│ │ └─ Chapter 2: 00:05:00 "본편"
│ ├─ Attachments
│ │ └─ Font: subtitle_font.ttf
│ ├─ Cluster 1 (0-2s)
│ ├─ Cluster 2 (2-4s)
│ └─ Cues (시크 인덱스)
실전 사용
기본 명령
1) 구조 확인
# 전체 정보
ffprobe -hide_banner -show_format -show_streams -show_chapters input.mkv
# 트랙 목록만
ffprobe -v error -show_entries stream=index,codec_type,codec_name,language input.mkv
2) 무손실 리먹스
# MKV → MKV (코덱 복사)
ffmpeg -i input.mkv -c copy output.mkv
# MP4 → MKV
ffmpeg -i input.mp4 -c copy output.mkv
다중 트랙 관리
여러 입력에서 트랙 조립
# 비디오 + 다중 오디오 + 자막
ffmpeg -i video.mp4 \
-i audio_kor.m4a \
-i audio_eng.m4a \
-i subtitle_kor.srt \
-i subtitle_eng.srt \
-map 0:v:0 \
-map 1:a:0 \
-map 2:a:0 \
-map 3:s:0 \
-map 4:s:0 \
-c copy \
-metadata:s:a:0 language=kor -metadata:s:a:0 title="한국어" \
-metadata:s:a:1 language=eng -metadata:s:a:1 title="English" \
-metadata:s:s:0 language=kor -metadata:s:s:0 title="한국어 자막" \
-metadata:s:s:1 language=eng -metadata:s:s:1 title="English Subtitle" \
package.mkv
기본 트랙 설정
# 첫 번째 오디오를 기본으로
ffmpeg -i input.mkv \
-c copy \
-disposition:a:0 default \
-disposition:a:1 0 \
output.mkv
자막 관리
자막 추출
# 첫 번째 자막 트랙
ffmpeg -i input.mkv -map 0:s:0 -c:s copy subtitle.srt
# 모든 자막 트랙
ffmpeg -i input.mkv -map 0:s -c:s copy subtitle_%d.srt
자막 추가
# 외부 SRT 추가
ffmpeg -i video.mkv -i subtitle.srt \
-map 0 -map 1 \
-c copy \
-metadata:s:s:0 language=kor \
output.mkv
ASS 자막 + 폰트 임베드
# ASS 자막 + 폰트 첨부
ffmpeg -i video.mkv \
-i subtitle.ass \
-attach font.ttf -metadata:s:t mimetype=application/x-truetype-font \
-map 0 -map 1 \
-c copy \
-metadata:s:s:0 language=kor \
output.mkv
챕터 관리
챕터 추가
# 챕터 파일 (chapters.txt)
cat > chapters.txt << EOF
CHAPTER01=00:00:00.000
CHAPTER01NAME=오프닝
CHAPTER02=00:05:00.000
CHAPTER02NAME=본편
CHAPTER03=00:50:00.000
CHAPTER03NAME=엔딩
EOF
# 챕터 추가
ffmpeg -i input.mkv -i chapters.txt -map_metadata 1 -c copy output.mkv
MKV → MP4 변환
# 코덱 호환 시 (H.264 + AAC)
ffmpeg -i input.mkv \
-c:v copy \
-c:a copy \
-map 0:v:0 \
-map 0:a:0 \
-movflags +faststart \
output.mp4
# 코덱 변환 필요 시
ffmpeg -i input.mkv \
-c:v libx264 \
-preset medium \
-crf 23 \
-c:a aac \
-b:a 192k \
-movflags +faststart \
output.mp4
성능 비교
컨테이너 오버헤드
| 컨테이너 | 오버헤드 | 메타데이터 | 복잡도 |
|---|---|---|---|
| MKV | 매우 낮음 | 풍부 | 높음 |
| MP4 | 낮음 | 중간 | 중간 |
| WebM | 매우 낮음 | 제한적 | 낮음 |
결론: 컨테이너 오버헤드는 거의 무시 가능
트랙 개수별 파일 크기
테스트: 1080p 1시간 영상
| 구성 | 파일 크기 | 비고 |
|---|---|---|
| 비디오만 | 1.2GB | 기준 |
| + 오디오 1개 | 1.25GB | +50MB |
| + 오디오 3개 | 1.35GB | +150MB |
| + 자막 5개 | 1.36GB | +10MB (텍스트) |
결론: 오디오 트랙이 주요 용량 증가 요인
실무 활용 사례
사례 1: 블루레이 리핑 - 다중 오디오·자막
요구사항:
- 원본 품질 유지
- 다국어 오디오
- 다국어 자막
- 챕터 보존
MakeMKV 출력 → FFmpeg 정리
# MakeMKV 출력 (모든 트랙 포함)
# input.mkv: 비디오 1개, 오디오 5개, 자막 10개
# 필요한 트랙만 선택
ffmpeg -i input.mkv \
-map 0:v:0 \
-map 0:a:0 -map 0:a:1 \
-map 0:s:0 -map 0:s:1 \
-c copy \
-metadata:s:a:0 language=kor -metadata:s:a:0 title="한국어" \
-metadata:s:a:1 language=eng -metadata:s:a:1 title="English" \
-metadata:s:s:0 language=kor \
-metadata:s:s:1 language=eng \
cleaned.mkv
Python 자동화
import subprocess
from pathlib import Path
def clean_bluray_rip(input_file, output_file, keep_tracks):
"""
블루레이 리핑 정리
keep_tracks: {'audio': [0, 1], 'subtitle': [0, 1]}
"""
cmd = ['ffmpeg', '-i', str(input_file)]
cmd.extend(['-map', '0:v:0'])
for audio_idx in keep_tracks.get('audio', []):
cmd.extend(['-map', f'0:a:{audio_idx}'])
for sub_idx in keep_tracks.get('subtitle', []):
cmd.extend(['-map', f'0:s:{sub_idx}'])
cmd.extend(['-c', 'copy', str(output_file)])
subprocess.run(cmd, check=True)
# 사용
keep_tracks = {
'audio': [0, 1], # 한국어, 영어
'subtitle': [0, 1, 2] # 한국어, 영어, 일본어
}
clean_bluray_rip('rip.mkv', 'cleaned.mkv', keep_tracks)
사례 2: 다국어 강의 - 오디오 트랙 전환
요구사항:
- 강의 비디오
- 한국어/영어 음성
- 한국어/영어 자막
생성
# 비디오 + 다국어 오디오 + 자막
ffmpeg -i lecture.mp4 \
-i audio_kor.wav \
-i audio_eng.wav \
-i subtitle_kor.srt \
-i subtitle_eng.srt \
-map 0:v:0 \
-map 1:a:0 \
-map 2:a:0 \
-map 3:s:0 \
-map 4:s:0 \
-c:v copy \
-c:a aac -b:a 128k \
-c:s copy \
-metadata:s:a:0 language=kor -metadata:s:a:0 title="한국어" \
-metadata:s:a:1 language=eng -metadata:s:a:1 title="English" \
-metadata:s:s:0 language=kor \
-metadata:s:s:1 language=eng \
-disposition:a:0 default \
lecture_multi.mkv
사례 3: 팟캐스트 아카이브 - 챕터 마커
요구사항:
- 긴 팟캐스트 (2시간)
- 챕터 마커 (주제별)
- 메타데이터
챕터 파일 생성
# chapters.txt
cat > chapters.txt << EOF
CHAPTER01=00:00:00.000
CHAPTER01NAME=인트로
CHAPTER02=00:05:30.000
CHAPTER02NAME=주제 1: 기술 트렌드
CHAPTER03=00:35:00.000
CHAPTER03NAME=주제 2: 커리어
CHAPTER04=00:65:00.000
CHAPTER04NAME=Q&A
CHAPTER05=01:55:00.000
CHAPTER05NAME=아웃트로
EOF
MKV 생성
ffmpeg -i podcast.wav \
-i chapters.txt \
-c:a aac -b:a 128k \
-map_metadata 1 \
-metadata title="팟캐스트 에피소드 1" \
-metadata artist="호스트 이름" \
-metadata date="2026-03-31" \
podcast_ep01.mka
사례 4: 영화 컬렉션 - 감독 해설 트랙
요구사항:
- 원본 오디오
- 감독 해설 오디오
- 한국어/영어 자막
생성
ffmpeg -i movie.mp4 \
-i commentary.wav \
-i subtitle_kor.srt \
-i subtitle_eng.srt \
-map 0:v:0 \
-map 0:a:0 \
-map 1:a:0 \
-map 2:s:0 \
-map 3:s:0 \
-c:v copy \
-c:a aac -b:a 192k \
-c:s copy \
-metadata:s:a:0 title="원본 오디오" \
-metadata:s:a:1 title="감독 해설" \
-metadata:s:s:0 language=kor \
-metadata:s:s:1 language=eng \
-disposition:a:0 default \
movie_deluxe.mkv
최적화 팁
1) 불필요한 트랙 제거
# 비디오 + 첫 번째 오디오만
ffmpeg -i input.mkv \
-map 0:v:0 \
-map 0:a:0 \
-c copy \
slim.mkv
2) 자막 형식 변환
# ASS → SRT
ffmpeg -i input.mkv \
-map 0:s:0 \
-c:s srt \
subtitle.srt
# SRT → ASS
ffmpeg -i subtitle.srt subtitle.ass
3) 오디오 정규화
# 라우드니스 정규화
ffmpeg -i input.mkv \
-c:v copy \
-af "loudnorm=I=-16:TP=-1.5:LRA=11" \
-c:a aac -b:a 192k \
normalized.mkv
트러블슈팅
문제 1: 브라우저에서 재생 안 됨
증상: HTML5 video에서 MKV 재생 불가
<video src="video.mkv" controls></video>
<!-- 대부분 브라우저: 재생 불가 -->
해결: MP4 또는 WebM으로 변환
# MP4로 변환
ffmpeg -i input.mkv \
-c:v libx264 \
-c:a aac \
-movflags +faststart \
output.mp4
문제 2: 자막이 안 보임
증상: 플레이어에서 자막 트랙 인식 안 됨
원인 1: 언어 태그 누락
# 언어 태그 추가
ffmpeg -i input.mkv \
-c copy \
-metadata:s:s:0 language=kor \
output.mkv
원인 2: 코덱 미지원
# ASS → SRT 변환
ffmpeg -i input.mkv \
-map 0:v -map 0:a \
-map 0:s:0 \
-c:v copy -c:a copy \
-c:s srt \
output.mkv
문제 3: 오디오 트랙 선택 안 됨
증상: 플레이어가 항상 첫 번째 오디오만 재생
해결: 기본 트랙 설정
# 두 번째 오디오를 기본으로
ffmpeg -i input.mkv \
-c copy \
-disposition:a:0 0 \
-disposition:a:1 default \
output.mkv
문제 4: 파일 크기 너무 큼
증상: 불필요한 트랙으로 파일 비대
해결: 트랙 정리
# 필요한 트랙만 유지
ffmpeg -i input.mkv \
-map 0:v:0 \
-map 0:a:0 \
-map 0:s:0 \
-c copy \
slim.mkv
문제 5: 챕터 손실
증상: MKV → MP4 변환 시 챕터 사라짐
원인: MP4는 챕터 지원 제한적
해결: MKV 유지 또는 외부 챕터 파일
# 챕터 추출
ffprobe -v error -show_chapters -of json input.mkv > chapters.json
마무리
MKV는 EBML/Matroska 기반으로 다중 트랙·챕터·태그·첨부까지 담기 좋은 유연한 컨테이너입니다.
핵심 요약
-
유연성
- 거의 모든 코덱 지원
- 다중 오디오·자막·챕터
- 첨부 파일 (폰트, 커버)
-
아카이브 최적
- 원본 품질 유지
- 메타데이터 풍부
- 편집 워크플로 친화
-
배포 제약
- 브라우저 지원 제한
- 모바일 호환성 낮음
- MP4 변환 필요
선택 가이드
| 상황 | 추천 |
|---|---|
| 아카이브·보관 | MKV |
| 웹 배포 | MP4/WebM |
| 다중 트랙 필요 | MKV |
| 최대 호환 | MP4 |
| 편집 워크플로 | MKV (중간), MP4 (최종) |
FFmpeg 명령 치트시트
# 기본 리먹스
ffmpeg -i input.mkv -c copy output.mkv
# 다중 오디오 추가
ffmpeg -i video.mp4 -i audio1.wav -i audio2.wav \
-map 0:v -map 1:a -map 2:a \
-c:v copy -c:a aac -b:a 192k \
-metadata:s:a:0 language=kor \
-metadata:s:a:1 language=eng \
output.mkv
# 자막 추가
ffmpeg -i video.mkv -i subtitle.srt \
-map 0 -map 1 \
-c copy \
-metadata:s:s:0 language=kor \
output.mkv
# MKV → MP4
ffmpeg -i input.mkv -c:v copy -c:a copy -movflags +faststart output.mp4
# 트랙 제거
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -c copy slim.mkv
다음 단계
- MP4 비교: MP4 완벽 가이드
- WebM 비교: WebM 웹 표준
- HEVC 코덱: HEVC 실전 가이드
참고 자료
- Matroska 스펙: https://www.matroska.org/technical/specs/index.html
- MKVToolNix: https://mkvtoolnix.download/
- FFmpeg 문서: https://ffmpeg.org/ffmpeg-formats.html#matroska
한 줄 정리: 다중 트랙·챕터·풍부한 메타데이터가 필요하면 MKV로 아카이브하고, 최종 배포는 MP4로 변환한다.