PhoneGap / Cordova iOS播放声音禁用麦克风

时间:2015-07-17 16:14:33

标签: ios cordova audio audio-recording cordova-plugins

我目前正在开发PhoneGap应用程序,按下按钮后,应该播放8秒长的声音片段,同时通过Cordova插件将来自麦克风的麦克风声音传输到Wowza服务器iOS库VideoCore

我的问题是(在iOS专用)当声音片段停止播放时,麦克风 - 出于某种原因 - 也会停止录制声音。但是,流仍处于活动状态,导致服务器端的声音片段包含8秒的麦克风输入,然后完全静音。

注释播放声音的线会导致麦克风录制声音没有问题,但我们需要能够播放声音。

定义媒体变量:

_alarmSound = new Media("Audio/alarm.mp3")

播放声音并启动流:

if(_streamAudio){
    startAudioStream(_alarmId); 
}
if(localStorage.getItem("alarmSound") == "true"){
    _alarmSound.play();
}

在我看来,当PhoneGap停止播放声音片段时会发生某种内部资源使用冲突,但我不知道我能做些什么来修复它。

2 个答案:

答案 0 :(得分:2)

我在iOS上遇到了同样的问题,我通过做两件事解决了这个问题:

AVAudioSession类别

在iOS中,应用应使用单例AVAudioSession指定对声音资源的要求。使用Cordova时,有一个插件可以让您执行此操作:https://github.com/eworx/av-audio-session-adapter

例如,当你想播放声音时,你将类别设置为播放:

audioSession.setCategoryWithOptions(
        AVAudioSessionAdapter.Categories.PLAYBACK,
        AVAudioSessionAdapter.CategoryOptions.MIX_WITH_OTHERS,
        successCallback, 
        errorCallback
    );

如果您想使用麦克风录制声音并仍能播放声音,请将类别设置为PLAY_AND_RECORD:

audioSession.setCategoryWithOptions(
        AVAudioSessionAdapter.Categories.PLAY_AND_RECORD,
        AVAudioSessionAdapter.CategoryOptions.MIX_WITH_OTHERS,
        successCallback, 
        errorCallback
    );

cordova-plugin-media杀死AVAudioSession

您用于播放的媒体插件会以一种无法与其他声音插件和Web Audio API结合的方式处理录制和播放。每次完成播放或录制时,它都会停用AVAudioSession。由于您的应用只有一个此类会话,因此可以有效地停用应用中的所有声音。

为此注册了一个错误:https://issues.apache.org/jira/browse/CB-11026

由于该bug仍然没有修复,而您仍想使用Media插件,解决此问题的唯一方法是下载插件代码并注释掉/删除AVAudioSession停用的行:

[self.avSession setActive:NO error:nil];

答案 1 :(得分:1)

我发现花了一些心血来解决与该主题相关的现有问题,因此我希望这对需要更明确解决方案的人有所帮助。


Cordova Media plugin的5.0.2版本开始,此问题仍然存在。如果要使用此插件,我发现的最直接的解决方案是派生插件存储库,并对src/ios/CDVSound.m进行以下更改。经过数小时的研究,我无法在不修改插件源的情况下找到可行的解决方案,也找不到合适的替代插件。

强制会话类别

爱丁的答案中提到的插件作者解释了AVAudioSession类别on a similar question的问题。由于无论如何都需要对CDVSound.m进行更改,因此我发现以下更改比使eworx/av-audio-session-adapter插件更容易工作。

找到以下代码行:

NSString* sessionCategory = bPlayAudioWhenScreenIsLocked ? AVAudioSessionCategoryPlayback : AVAudioSessionCategorySoloAmbient;
[self.avSession setCategory:sessionCategory error:&err];

替换为:

[self.avSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];

防止会话停用

此外,爱丁答案中建议的更改对于防止停用其他音频会话是必要的,但是,并非所有实例都需要删除。

从函数audioRecorderDidFinishRecording()audioPlayerDidFinishPlayingitemDidFinishPlaying()中删除以下行和周围的条件语句:

[self.avSession setActive:NO error:nil];

该代码的其他实例用于错误处理和资源释放,根据我的经验,不需要,也不应该将其删除。

更新:播放量

应用这些更改后,我们在播放过程中(录音处于活动状态)遇到了音量低的问题。从上方的各个setCategory行之后添加以下行,可以全音量播放。这些更改将在the answer from which this fix was sourced中进行解释。

[self.avSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];

[weakSelf.avSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];