我目前正在开发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停止播放声音片段时会发生某种内部资源使用冲突,但我不知道我能做些什么来修复它。
答案 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()
,audioPlayerDidFinishPlaying
和itemDidFinishPlaying()
中删除以下行和周围的条件语句:
[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];