注:本文仅涉及我在本次开发中最初级的开发心得,还有很多不足和不完善,希望共同交流。
AVPlayer和AVAudioPlayer属于IOS系统中提供的高层次的多媒体模块。其内部可以实现多媒体文件(本地与网络)从读取、解析、PCM调制、音频转化到播放的一系列步骤。并且同时,该接口又将界面剥离出来,仅实现音频的播放,是继承自NSObject的。所以,对于播放器的样式具有高度的可定制性、并且能够满足一般的播放要求。
如果需要开发专业的音频播放器,涉及到PCM解析、音效混合等等更为专业的需求时,则需要自己开发IOS系统库中偏中底层的接口,如Audio ConVerter Services等。
我将AVPlayer的封装方案设计为了3层:播放器、控制管理器、UI界面。具体结构如下图:
由于项目中,需要像“得到”类似的播放形式,因此对Manager、Player部分做了剥离,使之与UI部分分开。而针对播放器状态的切换、获取、以及播放进程等事件的获取,则选用NSNotification、Delegate来实现。这里有一个概念要明确的是,Player是一个音频播放的工具,所以我们可以在全局就生成一个Player就够了,这样可以满足我们在不同的ViewController获取到唯一的播放器对象。因此,在生成AVPlayer、Manager的类中,使用了单例模式进行设计。
下面是针对AVPlayer的功能介绍和实现:
AVPlayer所加载的是AVPlayerItem对象。多媒体数据的路径等均是加载在AVPlayerItem中,再由AVPlayer加载改Item对象完成的。这里需要注意的是:加载网络链接和本地路径下的文件,使用的方法是不同的。两者不能用混,否则加载是无效的。
设置好的Item对象就可以加载AVplayer了。
上边的代码:[_playerreplaceCurrentItemWithPlayerItem:item];是AVplayer切换Item对象的函数,可以用它来切换你的音频源。
接下来为Player添加观察者,来反馈播放器的初始化状态是否成功。
这里它的状态会返回播放器的初始化是否完成。可以根据需求自行添加处理逻辑
接下来,为AVPlayer添加一个获取它一系列播放参数的功能方法,用以获取它的播放总时长、当前播放进度等。这里需要注意一点的是,Player.currentItem对象在加载有些对象的时候,会产生错误的currentTime和timescale,而这两个参数是计算进度的关键参数。具体错误返回可能的表现为,数字为0、得到非数字对象。那如果不做判断处理,后边进行数学运算时,势必会引起Crash,因此,在获得对象使用之前最好还是有判断,以增强代码的健壮性。具体代码如下图:
最下边的两种参数传递的方法,就是将Player层的数据传递给Manager层或UI层做逻辑处理、UI更新的,具体使用因人而异。
基本的功能就是这四点,就可以实现基本的播放和切换操作了。具体的Manager、UI层的逻辑,可以根据需求自行设计。