2010-07-20 13 views
8

Ho un'app che utilizza MPAudioPlayerController per accedere alla libreria musicale di iPod e un AVAudioPlayer per sovrapporre l'audio sulla parte superiore della musica. Ho usato this documentation come guida. In particolare:Audio Session "Ducking" Rotto in iOS 4 ...?

Infine, è possibile migliorare una categoria per abbassare automaticamente il volume di altri audio durante la riproduzione dell'audio. Questo potrebbe essere usato, ad esempio, in un'applicazione di esercizio. Supponiamo che l'utente si stia esercitando sul proprio iPod quando l'applicazione desidera sovrapporre un messaggio verbale, ad esempio "Hai canottaggio per 10 minuti". Per garantire che il messaggio dell'applicazione sia comprensibile, applica la proprietà kAudioSessionProperty_OtherMixableAudioShouldDuck al sessione audio. Quando avviene il ducking, tutti gli altri audio sul dispositivo, a parte l'audio del telefono, diminuiscono di volume.

Ma non vedo questo comportamento. In effetti, quello che vedo (o sento, piuttosto) è che se imposto AudioSession con kAudioSessionProperty_OtherMixableAudioShouldDuck impostato su true, il volume iniziale di MPAudioPlayerController viene ridotto, e se poi richiamo pause (e poi riproduco di nuovo) su MPAudioPlayerController il livello del volume viene aumentato a livelli "normali". Riproduzione di AVAudioPlayer non ha alcun effetto sul livello audio ...

Quindi ho creato un semplice caso di test per riprodurre questo.

In un colpo di testa 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 

e nella realizzazione:

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

ho cablato un paio UIButtons. Uno per la musicaAzione (utilizzata per riprodurre/sospendere MPMusicPlayerController) e una per l'audioAzione (utilizzata per riprodurre/sospendere AVAudioPlayer).

Come accennato, Se tocco il pulsante MusicAction, la musica suona, ma a un livello di volume ridotto, e se tocco il pulsante SoundAction, la sovrapposizione viene riprodotta, ma non ha alcun effetto sul volume del MPMusicPlayerController. E, più simile a un bug, è che quando metto in pausa e poi su MPMusicPlayerController il volume della musica aumenta al livello che sarebbe stato se non avessi impostato AudioSession.

Sono interessato a sapere se qualcun altro ha avuto questa esperienza, e in tal caso se hai trovato un lavoro in giro (o puoi dirmi che sto facendo qualcosa di sbagliato). Altrimenti, suppongo di essere fuori da Radar.

Molte grazie,

Levi

risposta

2

La documentazione non è chiaro su ciò che il comportamento previsto della ducking si suppone che sia, ma quello che ho trovato è che se si imposta la sessione audio per ducking, quando si attiva la sessione audio, si annerisce, e quando lo si disattiva, svanisce. Quindi devi continuare ad attivare e disattivare la sessione audio per fermare la musica solo per il tuo sound cue.

Un errore riscontrato è che se si disattiva la sessione audio mentre si è all'interno del metodo audioPlayerDidFinishPlaying:successfully: del proprio AVAudioPlayerDelegate, il ducking non viene rimosso e il volume viene mantenuto allo stesso livello. Ho già archiviato un radar su questo, ma non fa male se altri file simili. In effetti probabilmente metterà un po 'di pressione su di loro per risolverlo.

Quello che stai facendo è avviare la sessione audio e mantenerla attiva, in modo che si chiuda immediatamente e rimanga schivata, in modo che non emetta più musica quando suoni un suono. Il problema con il volume della musica risalente dopo aver messo in pausa e riprodotto la musica sembra un bug.

3

Il ducking non è correlato automaticamente ai suoni di riproduzione in alcun modo. Quando accendi il ducking, le anatre sonore di sottofondo. Quando si disattiva il ducking e si disattiva la sessione audio, il suono di sottofondo ritorna al suo livello originale.

Quindi non attivare il ducking nel viewDidLoad. Non accenderlo finché non si sta effettivamente per riprodurre il suono. Ciò fa in modo che il suono di fondo si schizzi. Quando il suono è terminato, gira il ducking e attiva di nuovo la sessione audio inattiva e attiva. Ciò causa l'annullamento del suono di sottofondo:

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

Ho usato questo post quando avevo un problema simile e avevo difficoltà a farlo funzionare in modo coerente. Funzionerebbe per un po 'e poi si bloccherebbe "schivato". Ho dedicato molto tempo alla ricerca e al debug di questo e, infine, ho appena chiamato Apple. Mi hanno detto di guardare il codice di esempio breadcrumb. Ho seguito quell'esempio e tutto ha funzionato bene.

Ecco il codice di esempio di Apple:

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

Il supporto/sviluppatore di Apple ha anche detto di guardare l'ordine di come e quando si impostano le proprietà della sessione. Quello a quanto pare era il trucco. Dopo aver letto molti post qui e altrove, avevo impostazioni che erano in conflitto tra loro. Partendo da zero e seguendo l'esempio della briciola di pane, ha funzionato. Da allora non ho avuto un problema.

ho postato la stessa risposta qui:

How to unduck AVAudioSession

Per me La risposta è stata borderline segreto commerciale dato che era così difficile da ottenere a lavorare e c'erano le applicazioni di lavoro del mercato. Per me, vedere un esempio funzionante, che era più o meno il solo suono del ducking and unducking, valeva il suo peso in oro.

Inoltre, ho accennato ad Apple che si trattava di un problema noto e non erano d'accordo. Non erano a conoscenza di alcun problema qui. Abbastanza sicuro se segui l'esempio del breadcrumb funziona senza alcuna sessione strana disattivata e reattiva, ecc., Ecc.