强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

FFmpeg 多媒体处理教程 / 容器格式

容器格式

概述

容器格式(Container Format)是用于存储音频、视频、字幕等多媒体数据的文件格式。容器本身不决定数据的编码方式,而是定义了如何组织和同步这些数据流。本章详细介绍常见容器格式及其使用方法。

容器与编解码器的区别

基本概念

概念说明示例
容器格式存储多媒体数据的文件格式MP4、MKV、AVI
编解码器压缩/解压缩数据的算法H.264、AAC、VP9
流(Stream)容器中的独立数据轨道视频流、音频流、字幕流
┌─────────────────────────────────────────────┐
│              容器文件 (Container)            │
│  ┌─────────────────────────────────────────┐│
│  │  视频流 (Video Stream)                  ││
│  │  编解码器: H.264/H.265/VP9             ││
│  └─────────────────────────────────────────┘│
│  ┌─────────────────────────────────────────┐│
│  │  音频流 (Audio Stream)                  ││
│  │  编解码器: AAC/MP3/Opus                 ││
│  └─────────────────────────────────────────┘│
│  ┌─────────────────────────────────────────┐│
│  │  字幕流 (Subtitle Stream)               ││
│  │  格式: SRT/ASS/VobSub                   ││
│  └─────────────────────────────────────────┘│
│  ┌─────────────────────────────────────────┐│
│  │  元数据 (Metadata)                      ││
│  │  标题、作者、创建时间等                  ││
│  └─────────────────────────────────────────┘│
│  ┌─────────────────────────────────────────┐│
│  │  章节信息 (Chapter Info)                ││
│  │  章节标记、时间戳                        ││
│  └─────────────────────────────────────────┘│
└─────────────────────────────────────────────┘

常见容器格式对比

综合对比表

格式扩展名视频编解码器音频编解码器字幕支持流媒体兼容性说明
MP4.mp4H.264/H.265/VP9/AV1AAC/MP3/OpusTTXT/VobSubHLS极好最通用格式
MKV.mkv几乎所有几乎所有ASS/SRT/SSA/VobSub有限开放格式
AVI.avi几乎所有几乎所有传统格式
MOV.movH.264/H.265/ProResAAC/PCMTTXT有限Apple 格式
FLV.flvH.264/VP6AAC/MP3RTMPFlash 格式
WebM.webmVP8/VP9/AV1Vorbis/OpusWebVTTDASHWeb 格式
MPEG-TS.tsH.264/H.265AAC/MP3DVBHLS/DVB流媒体格式
OGG.oggTheoraVorbis/Opus有限开源格式
WMV.wmvWMVWMA有限Microsoft 格式

格式选择建议

使用场景推荐格式原因
Web 视频MP4兼容性最好,支持 HLS
高清电影MKV支持多音轨、多字幕
流媒体直播FLV/MPEG-TS低延迟,支持推流
Apple 设备MOV/MP4原生支持
开源项目WebM/OGG免版税
存档备份MKV支持所有编解码器
移动设备MP4通用兼容

MP4 格式详解

MP4 特性

特性支持说明
多音轨支持多个音频流
多字幕TTXT、VobSub 格式
章节通过元数据支持
流媒体支持 HLS、DASH
元数据丰富的元数据支持
快速启动faststart 选项
分片支持分片 MP4

MP4 封装选项

# 基本 MP4 封装
ffmpeg -i input.mkv -c:v libx264 -c:a aac output.mp4

# 快速启动(Web 播放优化)
ffmpeg -i input.mkv -c:v libx264 -c:a aac -movflags +faststart output.mp4

# 分片 MP4(DASH/HLS)
ffmpeg -i input.mkv -c:v libx264 -c:a aac \
    -movflags +frag_keyframe+empty_moov+default_base_moof output.mp4

# 碎片化 MP4
ffmpeg -i input.mkv -c:v libx264 -c:a aac \
    -movflags +frag_keyframe+separate_moof+omit_tfhd_offset output.mp4

MP4 常用参数

参数说明示例
+faststart将 moov 原子移到文件开头-movflags +faststart
+frag_keyframe在关键帧处分片-movflags +frag_keyframe
+empty_moov创建空的 moov 原子-movflags +empty_moov
+default_base_moof默认基地址-movflags +default_base_moof
+separate_moof独立的 moof 原子-movflags +separate_moof
+omit_tfhd_offset省略 tfhd 偏移-movflags +omit_tfhd_offset
+dashDASH 兼容-movflags +dash

MP4 元数据编辑

# 添加元数据
ffmpeg -i input.mp4 \
    -metadata title="视频标题" \
    -metadata artist="作者" \
    -metadata date="2024" \
    -metadata comment="备注" \
    -c copy output.mp4

# 删除元数据
ffmpeg -i input.mp4 -map_metadata -1 -c copy output.mp4

# 从文件读取元数据
ffmpeg -i input.mp4 -map_metadata 1 -i metadata.txt -c copy output.mp4

MKV 格式详解

MKV 特性

特性支持说明
多音轨无限制
多字幕ASS/SRT/SSA/VobSub/PGS
章节XML 章节格式
元数据标签系统
附件字体、图片等
菜单简单菜单支持
流媒体⚠️有限支持

MKV 封装选项

# 基本 MKV 封装
ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mkv

# 保留所有流
ffmpeg -i input.mp4 -map 0 -c copy output.mkv

# 添加多音轨
ffmpeg -i video.mp4 -i audio1.mp3 -i audio2.aac \
    -map 0:v -map 0:a -map 1:a -map 2:a \
    -c:v copy -c:a copy \
    -metadata:s:a:0 language=chi \
    -metadata:s:a:1 language=eng \
    output.mkv

# 添加字幕
ffmpeg -i input.mp4 -i subtitle.srt -i subtitle.ass \
    -map 0 -map 1 -map 2 \
    -c:v copy -c:a copy -c:s srt \
    output.mkv

MKV 章节编辑

# 创建章节文件 chapters.xml
cat > chapters.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<Chapters>
  <EditionEntry>
    <ChapterAtom>
      <ChapterTimeStart>00:00:00.000</ChapterTimeStart>
      <ChapterTimeEnd>00:05:00.000</ChapterTimeEnd>
      <ChapterDisplay>
        <ChapterString>第一章</ChapterString>
      </ChapterDisplay>
    </ChapterAtom>
    <ChapterAtom>
      <ChapterTimeStart>00:05:00.000</ChapterTimeStart>
      <ChapterTimeEnd>00:10:00.000</ChapterTimeEnd>
      <ChapterDisplay>
        <ChapterString>第二章</ChapterString>
      </ChapterDisplay>
    </ChapterAtom>
  </EditionEntry>
</Chapters>
EOF

# 应用章节
ffmpeg -i input.mkv -i chapters.xml -map_metadata 1 -c copy output.mkv

MKV 流语言设置

# 设置音频流语言
ffmpeg -i input.mkv \
    -metadata:s:a:0 language=chi \
    -metadata:s:a:1 language=eng \
    -c copy output.mkv

# 设置字幕流语言
ffmpeg -i input.mkv \
    -metadata:s:s:0 language=chi \
    -metadata:s:s:1 language=eng \
    -c copy output.mkv

# 设置默认流
ffmpeg -i input.mkv \
    -disposition:a:0 default \
    -disposition:a:1 0 \
    -c copy output.mkv

FLV 格式详解

FLV 特性

特性支持说明
多音轨仅支持单音轨
字幕不支持
章节不支持
流媒体RTMP 推流
元数据基本元数据
低延迟适合直播

FLV 封装选项

# 基本 FLV 封装
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f flv output.flv

# RTMP 推流
ffmpeg -re -i input.mp4 \
    -c:v libx264 -preset ultrafast -tune zerolatency \
    -c:a aac -b:a 128k \
    -f flv rtmp://server/live/stream

# 带元数据的 FLV
ffmpeg -i input.mp4 \
    -c:v libx264 -c:a aac \
    -metadata title="直播标题" \
    -f flv output.flv

MPEG-TS 格式详解

MPEG-TS 特性

特性支持说明
多音轨PID 标识
字幕DVB 字幕
章节不支持
流媒体HLS/DVB
错误恢复包级错误恢复
低延迟⚠️取决于配置

MPEG-TS 封装选项

# 基本 MPEG-TS 封装
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f mpegts output.ts

# HLS 分片
ffmpeg -i input.mp4 -c:v libx264 -c:a aac \
    -f hls -hls_time 4 -hls_list_size 0 \
    -hls_segment_filename "segment_%03d.ts" \
    playlist.m3u8

# 低延迟 MPEG-TS
ffmpeg -i input.mp4 -c:v libx264 -c:a aac \
    -mpegts_flags +resend_headers \
    -f mpegts output.ts

MPEG-TS 流标识

# 设置流类型
ffmpeg -i input.mp4 -c:v libx264 -c:a aac \
    -streamid 0:256 -streamid 1:257 \
    -f mpegts output.ts

# 查看流信息
ffprobe -show_streams output.ts

WebM 格式详解

WebM 特性

特性支持说明
多音轨⚠️有限支持
字幕WebVTT 格式
章节不支持
流媒体DASH
元数据基本元数据
免版税VP8/VP9/AV1 + Vorbis/Opus

WebM 封装选项

# VP9 + Opus
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webm

# VP8 + Vorbis
ffmpeg -i input.mp4 -c:v libvpx -b:v 2M -c:a libvorbis output.webm

# AV1 + Opus
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -b:v 0 -c:a libopus output.webm

# 分片 WebM (DASH)
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus \
    -dash 1 output.webm

格式转换

常见格式转换

# AVI 转 MP4
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4

# MKV 转 MP4
ffmpeg -i input.mkv -c:v copy -c:a copy output.mp4

# FLV 转 MP4
ffmpeg -i input.flv -c:v copy -c:a copy output.mp4

# MOV 转 MP4
ffmpeg -i input.mov -c:v copy -c:a copy output.mp4

# MP4 转 WebM
ffmpeg -i input.mp4 -c:v libvpx-vp9 -c:a libopus output.webm

# MP4 转 MKV
ffmpeg -i input.mp4 -c copy output.mkv

无损转换

# 直接复制流(无损,最快)
ffmpeg -i input.avi -c copy output.mp4

# 仅复制特定流
ffmpeg -i input.mkv -map 0:v -map 0:a:0 -c copy output.mp4

带滤镜的格式转换

# 转换并缩放
ffmpeg -i input.avi -vf scale=1280:720 -c:v libx264 -c:a aac output.mp4

# 转换并裁剪
ffmpeg -i input.mkv -vf crop=1280:720:0:0 -c:v libx264 -c:a aac output.mp4

# 转换并添加水印
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=10:10" -c:v libx264 -c:a copy output.mkv

多流处理

多音轨处理

# 提取特定音轨
ffmpeg -i input.mkv -map 0:v -map 0:a:1 -c copy output.mp4

# 合并多音轨
ffmpeg -i video.mp4 -i audio_en.mp3 -i audio_cn.mp3 \
    -map 0:v -map 1:a -map 2:a \
    -c:v copy -c:a aac \
    -metadata:s:a:0 language=eng \
    -metadata:s:a:1 language=chi \
    output.mkv

# 混合音轨
ffmpeg -i input.mkv -filter_complex "[0:a:0][0:a:1]amix=inputs=2:duration=longest[a]" \
    -map 0:v -map "[a]" -c:v copy -c:a aac output.mp4

多字幕处理

# 添加外部字幕
ffmpeg -i input.mp4 -i subtitle.srt \
    -map 0 -map 1 \
    -c:v copy -c:a copy -c:s mov_text \
    output.mp4

# 提取字幕
ffmpeg -i input.mkv -map 0:s:0 output.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

流映射策略

# 选择所有流
ffmpeg -i input.mkv -map 0 -c copy output.mkv

# 选择特定类型的第一个流
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -c copy output.mp4

# 排除特定流
ffmpeg -i input.mkv -map 0 -map -0:s -c copy output.mp4

# 从多个输入选择流
ffmpeg -i video.mp4 -i audio.mp3 -i subtitle.srt \
    -map 0:v -map 1:a -map 2:s \
    -c copy output.mkv

容器格式检测

使用 ffprobe 检测

# 基本信息
ffprobe input.mp4

# JSON 格式输出
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4

# 仅显示格式信息
ffprobe -v quiet -show_format input.mp4

# 仅显示流信息
ffprobe -v quiet -show_streams input.mp4

# 选择特定流信息
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,width,height input.mp4

格式检测脚本

#!/bin/bash
# detect_format.sh

FILE=$1

echo "=== 文件信息 ==="
echo "格式: $(ffprobe -v quiet -show_entries format=format_name -of csv=p=0 "$FILE")"
echo "时长: $(ffprobe -v quiet -show_entries format=duration -of csv=p=0 "$FILE") 秒"
echo "大小: $(ls -lh "$FILE" | awk '{print $5}')"

echo -e "\n=== 流信息 ==="
ffprobe -v quiet -show_entries stream=index,codec_type,codec_name,width,height,r_frame_rate,sample_rate,channels -of csv=p=0 "$FILE"

echo -e "\n=== 视频流 ==="
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate,pix_fmt -of csv=p=0 "$FILE"

echo -e "\n=== 音频流 ==="
ffprobe -v quiet -select_streams a:0 -show_entries stream=codec_name,sample_rate,channels,channel_layout -of csv=p=0 "$FILE"

容器格式最佳实践

场景 1:Web 发布

# MP4 + faststart(推荐)
ffmpeg -i input.mkv \
    -c:v libx264 -preset slow -crf 23 \
    -profile:v high -level 4.1 \
    -movflags +faststart \
    -c:a aac -b:a 128k \
    output_web.mp4

场景 2:高质量存档

# MKV + 多音轨 + 字幕
ffmpeg -i input.mp4 \
    -map 0 \
    -c:v libx265 -preset slow -crf 22 \
    -c:a copy \
    -c:s copy \
    output_archive.mkv

场景 3:流媒体

# HLS 分片
ffmpeg -i input.mp4 \
    -c:v libx264 -preset fast -crf 23 \
    -c:a aac -b:a 128k \
    -f hls -hls_time 4 -hls_list_size 0 \
    -hls_segment_filename "segment_%03d.ts" \
    playlist.m3u8

场景 4:移动设备

# 兼容性 MP4
ffmpeg -i input.mkv \
    -c:v libx264 -profile:v baseline -level 3.0 \
    -vf scale=640:480 \
    -c:a aac -b:a 96k -ar 44100 -ac 2 \
    output_mobile.mp4

注意事项

  1. 格式兼容性:不同播放器和设备对格式的支持程度不同
  2. 流选择:使用 -map 明确指定流,避免自动选择问题
  3. 元数据保留:使用 -map_metadata 保留或删除元数据
  4. 分片选项:流媒体需要使用分片格式
  5. 编码器兼容性:某些容器不支持特定编解码器

扩展阅读

  1. FFmpeg 格式文档
  2. MP4 格式规范
  3. Matroska 格式规范
  4. WebM 格式规范
  5. HLS 规范

总结

本章介绍了 FFmpeg 支持的各种容器格式,包括:

  • 容器格式的概念和分类
  • MP4、MKV、FLV、TS、WebM 等格式的特性
  • 格式转换方法
  • 多流处理技巧
  • 容器格式检测

掌握这些知识可以帮助您根据不同的使用场景选择合适的容器格式。