在 iOS 中实现背景音频并对其进行故障排除

Posted

技术标签:

【中文标题】在 iOS 中实现背景音频并对其进行故障排除【英文标题】:Implementing and Troubleshooting Background Audio in iOS 【发布时间】:2012-08-15 10:59:55 【问题描述】:

*** 上有很多关于 ios 中背景音乐播放的问题。没有人完全探索所有边缘情况,目的是 这个问题将是背景音频问题中的最后一句话 iOS

定义和假设

所有代码、问题和示例参考ios5。

“背景” — 当用户按下主页按钮或电源按钮时应用程序所处的状态(因此设备会显示锁定屏幕)。也可以使用多任务切换器或 iPad 上的多任务手势将该应用置于后台。

"audio" — 使用 AudioQueue(包括 AVAudioPlayer)播放的音频

先决条件

据我了解,让应用在后台播放音频有 2 个要求。

    Info.plist 中将UIBackgroundModes 设置为audio [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

要求

我的用例是在后台播放相对较长的音频(音乐)。可能有数百首曲目,应用程序将按顺序播放它们。可以认为音频将无限期地播放。

应用程序将通过暂停播放来处理中断。

问题

我的成功参差不齐:

[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:...];

允许在后台播放音频。但我对它是否需要以及它与以下内容有何不同感到困惑:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

边缘案例

    中断。如果您注册以接收音频中断(电话等)的通知,请成为AVAudioPlayer 的代表。例如,如果您在中断开始时暂停或停止音频并在中断结束时恢复音频,如果中断超过 10 分钟(后台任务允许完成的最长时间),您的应用是否会暂停?

    如果调用 Lock 或 Home,模拟器将停止音频,同时使用:

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    

但是,这适用于设备。这是一个已知问题吗?

【问题讨论】:

您想在后台播放短音频(例如少于 10 秒)还是长音频? 你想在后台播放音乐并处理中断吗?? @yonel 我添加了要求部分来回答您的问题。 @Sandy 是的,需要处理中断。我添加了一个需求部分。 我已经处理过了,双击主页按钮,滚动视图有播放和暂停按钮。我也处理这个,屏幕锁定播放暂停处理。请告诉我是否可以提供帮助你。 【参考方案1】:

我在 GPS 背景模式和背景音频方面有一些经验。这和你的情况不完全一样(你想播放一个长音频文件,我播放短消息),但我可以告诉你:

beginBackgroundTaskWithExpirationHandler 这个选择器在后台被调用时有一个目的:避免应用程序返回到暂停状态,在这种状态下不能再调用任何代码(你被“冻结”了)。因此,只要您调用 beginBackgroundTaskWithExpirationHandler 并且在使用 beginBackgroundTaskWithExpirationHandler 终止长时间运行的任务之前,您就会使用 CPU 并消耗电池。 我真的怀疑在后台播放文件是否应该像运行应用程序一样使用 iPhone 的电池,所以我怀疑 beginBackgroundTaskWithExpirationHandler 是否真的参与了您的流程。

模拟器:不要依赖模拟器:它没有完全实现后台模式。实际上,当您单击主页按钮时,您的应用程序会进入后台,但是在此阶段,您仍然可以在应用程序中执行代码。一段时间后,您的应用程序将暂停(=冻结),并且您的代码执行将暂停以节省电池。 模拟器上永远不会出现这种挂起状态。

中断。来电时暂停/恢复播放不取决于您。平台负责此操作,您可以通过 AVAudioSessionDelegate 对此做出反应。但是,您可以通过在音频会话上设置属性来影响会话与其他音频声音交互的方式(例如,参见 kAudioSessionProperty_OverrideCategoryMixWithOthers)。 所以流程更多:您描述您的音频会话应与系统其余部分交互的方式,系统将相应地混合声音,如果您的会话被中断,您将收到 AVAudioSessionDelegate 通知。

希望这会有所帮助。

【讨论】:

【参考方案2】:

我已将以下代码用于设备控制 -

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

用于注册监听遥控器。 完成后将其删除 -

[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];

使应用程序canBecomeFirstResponder-

- (BOOL)canBecomeFirstResponder 
    return YES;

使用委托方法来处理 iPhone 控制,例如双击主页按钮时播放和暂停

- (void)remoteControlReceivedWithEvent:(UIEvent *)event 
    //if it is a remote control event handle it correctly
    if (event.type == UIEventTypeRemoteControl) 
        if (event.subtype == UIEventSubtypeRemoteControlPlay) 
           [audioPlayer play];
            NSLog(@"play");
         else if (event.subtype == UIEventSubtypeRemoteControlPause) 
           [audioPlayer stop];
             NSLog(@"pause");
         else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) 
            NSLog(@"toggle");
        
    

【讨论】:

以上是关于在 iOS 中实现背景音频并对其进行故障排除的主要内容,如果未能解决你的问题,请参考以下文章

同时播放两个 AVPlayer 音频文件时出现音频故障

如何排除React Router的故障

如何在 Django 中进行故障排除?

一步一步:如何进行 Xdebug 故障排除连接到客户端 IDE

Linux服务器的故障排除方法

Ingress Nginx 故障排除