[英]No audio from AVCaptureSession after changing AVAudioSession
我正在制作一個支持視頻播放和錄制的應用。 我總是希望允許背景音頻混合,除了在視頻播放期間(在播放期間,背景音頻應該靜音)。 因此,我在改變播放狀態時使用以下兩種方法。 當我的AVPlayer開始加載時,我調用MuteBackgroundAudio
,當我關閉包含它的視圖控制器時,我調用ResumeBackgroundAudio
。 這按預期工作,音頻在離開播放后成功返回。
問題是,在執行此操作至少一次后,每當我使用AVCaptureSession
錄制任何內容時,都不會錄制任何聲音。 我的會話配置如下:
AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
if (error)
{
NSLog(@"%@", error);
}
if ([self.session canAddInput:audioDeviceInput])
{
[self.session addInput:audioDeviceInput];
}
[self.session setAutomaticallyConfiguresApplicationAudioSession:NO];
// ... videoDeviceInput
請注意,我沒有設置usesApplicationAudioSession
,因此它默認為YES
。
void MuteBackgroundAudio(void)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
if ([[AVAudioSession sharedInstance] isOtherAudioPlaying] && !isMuted)
{
isMuted = YES;
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker
error:&error];
if (error)
{
NSLog(@"DEBUG - Set category error %ld, %@", (long)error.code, error.localizedDescription);
}
NSError *error2 = nil;
[[AVAudioSession sharedInstance] setActive:YES
withOptions:0
error:&error2];
if (error2)
{
NSLog(@"DEBUG - Set active error 2 %ld, %@", (long)error.code, error.localizedDescription);
}
}
});
}
void ResumeBackgroundAudio(void)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
if (isMuted)
{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *deactivationError = nil;
[audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&deactivationError];
if (deactivationError)
{
NSLog(@"DEBUG - Failed at deactivating audio session, retrying...");
ResumeBackgroundAudio();
return;
}
isMuted = NO;
NSLog(@"DEBUG - Audio session deactivated");
NSError *categoryError = nil;
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers
error:&categoryError];
if (categoryError)
{
NSLog(@"DEBUG - Failed at setting category");
return;
}
NSLog(@"DEBUG - Audio session category set to mix with others");
NSError *activationError = nil;
[audioSession setActive:YES error:&activationError];
if (activationError)
{
NSLog(@"DEBUG - Failed at activating audio session");
return;
}
NSLog(@"DEBUG - Audio session activated");
}
});
}
調試
我注意到在調用ResumeBackgroundAudio
之后,audioSession總是需要兩次嘗試才能成功停用。 由於AVAudioSession.h
這個注釋,我的AVPlayer似乎沒有及時解除分配或停止:
請注意,如果會話在運行或暫停I / O(例如音頻隊列,播放器,錄像機,轉換器,遠程I / O等)時設置為非活動狀態,則此方法將在iOS 8上或之后鏈接的應用中引發異常。 。
沒有聲音被記錄的事實讓我相信audioSession
實際上沒有被激活,但是我的日志記錄說它確實(總是在遞歸的第二次迭代中)。
我從這篇文章中得到了使用遞歸來解決這個問題的想法。
澄清一下,導致問題的流程如下:
MuteBackgroundAudio
靜音,播放開始( MuteBackgroundAudio
) ResumeBackgroundAudio
) 我和你描述的問題完全相同,直到最后一個細節( [audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&deactivationError];
第一次失敗,無論如何)
對於我的情況,唯一可接受的方法是停止然后啟動AVCaptureSession。 我不完全確定,但我認為這與Whatsapp處理它的方式完全相同 - 他們的相機與我建議的解決方案完全一樣。
在已經運行的會話中刪除和添加相同的音頻輸入似乎也可以工作,但我的相機凍結很可怕 - 與會話開始/停止相比沒什么。
遞歸解決方案很不錯,但我認為“限制”遞歸調用(添加一個短暫的延遲和某種類型的最大重試計數)是一個好主意,以防由於合法的原因每次都會失敗。 否則你的堆棧將溢出,你的應用程序將崩潰。
如果你或任何人找到了更好的解決方案,我很想知道。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.