我有一个使用MPAudioPlayerController访问iPod音乐库的应用程序,以及一个AVAudioPlayer,用于在音乐之上叠加音频。我使用this documentation作为指南。具体做法是:
最后,您可以增强类别,以便在播放音频时自动降低其他音频的音量。例如,这可以用在锻炼应用中。当您的应用程序想要覆盖语音消息时,假设用户正在练习iPod - 例如,“您已经划了10分钟。”为了确保应用程序中的消息可以理解,请将kAudioSessionProperty_OtherMixableAudioShouldDuck属性应用于音频会话。当发生躲避时,设备上的所有其他音频 - 除了电话音频 - 音量降低。
但我没有看到这种行为。实际上,我所看到的(或听到的)是,如果我将kAudioSessionProperty_OtherMixableAudioShouldDuck设置为true设置AudioSession,则MPAudioPlayerController初始卷会减少,如果我然后在MPAudioPlayerController上调用pause(然后再次播放)音量级别增加到“正常”水平。播放AVAudioPlayer对音频级别没有任何影响...
所以我设置了一个简单的测试用例来重现这个。
在ViewController标题中:
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
@interface MusicPlayerVolumeTestViewController : UIViewController <AVAudioPlayerDelegate>
{
UIButton *musicButton;
UIButton *soundButton;
AVAudioPlayer *audioPlayer;
MPMusicPlayerController *musicPlayerController;
}
@property (nonatomic, retain) IBOutlet UIButton *musicButton;
@property (nonatomic, retain) IBOutlet UIButton *soundButton;
@property (nonatomic, retain) MPMusicPlayerController *musicPlayerController;
- (IBAction)musicAction;
- (IBAction)soundAction;
@end
并在实施中:
- (void)viewDidLoad
{
[super viewDidLoad];
//Setup our Audio Session
OSStatus status = AudioSessionInitialize(NULL, NULL, NULL, NULL);
//We want our audio to play if the screen is locked or the mute switch is on
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
status = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
//We want our audio to mix with other app's audio
UInt32 shouldMix = true;
status = AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (shouldMix), &shouldMix);
//Enable "ducking" of the iPod volume level while our sounds are playing
UInt32 shouldDuck = true;
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(shouldDuck), &shouldDuck);
//Activate our audio session
AudioSessionSetActive(YES);
//Setup the Music Player to access the iPod music library
self.musicPlayerController = [MPMusicPlayerController applicationMusicPlayer];
[self.musicPlayerController setShuffleMode: MPMusicShuffleModeSongs];
[self.musicPlayerController setRepeatMode: MPMusicRepeatModeNone];
[self.musicPlayerController setQueueWithQuery:[MPMediaQuery songsQuery]];
//Setup a AVAudioPlayer sound to overlay against the Music Player audio
NSURL *soundURL = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"mp3"]];
NSError *error = nil;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error: &error];
if (!audioPlayer)
{
NSLog(@"Could not create audio effect player: %@", [error localizedDescription]);
}
[audioPlayer prepareToPlay];
}
- (IBAction)musicAction
{
if (self.musicPlayerController.playbackState == MPMusicPlaybackStatePlaying)
{
[self.musicPlayerController pause];
}
else if (self.musicPlayerController.playbackState == MPMusicPlaybackStateStopped
|| self.musicPlayerController.playbackState == MPMusicPlaybackStatePaused)
{
[self.musicPlayerController play];
}
}
- (IBAction)soundAction
{
if (audioPlayer.playing)
{
[audioPlayer pause];
}
else
{
[audioPlayer play];
}
}
我已经连接了几个UIButtons。一个用于musicAction(用于播放/暂停MPMusicPlayerController),另一个用于soundAction(用于播放/暂停AVAudioPlayer)。
如上所述,如果我点击musicAction按钮,音乐会播放,但音量会降低,如果我点击soundAction按钮,则会播放叠加,但不会影响MPMusicPlayerController的音量。而且,更像bug的是,当我暂停然后播放MPMusicPlayerController时,音乐音量会增加到我没有设置AudioSession时的音量。
我很想知道是否有其他人有过这种经历,如果有的话,如果你找到了解决方法(或者可以告诉我,我做错了什么)。否则,我想我要去雷达了。
非常感谢,
列维
答案 0 :(得分:9)
当我遇到类似的问题并且难以让它始终如一地工作时,我使用了这篇文章。它会工作一段时间,然后只是卡住“躲避”。我花了很多时间研究和调试这个,最后只是打电话给Apple。他们告诉我要查看面包屑示例代码。我遵循了这个例子,一切正常。
这是Apple的示例代码:
http://developer.apple.com/library/ios/#samplecode/Breadcrumb/Introduction/Intro.html
Apple的支持/开发人员还说要观察他们设置会话属性的方式和时间顺序。这显然是诀窍。在这里和其他地方阅读了很多帖子后,我的设置相互冲突。从头开始并遵循面包屑的例子使其成功。我从那以后就没有问题了。
我在这里发布了相同的答案:
对我而言,这个答案是临界商业秘密,因为它很难开始工作并且市场上有应用程序。对我来说,看到一个工作的例子,这几乎就是声音的躲避和脱落,值得用金重量。
另外,我向Apple提到这是一个已知问题,他们不同意。他们在这里没有发现任何问题。果然,如果你遵循面包屑的例子,它可以解决任何奇怪的会话停用和被动等等。
答案 1 :(得分:3)
躲避并不会以任何方式与您的播放声音自动相关。当你打开闪避时,背景声响起。当您关闭闪避并停用音频会话时,背景声音将恢复到原始级别。
所以不要开启viewDidLoad
。在你真正要播放声音之前不要打开它。这会导致背景声音消失。当您的声音播放完毕后,请关闭后退并将您的音频会话切换为非激活状态并再次激活。这会导致背景声音消失:
UInt32 duck = 0;
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck,
sizeof(duck), &duck);
AudioSessionSetActive(false);
AudioSessionSetActive(true);
答案 2 :(得分:2)
文档不清楚预期的回避预期行为是什么,但我发现如果你设置你的音频会话以避免闪避,当你激活音频会话时,它会躲避,并且当你停用它时,它会松开。因此,您必须继续激活和停用音频会话,以便为您的声音提示播放音乐。
我发现的一个错误是,如果您在audioPlayerDidFinishPlaying:successfully:
的{{1}}方法内停用音频会话,则不会删除闪避,并且音量保持在同一级别。我已经在这上面提交了一个雷达,但是如果其他文件类似,它也不会受到伤害。事实上,它可能会对它们施加一些压力来解决它。
你正在做的是开始音频会话并保持开启状态,所以它立即躲避并保持躲避状态,这样当你播放声音时它不会再淹没音乐。暂停和播放音乐后音乐音量恢复的问题听起来像是一个错误。