zoukankan      html  css  js  c++  java
  • iOS AvPlayer AvAudioPlayer音频的后台播放问题

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了。如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,AvPlayer播放的话,要实现完美的后台音频播放,依据app的功能需要,可能需要实现几个关键的功能。

    首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionCategoryPlayback即可。模式意义及其他模式请参考文档。

    1. AVAudioSession *session = [AVAudioSession sharedInstance];  
    2. [session setCategory:AVAudioSessionCategoryPlayback error:nil];  
    3. [session setActive:YES error:nil];  

     

    1。通知OS该app支持background audio。缺 省情况下,当按下home键时,当前正在运行的程序被suspend,状态从active变成in-active,也就是说如果正在播放音频,按下 HOME后就会停止。这里需要让app在按在HOME后,转到后台运行而非被suspend,解决办法是在程序的-info.plist中增加 required background modes这个key项,并选择App plays audio这个value项。



    2。现在按下HOME键后,程序退到后台,但是声音仍在播放。但是如果要实现播放列表的依次播放、循环播放,即放完一首后自动切换到下一首,问题来 了,当App在后台放完一首后,就会停下来。原因是在后台运行时,一旦声音停下来,程序也随之suspend,因此在切换文件加载的间隙,程序就会被 suspend。曾经有山寨的解决办法是专门起一个player的实例连续不停的放同一无声音片断,阻止程序被suspend。这里提供的方法是通过申请 后台taskID达到后台切换播放文件的功能。

    即声明后台task id,并通过beginBackgroundTaskWithExpirationHandler将App设为后台Task,达到持续后台运行的目的。我 们知道一般情况下,按HOME将程序送到后台,可以有5或10秒时间可以进行一些收尾工作,具体时间[[UIApplication sharedApplication] backgroundTimeRemaining]返回值。超时后app会被suspend,现在要做的就是用[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]开始后台任务,可以将后台运行超时时间长时间的延长,具 体延长多少时间还是见返回值,总之对于放段时间音乐应该够了。另一个问题是每个开始的后台任务,都必须用endBackgroundTask来结束。 因此,在每次开始播放后启动新的后台任务,同时结束上一个后台任务:

    首先,要在viewdidload中

    1. [UIApplication sharedApplication] beginReceivingRemoteControlEvents];  

    否则,无法切换到下一首,接下来

    1. UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;  
    2.       
    3. [avPlayer play];  
    4. newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];  
    5. if (newTaskId != UIBackgroundTaskInvalid && oldTaskId != UIBackgroundTaskInvalid) {  
    6.      [[UIApplication sharedApplication] endBackgroundTask: oldTaskId];}   
    7. oldTaskId = newTaskId;  

    当然,还有更方便的办法就是在resignActive时beginBackgroundTaskWithExpirationHandler:并在BecomeActive中endBackgroundTask: 


    3。我们知道,ipod播放程序在后台时,双击HOME键,会有个控制界面,可以对它进行播放控制。


    如果您想让您的app可以像ipod一样在后台也可以方便的通过双击HOME键来控制,就要用到远程控制事件了。

    首先在viewdidload等初始化的地方声明App接收远程控制事件,并在相应地方结束声明

    1. - (void) viewWillAppear:(BOOL)animated  
    2. {  
    3. [super viewWillAppear:animated];  
    4. [UIApplication sharedApplication] beginReceivingRemoteControlEvents];  
    5. [self becomeFirstResponder];  
    6. }  
    7.   
    8. - (void) viewWillDisappear:(BOOL)animated  
    9. {  
    10. [super viewWillDisappear:animated];  
    11. [UIApplication sharedApplication] endReceivingRemoteControlEvents];  
    12. [self resignFirstResponder];  
    13. }  


    定义

    1. - (BOOL)canBecomeFirstResponder  
    2. {  
    3.        return YES;  
    4. }  


    最后定义 remoteControlReceivedWithEvent,处理具体的播放、暂停、前进、后退等具体事件

    1. - (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {      
    2.     if (receivedEvent.type == UIEventTypeRemoteControl) {  
    3.   
    4.         switch (receivedEvent.subtype) {  
    5.   
    6.             case UIEventSubtypeRemoteControlTogglePlayPause:  
    7.                 [self playButtonPressed:playButton];  
    8.                 [self testing];  
    9.                 break;  
    10.   
    11.             case UIEventSubtypeRemoteControlPreviousTrack:  
    12.                 [self rewButtonReleased:(UIButton *)rewButton];  
    13.                 break;  
    14.   
    15.             case UIEventSubtypeRemoteControlNextTrack:  
    16.                 [self ffwButtonReleased:(UIButton *)ffwButton];  
    17.                 break;  
    18.   
    19.             default:  
    20.                 break;  
    21.         }  
    22.     }  
    23. }  
     

    4. 至此,您有播放App已经相当完美了,还有最后一个问题,那就是当用户使用耳机时,问题又来了。系统默认当插入耳机时,正在播放的声音不中断,直接切换到 耳机播放,而当拔出耳机时,播放停止。如果这种行为满足您的要求,那OK,否则您就需要进一步研究耳机检测和声音路由切换的问题。

  • 相关阅读:
    Windows核心编程笔记:同步设备I/O与异步设备I/O 200404
    最顶层窗口
    Windows环境变量
    如何使用Beyond Compare比较两个文件夹的差异
    c++生成缩略图
    MD5加密算法
    c++读写注册表
    通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
    Hive中HSQL中left semi join和INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN区别
    postgreSQL格式化时间的函数详解
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5737738.html
Copyright © 2011-2022 走看看