Аудио сессия "Ducking" сломана в iOS 4 ...? - PullRequest
8 голосов
/ 20 июля 2010

У меня есть приложение, которое использует MPAudioPlayerController для доступа к музыкальной библиотеке iPod и AVAudioPlayer для наложения звука поверх музыки. Я использовал эту документацию в качестве руководства. В частности:

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

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

Я подключил пару кнопок UIB. Один для musicAction (используется для воспроизведения / паузы MPMusicPlayerController) и один для soundAction (используется для воспроизведения / паузы AVAudioPlayer).

Как уже упоминалось, если я касаюсь кнопки musicAction, музыка воспроизводится, но с уменьшенным уровнем громкости, и если я нажимаю кнопку soundAction, наложение воспроизводится, но не влияет на громкость MPMusicPlayerController. И, более похоже на ошибку, это то, что когда я делаю паузу и затем играю MPMusicPlayerController, громкость музыки увеличивается до уровня, который был бы, если бы я не настроил AudioSession.

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

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

Леви

Ответы [ 3 ]

9 голосов
/ 01 октября 2011

Я использовал этот пост, когда у меня была похожая проблема, и у меня были проблемы с тем, чтобы заставить его работать последовательно.Это будет работать какое-то время, а затем просто застрять "утка".Я потратил много времени на исследование и отладку этого и, наконец, просто позвонил в Apple.Они сказали мне, чтобы посмотреть на пример кода крошки.Я последовал этому примеру, и все работало нормально.

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

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

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

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

Как отсоединить AVAudioSession

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

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

3 голосов
/ 09 января 2011

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

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

UInt32 duck = 0;
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, 
                        sizeof(duck), &duck);
AudioSessionSetActive(false);
AudioSessionSetActive(true);
2 голосов
/ 28 июля 2010

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

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

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

...