iOS音频的后台播放总结(后台网络请求歌曲,Remote控制,锁屏封面,各种打断)...
iOS音频的后台播放总结(后台网络请求歌曲,Remote控制,锁屏封面,各种打断)
目录(?)[+]
在没有网络的情况下,音频的后台播放比较简单,google一下可以搜到很多资料,但是如果每次歌曲的请求都是通过网络,就不成了,有时可以也扛不了几首,这里总结下实现方法,可以实现像电台一样的功能,后台播放,网络请求歌曲,Remote控制,锁屏有封面,电话和听歌打断处理等。
初始化AudioSession和基本配置
音频播放器采用的AVPlayer ,自己进行了功能封装,暂且不谈,在程序启动的时候需要配置AudioSession,AudioSession负责应用音频的设置,比如支不支持后台,打断等等,这一步很重要,比如在viewdidload里初始化AVplayer以后要调用下面的函数:
[objc] view plaincopy
- -(void)setAudioSession{
- //AudioSessionInitialize用于控制打断 ,后面会说
- AudioSessionInitialize (
- NULL, // ‘NULL’ to use the default (main) run loop
- NULL, // ‘NULL’ to use the default run loop mode
- ASAudioSessionInterruptionListener, // a reference to your interruption callback
- NULL // data to pass to your interruption listener callback
- );
- //这种方式后台,可以连续播放非网络请求歌曲,遇到网络请求歌曲就废,需要后台申请task
- AVAudioSession *session = [AVAudioSession sharedInstance];
- NSError *setCategoryError = nil;
- BOOL success = [session setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
- if (!success)
- {
- /* handle the error condition */
- return;
- }
- NSError *activationError = nil;
- success = [session setActive:YES error:&activationError];
- if (!success)
- {
- /* handle the error condition */
- return;
- }
- }
AudioSessionInitialize用于处理中断处理,AVAudioSession主要调用setCategory和setActive方法来进行设置,AVAudioSessionCategoryPlayback一般用于支持后台播放,在官方文档可以看到其他的类型,每个分别适用于不同的场合:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryAmbient">
<blockquote>AVAudioSessionCategoryAmbient</blockquote>
</a>;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategorySoloAmbient">
<blockquote>AVAudioSessionCategorySoloAmbient</blockquote>
</a>;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryPlayback">
<blockquote>AVAudioSessionCategoryPlayback</blockquote>
</a>;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryRecord">
<blockquote>AVAudioSessionCategoryRecord</blockquote>
</a>;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryPlayAndRecord">
<blockquote>AVAudioSessionCategoryPlayAndRecord</blockquote>
</a>;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryAudioProcessing">
<blockquote>AVAudioSessionCategoryAudioProcessing</blockquote>
</a>;
NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryMultiRoute">
<blockquote>AVAudioSessionCategoryMultiRoute</blockquote>
</a>;
|
1
|
除了代码的初始化,很重要的一步是对info-plist的设置,让应用支持音频的后台播放
库的引入包括:
AudioToolBox.framework
MediaPlayer.framework
CoreMedia.framework
AVFoundation.framework
后台播放
正常情况下,如果配置了AVAudioSessionCategoryPlayback这个方法并修改了info-plist文件,应用就已经支持后台音频播放了,但是如果每一首歌曲都不存在本地,在网络的话就不行了,需要申请后台任务来进行处理,首先修改:
[objc] view plaincopy
- - (void)applicationDidEnterBackground:(UIApplication *)application {
- [application beginReceivingRemoteControlEvents];
- }
然后在播放器的播放函数里添加:
[objc] view plaincopy
- -(void)justPlay{
- UIBackgroundTaskIdentifier bgTask = 0;
- if([UIApplication sharedApplication].applicationState== UIApplicationStateBackground) {
- NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx后台播放”);
- [thePlayer play];
- UIApplication*app = [UIApplication sharedApplication];
- UIBackgroundTaskIdentifier newTask = [app beginBackgroundTaskWithExpirationHandler:nil];
- if(bgTask!= UIBackgroundTaskInvalid) {
- [app endBackgroundTask: bgTask];
- }
- bgTask = newTask;
- }
- else {
- NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx前台播放”);
- [thePlayer play];
- }
- }
这样播放就可以进行前台或者后台的判断,支持网络后台播放了,一首一首连续播放。
Remote控制
在播放视图的ViewController里加上这两个函数:
[objc] view plaincopy
- - (void)viewDidAppear:(BOOL)animated {
- NSLog(@”viewDidAppear!!!”);
- [super viewDidAppear:animated];
- //Once the view has loaded then we can register to begin recieving controls and we can become the first responder
- [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
- [self becomeFirstResponder];
- }
- - (void)viewWillDisappear:(BOOL)animated {
- NSLog(@”viewWillDisappear!!!”);
- [super viewWillDisappear:animated];
- //End recieving events
- [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
- [self resignFirstResponder];
- }
当然也可以同理放到delegate.m里面的进入后台和回到前台的函数中,否则的话,上面的代码只是允许当前视图的情况下进入后台可以Remote控制
然后添加下面的代码:
[objc] view plaincopy
- -(void)remoteControlReceivedWithEvent:(UIEvent *)event{
- //if it is a remote control event handle it correctly
- if (event.type == UIEventTypeRemoteControl) {
- if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
- [self playerTap];
- } else if (event.subtype == UIEventSubtypeRemoteControlNextTrack){
- [self nextSongAuto];
- [self configNowPlayingInfoCenter];
- }
- }
- }
- //Make sure we can recieve remote control events
- - (BOOL)canBecomeFirstResponder {
- return YES;
- }
锁屏封面
一般在每次切换歌曲或者更新信息的时候要调用这个方法
[objc] view plaincopy
- - (void)configNowPlayingInfoCenter {
- NSDictionary *albumDic=[currentParserSongArray objectAtIndex:songIndex];
- if (NSClassFromString(@”MPNowPlayingInfoCenter”)) {
- NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
- [dict setObject:[albumDic objectForKey:@"name"] forKey:MPMediaItemPropertyTitle];
- [dict setObject:[albumDic objectForKey:@"singer"] forKey:MPMediaItemPropertyArtist];
- [dict setObject:[albumDic objectForKey:@"album"] forKey:MPMediaItemPropertyAlbumTitle];
- MPMediaItemArtwork * mArt = [[MPMediaItemArtwork alloc] initWithImage:cdCoverImgView.image];
- [dict setObject:mArt forKey:MPMediaItemPropertyArtwork];
- [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;
- [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
- }
- }
打断处理
试用了官方文档上的各种代理方法,打断通知,都没用,后来用C函数处理可以控制打断,首先AudioToolBox.framework是需要引入的
在设定session的时候调用了ASAudioSessionInterruptionListener这个函数 ,就是处理打断的,在所需加入的类的实现
@implementation前面加入这个静态方法
[objc] view plaincopy
- static void ASAudioSessionInterruptionListener(voidvoid *inClientData, UInt32 inInterruptionState)
- {
- [[ToolManager defaultManager] handleInterruption:inInterruptionState];
- }
每次打断结束或者开始都会调用这个方法 ,inInterruptionState来判断是开始还是结束,因为是C函数,不可以直接调用类中[self xxx]方法,通知也没用 ,故写了个单例类,接收这个参数,然后进行判断
[objc] view plaincopy
- - (void)handleInterruptionChangeToState:(NSNotification *)notification
- {
- AudioQueuePropertyID inInterruptionState=[[notification object] longValue];
- if (inInterruptionState == kAudioSessionBeginInterruption)
- {
- NSLog(@”begin interruption——->”);
- }
- else if (inInterruptionState == kAudioSessionEndInterruption)
- {
- NSLog(@”end interruption——->”);
- }
- }
转载于:https://www.cnblogs.com/ios4app/p/6947622.html
iOS音频的后台播放总结(后台网络请求歌曲,Remote控制,锁屏封面,各种打断)...相关推荐
- iOS 音频录制、播放(本地、网络)
文章目录一.录音机(AVAudioRecorder)1.简介2.如何使用3.具体实现(开始.暂停.停止.播放 四个功能)4.附件实现demo二.播放音频1.播放本地音频文件(AVAudioPlayer ...
- iOS音乐后台播放、锁屏封面及播放控制
在默认情况下App被切换到后台时,音乐的就停止播放了,但音乐类App的一般都会需要在后台继续播放,这样用户就可以一边听音乐,一边操作其他的App.对于这种情况我们可以对App做一些简单的配置,实现后台 ...
- Android okHttp网络请求之缓存控制Cache-Control
前言: 前面的学习基本上已经可以完成开发需求了,但是在项目中有时会遇到对请求做个缓存,当没网络的时候优先加载本地缓存,基于这个需求我们来学习一直okHttp的Cache-Control. okHttp ...
- android 后台播放,实现后台播放 | Android 开发者 | Android Developers
在 TV 设备上观看内容的用户可能会随时决定切换到 TV 启动器.如果用户在使用 TV 播放应用时切换到启动器,默认情况下,此应用会暂停.由于用户没有明确要求暂停播放,因此这种默认行为可能会显得非常突 ...
- android h5控制锁屏,WebView播放H5课件时,锁屏解锁后,页面重新绘制的问题
难题描述:H5页面播放 ,锁屏,解锁后,重新加载了页面,三星不会出现(onpause onstop ,onresume),但在小米.魅族会调用 onpause onstop ondestroy,onr ...
- iOS音频开发(录音+播放+剪辑+合成+压缩转码)
录音: //音频会话 AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *sessionError; /* AVAu ...
- iOS音频的后台播放 锁屏
初始化AudioSession和基本配置 音频播放器采用的AVPlayer ,在程序启动的时候需要配置AudioSession,AudioSession负责应用音频的设置,比如支不支持后台,打断等等, ...
- iOS音频的后台播放总结
在没有网络的情况下,音频的后台播放比较简单,google一下可以搜到很多资料,但是如果每次歌曲的请求都是通过网络,就不成了,有时可以也扛不了几首,这里总结下实现方法,可以实现像电台一样的功能,后台播放 ...
- iOS - 音频后台播放设置及锁屏界面的显示与控制
音频后台播放设置 1.先在项目 的Capabilities中进行设置,开启后台模式 2.激活音频会话 其它地方也可以,只要保证能执行到以下代码块的内容即可,这里我选择在AppDelegate.m里设置 ...
最新文章
- 死锁产生条件-不剥夺条件
- [Azure] Azure 中国服务使用注意事项及兼容版存储访问工具
- [POJ3253]Fence Repair
- 【数据挖掘】决策树 分类 ( 抽取分类规则 | 过拟合 | 剪枝 | 先剪 | 后剪 | 连续数值离散化 | 最优化分点 | 增益率选择划分属性 )
- VCL界面控件DevExpress VCL Controls发布v18.2.5|附下载
- php crc16校验算法,PHP串口通信中计算crc16校验码
- Redis集群理论知识
- c语言程序设计王新萍课后答案,C语言程序设计教程
- vue中el-row使用
- Q78:规则网格(Regular Grids)——Ray Tracing中的一种加速技术
- Uber如何使用Mesos的?答曰:和Cassandra一起用
- NIUDAY 七牛美图 AI 共享日 | 大咖云集 邀您共同探索各场景下的 AI 应用与落地...
- OUTEROS常用命令
- IOS 中的Notification 学习
- struts2入门第一天----------一个简单例
- verilog实现四位全加器(基于一位全加器)
- c语言谷歌坐标转百度坐标,百度经纬度和google经纬度转换测试
- darknet测试voc数据集精度
- idea安装findBugs 报idea运行项目报错Cannot run program
- 写给新的一年(2015)
热门文章
- .NET设计模式(3): 抽象工厂模式
- 广西河池计算机考试考什么,2021上半年广西壮族自治区河池市计算机等级考试时间...
- 解决JupyterLab中tqdm_notebook进度条不显示问题
- 【渗透测试】cookie注入笔记
- 【例题+习题】【数值计算方法复习】【湘潭大学】(三)
- 对比关系生成模型(Comparative Relation Generative Model)
- 非正交坐标系-模态正交的物理及几何意义
- Apache HttpClient 4 3开发指南
- VueJS实现用户管理系统
- SpringBoot执行流程