Web Video MimeCodec 究竟代表什么意思?
大家才开始学习 MediaSource 的时候,我们都会好奇,其中指定 mimeCodec
的行为:
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource();
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
很多人不太理解这个 mimeCodec
代表着什么意思。
HTML5 在提供对视频的支持的时候,支持了一个方法,叫 canPlayType 。它主要用于测试当前浏览器是否可以支持播放给出的视频的 MIME type。
你可以在这里看到 codecs_parameter目前绝大多数支持的视频格式类型。
我们拆开看
video/mp4; codecs="avc1.42E01E, mp4a.40.2"
video/mp4;
avc1.42E01E
mp4a.40.2
video/mp4
可能大家都很熟悉,我们在 HTTP 返回的 Header 里也经常看到,类似我们经常还看见一些类似 text/plain
, image/png
等。而对于音视频而言常见的类型也就那么几种:
video/webm
video/mp4
video/quicktime
audio/ogg
audio/mpeg
而这些仅仅是代表当前资源的格式。通过格式我们可以初步看出是否对 Web 友好。
那么接下来我们看的可能大家有点懵逼了。
后面这一部分 cdoec=?
其实主要是用于视频用上面编码的,比如是 H.264 还是 H.265 还是早期的 MPEG-4(终于理解初中 火影忍者DVD 上的意思) 等。
我们 再看 avc1.42E01E
表示什么意思。
参考 RFC6381 中定义:
codecs := cod-simple / cod-fancy
所以其中 avc1 代表的编码采样数据,这里可以是 avc1,avc2, 又或者是 mp4a, mp4v。总之你看到 AVC的话,表示基于 H.264 来进行编解码的。看到 vp9
就表示基于 VP9 来进行编解码的。看到 hevc
的话表示视频是基于 H.265 编码的。
而 cod-fancy 是由一个 16进制字符串组成的。而 AVC 编码下组有三个部分组成
avc1.PPCCLL
PP = profile_idc
CC = constraint_set flags
LL = level_idc
其中 profile_idc 中表示 H.264 编解码中编码器的特性概述,不同的值,需要的编码性能不一样,在官方定义的常见有下面这些:
enum eAVEncH264VProfile {
eAVEncH264VProfile_unknown = 0,
eAVEncH264VProfile_Simple = 66,
eAVEncH264VProfile_Base = 66,
eAVEncH264VProfile_Main = 77,
eAVEncH264VProfile_High = 100,
eAVEncH264VProfile_422 = 122,
eAVEncH264VProfile_High10 = 110,
eAVEncH264VProfile_444 = 144,
eAVEncH264VProfile_Extended = 88,
eAVEncH264VProfile_ScalableBase = 83,
eAVEncH264VProfile_ScalableHigh = 86,
eAVEncH264VProfile_MultiviewHigh = 118,
eAVEncH264VProfile_StereoHigh = 128,
eAVEncH264VProfile_ConstrainedBase = 256,
eAVEncH264VProfile_UCConstrainedHigh = 257,
eAVEncH264VProfile_UCScalableConstrainedBase = 258,
eAVEncH264VProfile_UCScalableConstrainedHigh = 259
};
所以 0x42
也就是上面的 eAVEncH264VProfile_Base
;
其中 constraint_set flags
则表示编码级别的约束条件,常见的有下面的几种
constraint_set0_flag
constraint_set1_flag
constraint_set2_flag
constraint_set3_flag
constraint_set4_flag
constraint_set5_flag
他们分别针对不同的 profie 而制定。 而其中 0xE0
转换成二进制 11100000 也就是表示constraint_set2_flag
。
其中 level_idc
表示视频编码本身的视频参数,比如分辨率,码率,帧率等。Level 越高视频质量就相对越好。
而参考 eAVEncH264VLevel Enumeration Level常见的定义级别
enum eAVEncH264VLevel {
eAVEncH264VLevel1 = 10,
eAVEncH264VLevel1_b = 11,
eAVEncH264VLevel1_1 = 11,
eAVEncH264VLevel1_2 = 12,
eAVEncH264VLevel1_3 = 13,
eAVEncH264VLevel2 = 20,
eAVEncH264VLevel2_1 = 21,
eAVEncH264VLevel2_2 = 22,
eAVEncH264VLevel3 = 30,
eAVEncH264VLevel3_1 = 31,
eAVEncH264VLevel3_2 = 32,
eAVEncH264VLevel4 = 40,
eAVEncH264VLevel4_1 = 41,
eAVEncH264VLevel4_2 = 42,
eAVEncH264VLevel5 = 50,
eAVEncH264VLevel5_1 = 51,
eAVEncH264VLevel5_2 = 51
}
那么 0x1E
则表示 eAVEncH264VLevel3
。
这样大家是不是了解这些值具体的含义,不同 编码同样 code-fancy 也不一样,比如我们看到的 vp9,
var mime = 'video/webm; codecs="opus, vp09.00.10.08"';
这个需要去不同的编码定义里去寻找具体含义。
当然,开发不用太关心怎么去设置,这个是转码需要关心的,你可以阅读 使用 JS 获取视频 Codec 使用工具或者代码来获取这些值。