簡體   English   中英

iOS應用程序在后台錄制時音頻中斷

[英]Audio interruption when iOS application is recording in background

我的iPad聲音應用程序(iOS 7.1)可以在后台錄制。 只要在后台錄制不中斷,一切都可以。 例如,如果某人有(愚蠢的?)想法在錄音時開始聆聽音樂。

我試圖以不同的方式來處理這種中斷,但沒有成功。 問題是

  - (void)audioRecorderEndInterruption:(AVAudioPlayer *)p withOptions:(NSUInteger)flags

當應用程序在后台發生中斷時,永遠不會觸發它。 然后,我嘗試在另一種解決方案中,實現AVAudioSessionInterruptionNotification和handleInterruption:方法為

- (void) viewDidAppear:(BOOL)animated
{
......
AVAudioSession *session=[AVAudioSession sharedInstance];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleInterruption:)
                                             name:AVAudioSessionInterruptionNotification
                                           object:session];
.......
}
// interruption handling

- (void)handleInterruption:(NSNotification *)notification
{
    try {
        UInt8 theInterruptionType = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue];
        NSLog(@"Session interrupted > --- %s ---\n", theInterruptionType == AVAudioSessionInterruptionTypeBegan ? "Begin Interruption" : "End Interruption");

        .... MANAGE interruption begin    
        interruptionBeganWhileInBackgroundMode = TRUE;

        }            
        if (theInterruptionType == AVAudioSessionInterruptionTypeEnded) {

        .... MANAGE interruption end

        }
    } catch (CAXException e) {
        char buf[256];
        fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
    }
}

在這種情況下,在中斷開始時會觸發handleInterruption:,但在中斷結束時不會觸發(應在將InterruptionType設置為AVAudioSessionInterruptionTypeEnded的情況下觸發)

為了解決這個問題,我決定在中斷開始時設置一個標志( interruptBeganWhileInBackgroundMode ),以使應用程序得知在進入前台時發生了中斷。 這樣我就可以管理中斷的結束了。

它看起來很聰明,但事實並非如此! 這就是為什么

我嘗試了兩種實現。

解決方法1 在中斷開始時,將[記錄器暫停]放入handleInterruption:中,並在設置了中斷標志時在comeingForeground:方法中管理[記錄器記錄]。 在這種情況下,當應用程序返回到前台時,錄制會立即繼續進行, 但不是恢復,而是由錄制器擦除文件並重新開始新的錄制,因此中斷之前錄制的所有內容都會丟失

解決方案2 在handleInterruption中放置[recorder stop]:當中斷開始時,要保存文件,以確保保留記錄的數據。 該記錄已保存, 但是當應用程序進入前台時,它將停頓約十秒鍾,然后用戶才能再次進行交互 ,就好像有一個使UI凍結的進程(保存文件?)一樣。

最后一點:在此應用程序的iPhone版本中,我有完全相同的問題:當應用程序為前台且發生電話時,一切正常。 但是,當我的應用程序處於后台時發生電話呼叫時,我會看到與iPad版本相同的不良行為。

我注意到,iOS7中的Apple 語音備忘錄應用程序可以正確管理這些背景中斷(它停止並保存錄音),盡管它在進入前景時顯示00:00:00文件長度。 iTalk應用程序可以完美地管理它,當到達前台時會自動恢復記錄。

是否有人為后台錄制應用程序的音頻中斷管理找到解決方法? 我在許多開發者網站上找到了很多人在尋找它,但是沒有答案……謝謝!

我本人也一直在經歷同樣的問題。 似乎iOS7 AVAudioRecorder中存在一個如何處理中斷的錯誤。 它不會關閉文件,而是像我認為文檔所述那樣暫停了文件。 我還無法弄清是什么原因使應用程序重新回到前台。 就我而言,我會在10秒鍾后看到AVAudioRecorder完成(成功標志設置為NO)。

我最終使用Audio Queues重寫了錄音機。 我在這里(git@github.com:vecter / Audio-Queue-Services-Example.git)找到了一些示例代碼,這些示例代碼有助於在Objective-C環境中進行設置,Apple SpeakHere演示包含一些代碼來處理中斷通知。

本質上,我是在中斷開始時停止記錄,並為用戶打開一個警報以保存文件。 如果在應用程序處於后台運行時啟動了中斷,則此警報將推遲到通過UIApplicationDidBecomeActiveNotification為止。

還要注意的另一件事是,音頻隊列中似乎有一個小錯誤,有時AudioQueueStart方法將返回-50。 如果添加

AudioSessionInitialize(NULL, NULL,nil,(__bridge  void *)(self));
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                        sizeof(sessionCategory),
                        &sessionCategory
                        );
AudioSessionSetActive(true);

在使用任何AudioQueue方法之前,錯誤都會消失。 這些方法被標記為已棄用,但似乎是必需的。

不知道/認為這將與該主題的原始作者有關,但是這是我的經驗:

由於AVAudioSessionInterruptionNotification的緣故,我到了這里。 .began風味符合預期,但.end風味沒有。 就我而言,這是因為我使用了兩個AVPlayer實例:一個用於播放音樂,另一個用於靜音,而第一個實例則努力開始播放新曲目(否則,如果下一首曲目,iOS將在后台暫停我的應用程序加載速度不夠快)。

事實證明,這不是最聰明的解決方案,並且以某種方式弄亂了通知系統。 放棄第二個AVPlayer(靜音播放其中一個)導致.end被按預期方式觸發。 當然,我找到了通知問題的答案/解決方案,但現在剩下的是舊的... :-)

暫無
暫無

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

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