MKV(Matroska) 컨테이너 실전 활용 | EBML·다중 자막·FFmpeg 리먹스

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 호환성 축으로 선택할 수 있습니다
  • 자주 막히는 플레이어 이슈를 원인별로 줄일 수 있습니다

목차

  1. 컨테이너 개요
  2. 내부 구조
  3. 실전 사용
  4. 성능 비교
  5. 실무 활용 사례
  6. 최적화 팁
  7. 트러블슈팅
  8. 마무리

컨테이너 개요

역사 및 개발 배경

MatroskaMCF 등 기존 포맷을 대체하려는 목적으로 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

특징MKVMP4WebM
코덱 지원거의 모든 코덱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

마무리

MKVEBML/Matroska 기반으로 다중 트랙·챕터·태그·첨부까지 담기 좋은 유연한 컨테이너입니다.

핵심 요약

  1. 유연성

    • 거의 모든 코덱 지원
    • 다중 오디오·자막·챕터
    • 첨부 파일 (폰트, 커버)
  2. 아카이브 최적

    • 원본 품질 유지
    • 메타데이터 풍부
    • 편집 워크플로 친화
  3. 배포 제약

    • 브라우저 지원 제한
    • 모바일 호환성 낮음
    • 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 실전 가이드

참고 자료

한 줄 정리: 다중 트랙·챕터·풍부한 메타데이터가 필요하면 MKV로 아카이브하고, 최종 배포는 MP4로 변환한다.