video不能播放mp4的问题(一)

最近项目中遇到了video标签无法播放mp4的问题,表现如下:
  1. IE可正常播放
  2. safari需要点击两次可播放
  3. chrome内核系列都不能播放
原因排除
  1. 首先,排除掉代码错误:替换其它可播放的mp4文件
  2. 其次,排除路径错误 :F12控制台查看网络请求
  3. 最后,浏览器是否支持:网上查找支持范围,或在较新版的chrome测试

一、视频格式

video标签只支持MPEG4,Ogg,WebM三种视频格式,各浏览器支持如下:

格式 IE Firefox Opera Chrome Safari
Ogg - 3.5+ 10.5+ 5.0+ -
MPEG 4 9.0+ - - 5.0+ 3.0+
WebM - 4.0+ 10.6+ 6.0+ -

二、视频编码

其实,上面的三种格式只是封装格式,并非编码,而video标签对编码也是有要求的:

格式 视频编码 音频编码
Ogg Theora Vorbis
MPEG 4 H.264 AAC
WebM VP8 Vorbis

是不是以为找到了问题: 问题mp4肯定不是h264编码
too naive !!! 这么明显的编码方式,视频生成人员怎能不知

三、工具ffmpeg

不知道ffmpeg是什么?
自行搜索
mac下可用homebrew快速安装:

brew install ffmpeg

ffmpeg也可在node中使用:

npm install ffmpeg //安装
var ffmpeg = require('ffmpeg');

地址:https://www.npmjs.com/package/ffmpeg

三、查看编码

ffmpeg -i input.mp4 
ffmpeg -i input2.mp4 
不能播放

正常播放

h264后括号内的内容不同,是不是觉得已经接近真相了

四、AVC编码

AVC其实就是H.264标准,是由ITU-T和ISO/IEC组成的联合视频组(JVT,Joint Video Team)一起开发的,ITU-T给这个标准命名为H.264(以前叫做H.26L),而ISO/IEC称它为MPEG-4 高级视频编码(Advanced Video Coding,AVC),它定位于覆盖整个视频应用领域,包括:低码率的无线应用、标准清晰度和高清晰度的电视广播应用、Internet上的视频流应用,传输高清晰度的DVD视频以及应用于数码相机的高质量视频应用等等。

AVC规格分为三等,从低到高分别为:Baseline、Main、High。

规格 说明 用途
Baseline(最低Profile) 级别支持I/P 帧,只支持无交错(Progressive)和CAVLC 低阶或需要额外容错的应用,比如视频通话、手机视频等;
Main(主要Profile) 级别提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced),同样提供对于CAVLC 和CABAC 的支持 主流消费类电子产品规格如低解码(相对而言)的mp4、便携的视频播放器、PSP和Ipod等
High(高端Profile,也叫FRExt) 级别在Main的基础上增加了8x8 内部预测、自定义量化、无损视频编码和更多的YUV 格式(如4:4:4) 用于广播及视频碟片存储(蓝光影片),高清电视的应用。

五、音频、视频分离

ffmpeg -i input.mp4 -vcodec copy -an video.mp4 //提取视频
视频文件(正常播放视频)
ffmpeg -i input.mp4 -acodec copy -vn audio.mp4 //提取音频
音频文件 (不能播放声音)
ffmpeg -i audio.mp4 -acodec aac audio1.mp4 //音频转码
音频转码(正常播放声音)

为了排除音频、视频组合干扰
需要用到控制变量法:

  1. 音频不变,视频转码
ffmpeg -i input.mp4 -c:a copy output.mp4 //音频拷贝,视频转码
音频拷贝,视频转码(不能播放)
  1. 视频不变,音频转码
ffmpeg -i input.mp4 -c:v copy output.mp4  //音频转码,视频拷贝
音频转码,视频拷贝(正常播放)

结论:音频才是问题所在

五、mono、stereo

音频channel(声道数):1就是单声道mono,2就是立体声stereo,其中单声道的容量是立体声的一半。在ffmpeg中可以通过参数-ac进行设置

ffmpeg -i input.mp4 -ac 2 -vcodec copy output.mp4 //音频声道切换,视频拷贝
音频声道切换,视频拷贝 (正常播放)
ffmpeg -i audio.mp4 -ac 2 audio1.mp4 //音频声道切换stereo
音频声道切换stereo(正常播放声音)

即使只是重新设置channel 为1(mono)

ffmpeg -i audio.mp4 -ac 1 audio1.mp4 //音频声道重新设置为mono
音频声道切换mono(正常播放声音)
ffmpeg -i input.mp4 -vcodec h264 output.mp4 //h264默认转码

h264默认转码(正常播放)

结论:这锅monostereo不背

六、比特率

经过观察:在所有不可播放的文件中,最后一个红色标记比特率都是 62 kb/s

比特率是指每秒传送的比特(bit)数。单位bps(Bit Per Second),比特率越高,传送数据速度越快。
声音中的比特率: 是指将模拟声音信号转换成数字声音信号后,单位时间内的二进制数据量,是间接衡量音频质量的一个指标。
视频中的比特率(码率):原理与声音中的相同,都是指由模拟信号转换为数字信号后,单位时间内的二进制数据量。

ffmpeg -i audio.mp4 -ab 64 audio1.mp4 //修改比特率,无论任何值,最终都是14kb/s
修改比特率(正常播放声音)
ffmpeg -i audio.mp4 -ar 44100 audio1.mp4 //重置采样率,只能为某些固定值,最后都是70kb/s
重置采样率(正常播放声音)

结论:比特率才是罪魁祸首

七、小结

实际过程中遇到的mp4文件参数可能不尽相同,但应该都可以通过本文测试方法定位到问题。

由于作者没有专业编码经验,不太了解:

  1. 为什么采样率只能用某些固定的值;
  2. 为什么修改比特率效果不尽理想,只能改成特定的值,
  3. 本例中,采用默认h264转码后比特率为70,修改比特率后变成14,修改声道后变成128,这些是否有特定规律

若有专业人士看见此文,
望不吝赐教,不胜感激。

推荐阅读更多精彩内容