您的位置:首页 > 其它

AVPlayer 无间隔循环播放

2018-01-14 16:29 2775 查看
AVPlayer 可以实现音频或者视频文件的在线播放和本地播放。最近做了一个单曲循环播放的功能。一开始选择了下面这个方法:

- (void)replaceCurrentItemWithPlayerItem:(nullable AVPlayerItem *)item;


但尝试后发现两首音乐无法完美衔接,中间会有一个短暂的停留,这个不太符合我们的需求。尝试在播放完后,重新创建播放器,继续播放这首音乐。但还是会有停留。

随后采用了一个折中的方案,在音乐播放即将完成的时候,重新创建一个新的播放器,开始播放。第一个播放器播放完成后就销毁掉。当第二个播放器即将播放完成的时候,在初始化第一个播放器,记录开始播放,以此循环。这样,用一段重合的音乐代替了一段暂停。

我们需要监听音乐播放:

id _timeObserve;
id _timeLoopObserve;


监听第一个播放器的播放情况:

@weakify(self)
_timeObserve = [self.musicPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
@strongify(self)
float current = CMTimeGetSeconds(time);
float total = CMTimeGetSeconds(self.currentPlayerItem.duration);
//即将播放完成后,继续播放该音乐
if (current >= total-5 && current < total && !self.musicPlayerSwitch) {
self.musicPlayer.volume = 0.8;
[self resetMusicLoopPlayer];
[self initMusicLoopPlayer];
self.musicLoopPlayer.volume = 0.8;
[self.musicLoopPlayer play];
self.musicPlayerSwitch = YES;
}
}else{
if (current > 6 && current < total-6) {
self.musicPlayerSwitch = NO;
[self resetMusicPlayer];
self.musicLoopPlayer.volume = 1;
}
}
}];


监听第二个播放器的播放情况:

@weakify(self)
_timeLoopObserve = [self.musicLoopPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
@strongify(self)
float current = CMTimeGetSeconds(time);
float total = CMTimeGetSeconds(self.currentPlayerItem.duration);
//即将播放完成后,继续播放该音乐
if (current >= total-5 && current < total && !self.musicPlayerSwitch) {
self.musicPlayer.volume = 0.8;
[self resetMusicPlayer];
[self initMusicPlayer];
self.musicPlayer.volume = 0.8;
[self.musicPlayer play];
self.musicPlayerSwitch = YES;
}
}else{
if (current > 6 && current < total-6) {
self.musicPlayerSwitch = NO;
[self resetMusicLoopPlayer];
self.musicPlayer.volume = 1;
}
}
}];


如上代码,在两段音乐重叠的时候,为了防止声音突然变大,通过设置
volume
降低声音。在其中一个播放器销毁的时候再恢复原声。

另外,销毁播放器的时候注意要把观察者移除:

- (void)resetMusicPlayer{
if (self.musicPlayer) {
[self.musicPlayer removeTimeObserver:_timeObserve];
_timeObserve = nil;
}
self.musicPlayer  = nil;
}


- (void)resetMusicLoopPlayer{
if (self.musicLoopPlayer) {
[self.musicLoopPlayer removeTimeObserver:_timeLoopObserve];
_timeLoopObserve = nil;
}
self.musicLoopPlayer  = nil;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AVPlayer 单曲循环