在上面的代码中,有许多逻辑是后面加的,比如更新UI界面,获取歌词等处理,如果要实现简单的播放,则可以不用重写该方法,直接通过playFromURL就可以实现我们的播放功能。
2、更新UI
这里的UI暂不包括歌词的更新,而只是进度条的更新,要更新进度条,比不可少的是定时器,这里我没有选择NSTimer,而是选择了CADisplayLink,至于为什么,我想大家应该都比较了解,可以这么来对比,下面引用一段其他博客的对比:
iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。
NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。
CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的
使用方法
if (!_progressTimer) {
_progressTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgress)];
[_progressTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
更新进度
- (void)updateProgress
{
if (self.glPlayerDelegate && [self.glPlayerDelegate respondsToSelector:@selector(updateProgressWithCurrentPosition:endPosition:)])
{
[self.glPlayerDelegate updateProgressWithCurrentPosition:self.currentTimePlayed endPosition:self.duration];
}
[self showLockScreenCurrentTime:(self.currentTimePlayed.second + self.currentTimePlayed.minute * 60) totalTime:(self.duration.second + self.duration.minute * 60)];
}
在这里有两个属性:currentTimePlayed和duration,分别保存着当前播放时间和总时间,是如下的结构体
typedef struct {
unsigned minute;
unsigned second;
/**
* Playback time in seconds.
*/
float playbackTimeInSeconds;
/**
* Position within the stream, where 0 is the beginning
* and 1.0 is the end.
*/
float position;
} FSStreamPosition;
我们在更新UI的时候,主要可以根据其中的minute和second来,如果播放了90s,那么minute就为1,而second为30,所以我们在计算的时候,应该是这样的(self.currentTimePlayed.second + self.currentTimePlayed.minute * 60)
当然在更新进度条的时候,我们也可以通过position直接来给slider进行赋值,这表示当前播放的比例










