简介:项目需求是实现在线音频的变速播放功能,项目开发之前就已经了解到原生的AVPlayer有变速播放的功能,于是很愉快的基于AVPlayer封装了一个播放器。但是后来测试变速播放的时候发现慢速播放有明显的回音,用户的体验的影响比较大,需要解决慢速播放有回音的问题。于是查看了一下AVPlayer类的头文件,发现没有相关的属性和方法可以解决这个问题。
多媒体基础层.png
解决思路:一开始,有两个
1、找一下有没有满足在线音频的变速播放功能的第三方播放器库
2、有没有什么方法可以去除AVPlayer慢速播放有回音的问题
3、找一下原生的其他底层的媒体库
第一个思路:
1、豆瓣开源的播放器DOUAudioStreamer不支持变速播放
2、FreeStreamer慢速播放也有回音
2、StreamingKit慢速播放也有回音
第二个思路:
1、研究了底层AudioToolbox库的AudioUinit,主要用来对录音进行降噪处理
后面发现第三个思路:
1、研究原生的AVAudioEngine,支持音频慢速播放没有回音,但是只支持本地音频文件的播放,于是就集成了FreeStreamer进行下载音频输出音频文件,但是FreeStreamer对音频格式有限,于是这个思路又陷入困境。
这样研究一圈又陷入死胡同,于是就回头想一想,看一下AVPlayer是不是有其他对方法被遗漏,发现之前只看了一下AVPlayer类的头文件和简单浏览了一下AVPlayerItem类的头文件,AVPlayerItem里面的属性和方法比较多,可能会有相关的设置,于是就回过头重新从头到尾仔细的看了一下AVPlayerItem类的头文件,发现隐藏在比较下面的属性audioTimePitchAlgorithm长得更之前研究AVAudioEngine时用到的变速节点AVAudioUnitTimePitch类有的像,上面的说明表明这个属性的设置可以用于以不同速率管理音频音高和缩放音频编辑的处理算法,iOS系统的默认值为AVAudioTimePitchAlgorithmLowQualityZeroLatency,OS X系统默认值为AVAudioTimePitchAlgorithmSpectral
/*!
@property audioTimePitchAlgorithm
@abstract Indicates the processing algorithm used to manage audio pitch at varying rates and for scaled audio edits.
@discussion
Constants for various time pitch algorithms, e.g. AVAudioTimePitchSpectral, are defined in AVAudioProcessingSettings.h.
The default value on iOS is AVAudioTimePitchAlgorithmLowQualityZeroLatency and on OS X is AVAudioTimePitchAlgorithmSpectral.
*/
@property (copy) AVAudioTimePitchAlgorithm audioTimePitchAlgorithm API_AVAILABLE(macos(10.9), ios(7.0), tvos(9.0), watchos(1.0));
于是上网搜了一下audioTimePitchAlgorithm属性的相关信息,然后在这篇文章AVPlayer视频播放之 - AVPlayerItem找到了以下相关的信息
/*!
@typedef AVAudioTimePitchAlgorithm
@abstract
The type of a time pitch algorithm.
@discussion
On OS X, the default algorithm for all time pitch operations is AVAudioTimePitchAlgorithmSpectral. On iOS, the default algorithm for playback is AVAudioTimePitchAlgorithmLowQualityZeroLatency and the default for export & other offline processing is AVAudioTimePitchAlgorithmSpectral.
For scaled audio edits, i.e. when the timeMapping of an AVAssetTrackSegment is between timeRanges of unequal duration, it is important to choose an algorithm that supports the full range of edit rates present in the source media. AVAudioTimePitchAlgorithmSpectral is often the best choice due to the highly inclusive range of rates it supports, assuming that it is desirable to maintain a constant pitch regardless of the edit rate. If it is instead desirable to allow the pitch to vary with the edit rate, AVAudioTimePitchAlgorithmVarispeed is the best choice.
*/
typedef NSString * AVAudioTimePitchAlgorithm NS_STRING_ENUM;
/*!
@abstract Values for time pitch algorithm
@constant AVAudioTimePitchAlgorithmLowQualityZeroLatency
Low quality, very inexpensive. Suitable for brief fast-forward/rewind effects, low quality voice.
Rate snapped to {0.5, 0.666667, 0.8, 1.0, 1.25, 1.5, 2.0}.
@constant AVAudioTimePitchAlgorithmTimeDomain
Modest quality, less expensive. Suitable for voice.
Variable rate from 1/32 to 32.
@constant AVAudioTimePitchAlgorithmSpectral
Highest quality, most computationally expensive. Suitable for music.
Variable rate from 1/32 to 32.
@constant AVAudioTimePitchAlgorithmVarispeed
High quality, no pitch correction. Pitch varies with rate.
Variable rate from 1/32 to 32.
*/
AVF_EXPORT AVAudioTimePitchAlgorithm const AVAudioTimePitchAlgorithmLowQualityZeroLatency API_AVAILABLE(ios(7.0), tvos(9.0), watchos(1.0)) API_UNAVAILABLE(macos);
AVF_EXPORT AVAudioTimePitchAlgorithm const AVAudioTimePitchAlgorithmTimeDomain API_AVAILABLE(macos(10.9), ios(7.0), tvos(9.0), watchos(1.0));
AVF_EXPORT AVAudioTimePitchAlgorithm const AVAudioTimePitchAlgorithmSpectral API_AVAILABLE(macos(10.9), ios(7.0), tvos(9.0), watchos(1.0));
AVF_EXPORT AVAudioTimePitchAlgorithm const AVAudioTimePitchAlgorithmVarispeed API_AVAILABLE(macos(10.9), ios(7.0), tvos(9.0), watchos(1.0));
解决方法:
最后,把audioTimePitchAlgorithm的值设为AVAudioTimePitchAlgorithmTimeDomain后,慢速播放就没有回音了
self.playerItem = [[AVPlayerItem alloc] initWithAsset:_asset];
self.playerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmTimeDomain;
总结:
1、AVPlayer其实也是基于AVAudioEngine,或者AVAudioEngine基于的库实现的,audioTimePitchAlgorithm的不同取值其实对应了,AVAudioEngine的不同节点类比如AVAudioUnitTimePitch、AVAudioUnitVarispeed这两个类可能分别对应AVAudioTimePitchAlgorithmTimeDomain、AVAudioTimePitchAlgorithmVarispeed,所以他们实现原理和底层调用的方法可能是一样的
2、转了一圈又回到原地,才发现自己正在找的,因为之前并没有太大的把握认为原生的AVPlayerItem支持去掉回音的功能,所以当时只是粗略的浏览一下,并没有一个一个去弄清楚他们的用途。
3、项目之前对音频播放的研究并不是很深入,只是停留在对AVPlayer的常规使用和封装,对AVPlayer的使用并没有较全面和深入的研究,对音频的生成、合成、处理的相关只是并不是很了解,只知道慢速播放会有回音,对回音产生的原因并没了解清楚,通过这轮的研究以后,开始明白回音的产生涉及到是对音频以不同速率管理音频音高和缩放音频编辑的处理算法。
网友评论