2010-07-20 2 views
8

У меня есть приложение, которое использует MPAudioPlayerController для доступа к музыкальной библиотеке iPod и AVAudioPlayer для наложения звука поверх музыки. В качестве руководства я использовал this documentation. В частности:Аудиозапись «Ducking» Сломанная в iOS 4 ...?

Наконец, вы можете улучшить категорию, чтобы автоматически понижать громкость другого звука при воспроизведении звука. Это можно использовать, например, в приложении для упражнений. Скажите, что пользователь упражняется на своем iPod, когда ваше приложение хочет наложить вербальное сообщение, например: «Вы грести в течение 10 минут». Чтобы сообщение из вашего приложения было понятным, примените свойство kAudioSessionSizeSourceSource аудио сессии. Когда происходит уклонение, все остальные аудио на устройстве, кроме звука телефона, уменьшаются в объеме.

Но я не вижу такого поведения. Фактически, то, что я вижу (или слышу, скорее), состоит в том, что, если я настрою AudioSession с kAudioSessionProperty_OtherMixableAudioShouldDuck равным true, начальный том MPAudioPlayerController уменьшится, и если я затем перезвоню (а затем снова воспроизведет) на MPAudioPlayerController, уровень громкости увеличивается до «нормальных» уровней. Воспроизведение 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. И, что больше похоже на ошибку, это то, что когда я останавливаюсь, а затем проигрываю MPMusicPlayerController, громкость музыки увеличивается до уровня, который был бы, если бы я не настраивал AudioSession.

Мне интересно узнать, имел ли кто-либо еще этого опыта, и если да, если вы нашли работу (или можете сказать мне, что я делаю что-то неправильно). В противном случае, я думаю, я ухожу в Радар.

Большое спасибо,

Леви

ответ

2

Документация не ясно, о том, что ожидаемое поведение приглушения должно быть, но то, что я обнаружил, что если вы установили звуковую сессию когда вы активируете сеанс аудио, он утирается, и когда вы его деактивируете, он отключается. Поэтому вы должны продолжать активировать и деактивировать аудио сессию, чтобы укусить музыку только для вашего звукового сигнала.

Одна ошибка, которую я обнаружил, заключается в том, что если вы отключите аудио сессию, находясь внутри метода audioPlayerDidFinishPlaying:successfully: вашего AVAudioPlayerDelegate, утка не будет удалена, а громкость будет сохранена на том же уровне. Я уже подал на него радар, но это не повредит, если другие похожие файлы. На самом деле это, вероятно, повлияет на них, чтобы исправить это.

Что вы делаете, это запуск аудиосеанса и его поддержание, поэтому он утирается немедленно и остается приглушенным, так что он не усыпляет музыку дальше, когда вы играете звук. Проблема с громкостью музыки, возникающей после паузы и воспроизведения музыки, звучит как ошибка.

3

Ducking никак не связан с вашими звуками воспроизведения. Когда вы включаете ducking, фоновый звук утки. Когда вы выключаете утенок и деактивируете свою аудио сессию, фоновый звук возвращается к исходному уровню.

So не включить ducking в ваш viewDidLoad. Не включайте его, пока вы на самом деле не собираетесь воспроизводить звук. Это заставляет фоновый звук утка. Когда ваш звук будет воспроизводиться, выключите и снова выключите аудиозапись. Это заставляет фоновый звук отключать:

UInt32 duck = 0; 
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, 
         sizeof(duck), &duck); 
AudioSessionSetActive(false); 
AudioSessionSetActive(true); 
9

Я использовал этот пост, когда у меня была аналогичная проблема, и мне не удалось заставить его работать последовательно. Это сработало бы некоторое время, а затем просто застряло бы «нырнуло». Я потратил много времени на исследование и отладку этого и, наконец, просто назвал Apple. Мне сказали, чтобы я посмотрел на образец кода. Я последовал этому примеру, и все сработало нормально.

Вот от Apple пример кода:

http://developer.apple.com/library/ios/#samplecode/Breadcrumb/Introduction/Intro.html

Поддержка/разработчик в компании Apple также сказал, чтобы наблюдать порядок, как и когда они устанавливают свойства сеанса. Похоже, это был трюк. Прочитав много сообщений здесь и в другом месте, у меня были настройки, которые противоречили друг другу. Начиная с нуля и следуя примеру хлебной крошки, он заработал. С тех пор у меня не было проблемы.

Я отправил тот же самый ответ здесь:

How to unduck AVAudioSession

Для меня этот ответ был пограничным торговым секретом, так как это было так трудно получить работу и там работали приложения на рынке. Для меня, видя рабочий пример, который был в значительной степени просто звуком, уклоняющимся и неуправляемым, стоил своего веса в золоте.

Кроме того, я упомянул Apple, что это была известная проблема, и они не согласились. Они не знали о какой-либо проблеме здесь. Разумеется, если вы будете следовать примеру пакетирования, он будет работать с любой странной сессией, дезактивирующей и реактивной, и т. Д. И т. Д.