Sesión de audio "Ducking" roto en iOS 4 ...?

Tengo una aplicación que usa el MPAudioPlayerController para acceder a la biblioteca de música del iPod, y un AVAudioPlayer para superponer audio sobre la música. he usadoesta documentación como guía. Específicamente:

Finalmente, puede mejorar una categoría para bajar automáticamente el volumen de otro audio cuando se está reproduciendo. Esto podría usarse, por ejemplo, en una aplicación de ejercicio. Digamos que el usuario se está ejercitando junto con su iPod cuando su aplicación quiere superponer un mensaje verbal, por ejemplo, "ha estado remando durante 10 minutos". Para asegurarse de que el mensaje de su aplicación sea inteligible, aplique la propiedad kAudioSessionProperty_OtherMixableAudioShouldDuck a la propiedad sesión de audio Cuando se produce el agachamiento, el resto del audio del dispositivo, aparte del audio del teléfono, disminuye en volumen.

Pero no estoy viendo este comportamiento. De hecho, lo que veo (o escucho, más bien) es que si configuro AudioSession con kAudioSessionProperty_OtherMixableAudioShouldDuck establecido en verdadero, el volumen inicial de MPAudioPlayerController se reduce, y si luego llamo pausa (y luego vuelvo a reproducir) en MPAudioPlayerController, el nivel de volumen se incrementa a niveles "normales". Reproducir el AVAudioPlayer no tiene ningún efecto en el nivel de audio ...

Así que he configurado un caso de prueba simple para reproducir esto.

En un encabezado 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

y en la implementación:

- (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];
    }
}

He conectado un par de UIButtons. Uno para musicAction (utilizado para reproducir / pausar el MPMusicPlayerController) y otro para soundAction (utilizado para reproducir / pausar el AVAudioPlayer).

Como se mencionó, si toco el botón musicAction, la música se reproduce, pero a un nivel de volumen reducido, y si toco el botón soundAction, se reproduce la superposición, pero no afecta el volumen del MPMusicPlayerController. Y, más parecido a un error, es que cuando hago una pausa y luego reproduzco el MPMusicPlayerController, el volumen de la música aumenta al nivel que hubiera sido si no hubiera configurado la AudioSession.

Me interesa saber si alguien más ha tenido esta experiencia, y si es así, si ha encontrado una solución (o puede decirme que estoy haciendo algo mal). De lo contrario, supongo que me voy al radar.

Muchas gracias,

Levi

Respuestas a la pregunta(3)

Su respuesta a la pregunta