Dan*_*son 4 objective-c avfoundation ios 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
Run Code Online (Sandbox Code Playgroud)
请注意,我尚未设置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");
}
});
}
Run Code Online (Sandbox Code Playgroud)
调试
我注意到 audioSession 在调用ResumeBackgroundAudio. 由于以下评论,我的 AVPlayer 似乎没有及时解除分配或停止AVAudioSession.h:
请注意,如果会话在运行或暂停 I/O(例如音频队列、播放器、录音机、转换器、远程 I/O 等)时设置为非活动状态,则此方法将在 iOS 8 上或之后链接的应用程序中引发异常。 .
没有声音被记录的事实让我相信audioSession实际上并没有被激活,但我的日志记录表明它确实被激活(总是在递归的第二次迭代中)。
我从这篇文章中得到了使用递归来解决这个问题的想法。
澄清一下,导致问题的流程如下:
MuteBackgroundAudio)ResumeBackgroundAudio)我遇到了与您所描述的完全相同的问题,直到最后一个细节([audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&deactivationError];无论如何第一次都失败了)
就我而言,唯一可接受的方法是停止然后启动 AVCaptureSession。我不完全确定,但我认为这与 Whatsapp 处理它的方式完全相同 - 他们的相机与我建议的解决方案完全一样。
在已经运行的会话上删除和添加相同的音频输入似乎也有效,但我的相机卡住了很糟糕 - 与会话开始/停止相比没什么。
递归解决方案很好,但我认为“限制”递归调用(添加短延迟和某种最大重试次数)是一个好主意,以防由于合法原因设置每次都失败。否则您的堆栈将溢出,您的应用程序将崩溃。
如果您或任何人找到了更好的解决方案,我很想知道。
| 归档时间: |
|
| 查看次数: |
967 次 |
| 最近记录: |