前言
最近一些客户遇到,mp4格式的视频文件,在浏览器播放有声音,但在ios播放无声音。还有这种情况?
客户业务着急上线,我们来看看是什么原因导致这个现象,怎样能快速解决客户的困扰。
问题定位
一、视频信息确认
首先,我们来看下视频的信息,发现音频是 AAC_HE_V2 编码格式。
这是什么编码格式呢?引用雷霄骅前辈的文章,我们先了解下常见AAC规格,有三种:LC-AAC(最基本的),HE-AAC(AACPlus v1),HE-AAC v2(AACPlus v2)。他们三个的关系如下图所示:
HE:“High Efficiency”(高效性)。HE-AAC v1(又称AACPlusV1,SBR),用容器的方法实现了AAC(LC)和SBR技术。SBR其实代表的是Spectral Band Replication(频段复制)。简要叙述一下,音乐的主要频谱集中在低频段,高频段幅度很小,但很重要,决定了音质。如果对整个频段编码,若是为了 保护高频就会造成低频段编码过细以致文件巨大;若是保存了低频的主要成分而失去高频成分就会丧失音质。SBR把频谱切割开来,低频单独编码保存主要成分, 高频单独放大编码保存音质,“统筹兼顾”了,在减少文件大小的情况下还保存了音质,完美的化解这一矛盾。
HEv2:用容器的方法包含了HE-AAC v1和PS技术。PS指“parametric stereo”(参数立体声)。原来的立体声文件文件大小是一个声道的两倍。但是两个声道的声音存在某种相似性,根据香农信息熵编码定理,相关性应该被去掉才能减小文件大小。所以PS技术存储了一个声道的全部信息,然后,花很少的字节用参数描述另一个声道和它不同的地方。
在低码率的情况下,HE-AAC,HE-AAC v2编码后的音质要明显好于LC-AAC。
二、苹果版本对HE-AAC v2的支持
经过苹果官网每款手机机型的技术规格确认,发现iPhone SE、iPhone 6s Plus、iPhone 6s、iPhone 6 Plus,iPhone 6以及之前的版本技术规格都不支持音频HE-AAC v2编码格式。如下图为iPhone 6 - 技术规格中支持的声音文件格式,不支持HE-AAC v2格式:
下图iPhone 7 - 技术规格中支持的声音文件格式,支持HE-AAC v2格式:
三、问题定位
是IOS不支持AAC_HE_V2解码吗?不可能的。这是苹果官方主推的音频格式,而且我们上面已经在官网各个机型确认过。
网上查了各种资料,原来IOS用AudioFile相关API解码或播放AAC_HE_V2这个第三方编码库中的编码格式存在兼容性问题:
在官方AQPlayer Demo 和 aqofflinerender中,都使用了AudioFile相关的API来读取音频文件,大部分情况下是没问题的。但在读取或播放AAC_HE_V2格式音频时,会出现仅仅能把原本双声道44100采样率的文件当成单声道22050采样来读取的问题。问题出在AudioFileGetProperty调用kAudioFilePropertyDataFormat时,仅仅会获取到最低级别的编码层级。
AAC_HE_V2编码包含了三层格式。(拿源文件44100双声道举列)第一层:仅仅支持22050,单声道。第二层,支持44100。单声道。第三层支持44100,双声道。
好吧,兼容性问题,播放无声音的原因终于找到了。
参考:https://www.cnblogs.com/bhlsheji/p/5266638.html
解决方案
那我们如何解决呢?这时候要借助ffmpeg,将源文件视频复制不编码,音频编码,音频默认是lc的,如下:
ffmpeg -i input.mp4 -vcodec copy output.mp4
我们再来看下处理后的文件信息:
重新用IOS手机播放一下,声音恢复正常。
进一步说明
当然,如果不想整体替换文件,可以使用云点播的转码功能,不用关心底层转码的实现逻辑,也不需要自己维护,
方便快捷,将转码url分发就可以了,而且费用也便宜。
如何对视频进行转码可参考:
https://cloud.tencent.com/document/product/266/45688。
转码计费可参考:
https://cloud.tencent.com/document/product/266/14666#.E8.A7.86.E9.A2.91.E8.BD.AC.E7.A0.81.3Cspan-id-.3D.22p2.22.3E.3C.2Fspan.3E。
小结
以上针对IOS播放第三方编码库Fraunhofer FDK AAC中的AAC_HE_V2音频编码格式存在兼容性的问题,对原因进行了分析,并提供了修复文件以及转码的方法,客户可以根据实际业务需要,自行选择修复或者转码的方式解决。