我们有一个使用WebRTC启用VoIP功能的应用程序。某些操作要求我们在语音对话期间与其中一个对话参与者播放一些音调(在本地-这不是直接的WebRTC问题)。换句话说,在WebRTC进行对话时,我们在应用程序中向其中一位参与者插入了一些提示音。
我们通过使用AVAudioPlayer并播放声音来做到这一点。 AVAudioSession类别为“ AVAudioSessionCategoryPlayAndRecord”。我们为AVAudioPlayer设置了一个委托。在大多数情况下,我们演奏的音色效果很好。有时,会调用AVAudioPlayer播放方法(成功-prepareToPlay
之后),但是我们什么也没听到,因此调用了- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)completed
委托方法,并将completed设置为YES,所以说成功完成。
这种情况发生时,从-play
方法到- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)completed
回调的经过时间为几百毫秒,而声音成功播放时则为大约1/4秒(大约持续时间为声音)。
我一直在试图找出可能发生的情况。我记录了系统的输出音量,AVAudioSession的类别,代码流向等等,在我们听到提示音和不听到提示音之间没有明显的区别。在所有情况下,该音调都来自相同的源声音文件-音调没有变化,因此我们知道该音调存在并且可以像通常播放的那样可读。
这是我们使用的代码。这是来自一般的声音播放例程,该例程会播放我们所有的蜂鸣声等,无论WebRTC是否也在通话中,因此在某些其他情况下,某些代码也是必需的。
// Attempt to play the new sound file.
NSError *error = nil;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error: &error];
if (nil != error) {
ZZLogInfo(@"AVAudioPlayer failed to create: %@.", error);
}
self.player = player;
[self adjustVolume];
[player setDelegate:self];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
if ([player prepareToPlay]) {
[player play];
} else {
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
}
这是一个医疗服务应用程序,需要确保在某些情况下音量足够大(在这种情况下不是必需的,但是在用于紧急通知时(例如,但在使用AVAudioPlayer播放声音时) ,我们做到了)我们使用了不赞成使用的API来强制音量。这就是[self adjustVolume];
的调用。声音播放完毕后,我们将其重置为之前的状态(代码未显示-与下面相同的基本代码,但将其重新设置。)。 (是的,我们知道它使用了已弃用的API,并且我们正在努力将其替换为其他东西,并与Apple合作处理医疗服务应用的特殊情况)
- (void)adjustVolume
{
MPMusicPlayerController* appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
self.lastAbsoluteVolume = [appMusicPlayer volume];
if (self.lastAbsoluteVolume < MinVolume) {
[appMusicPlayer setVolume:MaxVolume];
}
}
问题是,是什么原因导致ABAudioPlayer无法播放声音,但是使回调返回给委托并成功传递YES。而且为什么这个问题只会在某些时候出现。