下文仅为粗略介绍,可能有细节上的错误。
视频文件通常有许多种后缀,比如mp4, mkv, avi等等,为了在特定设备上播放某些视频,你也肯定使用过各种转码工具将其转换成合适的格式。
但是这些格式,这些不同的后缀,到底代表了什么?本篇将大概介绍视频的基本构成。
1. 容器 | Container
视频文件的常见后缀有mp4,mkv,flv等等,很多人可能以为这些后缀就代表了视频的编码格式,事实并非如此。
视频文件本身其实是一个个的容器(Container),视频的主体:画面、声音,甚至字幕都可以存放在该容器中,而文件的后缀实际上描述的是该容器的“型号”:比如mp4后缀的“视频文件”,实际上是一个包含画面、声音信息的容器,而该容器的格式遵循“mp4”这个标准。播放器通过识别后缀来区分不同容器的格式,并适应不同容器的规格,读取其中的画面及声音等信息。
2. 编码 | Codec
从上述的容器中提取出画面信息或者声音信息后,解码器就该登场了。通常画面、声音这些内容被称为一条条的“流”。
我随便打开一个电脑上的mp4文件,查看媒体信息。
可以看到画面部分的编码为H264,而这只是千千万种编码的一种,具体取决于原视频是何如被编码的。但是重要的是,即使是使用不同编码的画面信息,只要容器制式允许,他们都可以放在同一个类型的容器里。也就是说可能一个foo后缀的视频文件,其中既可以放A编码格式的画面,也可以放B编码格式的画面。文件后缀与其中视频所使用的编码格式并无强制的对应关系。
下图说明视频转换编码的基本流程
其中,muxer/demuxer 负责封装/拆开容器。
coder/decoder 负责将视频转码:通常是将一种编码的视频解码为一种中间状态,然后再编码成目标格式。
那既然视频只是一个容器,而且能放下不同编码的视频,那我们还需要转码干什么?
由于各种各样的原因,不同容器支持的编码格式也不相同。如果容器不支持某种编码格式,那么这类的视频要想放进这个容器,就只能进行转码。
当然也有不需要转码便可以更改视频容器的情况。比如我有一个mkv格式的文件,存放着H264格式的视频.如果我想将其转为mp4格式以便导入我的只支持mp4格式视频的垃圾爱疯的话,我只需要将原mkv容器中的画面信息及声音取出,并原封不动的放入mp4容器,由于不需要进行如何转码,因此这个过程非常快。使用ffmpeg这个强大的音视频转码工具可以轻松的做到这一点:
ffmpeg -i input.mkv -c copy output.mp4
有关ffmpeg的使用可参考其他网上的教程。
事实上,有不少转码软件最终调用的就是ffmpeg进行实际的转码工作。因此对于需要长期接触音视频处理的同学,我强烈推荐熟悉熟悉ffmpeg这个工具。不过我也不是这专业的人,因此不敢保证这东西能完全取代常用的转码工具。但我觉得它能让用户了解不少底层的信息,相比使用包装好的软件而不知道它们具体做了什么,知道底层的实现总不是坏事。