iOS播放器设计
ChenghuiBai Lv3

[TOC]

需求目标

1、基础播放器可随时替代(本地、远程播放、暂停、拖动进度、后台播放)
2、记录上次播放、播放模式(单曲,顺序,随机)等
3、播放单个故事,播放专辑列表
4、网络慢,加载进度条和语音提示
5、播放失败、播放状态变更时自定义日志log上传bugly

考虑点

架构

分层:
基础层:给url就播放,开始使用AVPlayer,后续可能采用ffmpeg
业务层:播放记录、播放模式、专辑列表播放、播放状态回调、根据故事id播放故事

接口尽可能简洁。

设计模式

遵守设计原则:单一原则、迪米特法则、依赖倒置原则、里斯替换原则、接口隔离原则、开放-封闭原则

抽象工厂模式:解决基础播放器快速替换问题

策略模式:实现不同播放模式,资源列表排序算法

记录音频播放信息

数据库建表存取

下载组件

断点下载组件下载音频:

播放日志

与服务端尽可能少的交互

通过优先级设置改变上传时机:
高优先级日志立即上传
低优先级达到一定数量或一定时长才上传
日志记录需要考虑多线程问题,写入时不能有其他操作,且不能同时多个写入
是否持久化

电量考虑

日志:尽量少的日志上传次数,传递数据都是必传字段;本地磁盘写入次数尽可能的少;
模式切换:播放列表之前一次计算好播放顺序,不要在每次播放器才计算。
系统远端控制:锁屏图片在子线程获取和解码

实现

AVFoundation后台播放模式设置

do {
//keep alive audio at background
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
} catch _ { }

do {
try AVAudioSession.sharedInstance().setActive(true)
} catch _ { }

开启远程控制器后,才会后台自动切歌播放(开启线控,还能支持耳机上的线控操作)
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

系统远端事件捕获不到问题,需要重写下面方法
-(BOOL)canBecomeFirstResponder{
return YES;
}

#pragma mark - 接收到远程控制时执行的方法
- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent{

}

锁屏播放信息设置
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSDictionary *songInfo = @{
MPMediaItemPropertyTitle: title,
MPMediaItemPropertyArtist: artist
MPMediaItemPropertyPlaybackDuration : [NSNumber numberWithFloat:length]
};
center.nowPlayingInfo = songInfo;

播放流程

1、根据故事id查看是否有播放记录?
有播放记录,获取播放进度
无播放记录,播放进度为初始值

2、查看该故事音频是否已本地缓存?
有缓存,设置播放进度,播放本地
无缓存,设置播放进度,播放远程

3、开始播放,添加播放记录。

4、播放过程中,定时器定时获取播放进度,设置进度条,同时更播放进度记录;
如果在后台:更新锁屏上的播放信息;否则不刷新锁屏信息(节能)

5、暂停更新播放进度。

6、播放完成更新播放进度。

7、播放状态、网络状态、音频获取状态变换回调,方便打点。

  • Post title:iOS播放器设计
  • Post author:ChenghuiBai
  • Create time:2019-01-06 10:38:10
  • Post link:https://baichenghui.github.io/2019/01/06/iOS播放器设计/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.