
[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.