簡體   English   中英

在iOS中實現和排除背景音頻

[英]Implementing and Troubleshooting Background Audio in iOS

StackOverflow上有很多關於iOS背景音樂播放的問題。 沒有完全探索所有邊緣情況,這個問題的目的是成為iOS背景音頻問題的最后一個詞

定義和假設

所有代碼,問題和示例均參考

“背景” - 當用戶按下主頁按鈕或電源按鈕時應用程序的狀態(因此設備顯示鎖定屏幕)。 該應用程序還可以使用多任務切換器或iPad上的多任務手勢進入后台。

“audio” - 使用AudioQueue播放的音頻(包括AVAudioPlayer)

先決條件

據我了解,有一個要求讓應用程序在后台播放音頻。

  1. Info.plist UIBackgroundModes設置為audio
  2. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

要求

我的用例是在后台播放相對較長的音頻(音樂)。 可能有數百個曲目,應用程序將按順序播放它們。 可以認為音頻將無限播放。

該應用程序將通過暫停播放來處理中斷。

問題

我的成功喜憂參半:

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

允許音頻在后台播放。 但是我很困惑它是否需要以及它與以下內容的區別:

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

邊緣案例

  1. 中斷。 如果您注冊成為音頻中斷(電話等)的通知,則成為AVAudioPlayer的代表。 例如,如果您在中斷開始時暫停或停止音頻,則在結束時恢復,如果中斷超過10分鍾(后台任務完成的最長時間),您的應用程序將被暫停?

  2. 如果調用Lock或Home,模擬器將停止音頻,同時使用:

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

但是這適用於設備。 這是一個已知的問題?

我有一些GPS背景模式和背景音頻的經驗。 這與你的情況不完全相同(你想播放一個很長的音頻文件,我播放短信)但是我可以告訴你:

  • beginBackgroundTaskWithExpirationHandler這個選擇器在后台調用時有一個目的:避免應用程序返回到暫停狀態,在該狀態下不再可以調用代碼(你被“凍結”)。 因此,只要您調用beginBackgroundTaskWithExpirationHandler並在使用beginBackgroundTaskWithExpirationHandler終止長時間運行的任務beginBackgroundTaskWithExpirationHandler ,就會使用CPU並消耗電量。
    我真的懷疑在后台播放文件應該使用iPhone的電池,就好像它正在運行應用程序一樣,所以我懷疑beginBackgroundTaskWithExpirationHandler確實參與了你的流程。

  • 模擬器:不依賴於模擬器:它沒有完全實現后台模式。 實際上,當您單擊主頁按鈕時,您的應用程序將進入后台,但在此階段,您仍可以在應用程序中執行代碼。 一段時間后,您的應用程序將被暫停(=凍結),您的代碼執行將被暫停以節省電池。 這種暫停狀態永遠不會出現在模擬器上。

  • 中斷。 當有電話呼叫時,你不能暫停/恢復播放。平台負責這個,你可以用你的AVAudioSessionDelegate做出反應。 但是,您可以通過在音頻會話上設置屬性來影響會話與其他音頻聲音交互的方式(例如,請參閱kAudioSessionProperty_OverrideCategoryMixWithOthers )。 因此流程更多:您描述音頻會話應與系統其余部分交互的方式,系統會相應地混合聲音,如果會話中斷,您將收到AVAudioSessionDelegate的通知。

希望這可以幫助。

我使用下面的代碼進行設備控制 -

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

用於注冊監聽遙控器。 完成后刪除它 -

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

讓app 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");
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM