2010-07-20 6 views
8

Ich habe eine App, die den MPAudioPlayerController verwendet, um auf die iPod Musikbibliothek zuzugreifen, und einen AVAudioPlayer, um Audio über die Musik zu legen. Ich habe this documentation als Leitfaden verwendet. Speziell:Audio Session "Ducking" in iOS 4 ...?

Schließlich können Sie eine Kategorie erweitern, um automatisch die Lautstärke anderer Audiodaten zu verringern, wenn Ihr Audio abgespielt wird. Dies könnte zum Beispiel in einer Übungsanwendung verwendet werden. Sagen Sie, der Benutzer trainiert gerade mit seinem iPod, wenn Ihre Anwendung eine verbale Nachricht überlagern möchte - zum Beispiel: "Sie haben 10 Minuten lang gerudert." Um sicherzustellen, dass die Nachricht aus Ihrer Anwendung verständlich ist, wenden Sie die Eigenschaft kAudioSessionProperty_OtherMixableAudioShouldDuck an Audiositzung. Wenn das Ducking stattfindet, werden alle anderen Audiodaten auf dem Gerät - abgesehen von Telefonaudio - in der Lautstärke reduziert.

Aber ich sehe dieses Verhalten nicht. In der Tat, was ich sehe (oder eher höre) ist, dass, wenn ich die AudioSession mit kAudioSessionProperty_OtherMixableAudioShouldDuck auf true gesetzt habe, die MPAudioPlayerController-Anfangslautstärke reduziert wird, und wenn ich dann auf dem MPAudioPlayerController die Lautstärke anhöre (und dann wieder spiele) wird auf "normale" Level erhöht. Die Wiedergabe des AVAudioPlayers hat keinen Einfluss auf den Audiopegel ...

Also habe ich einen einfachen Testfall eingerichtet, um dies zu reproduzieren.

In einem Viewcontroller-Header:

#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 

und bei der Umsetzung:

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

Ich habe ein paar UIButtons verdrahtet. Eine für musicAction (zum Abspielen/Anhalten des MPMusicPlayerControllers) und eine für die soundAction (zum Abspielen/Anhalten des AVAudioPlayers).

Wie gesagt, wenn ich auf die musicAction-Schaltfläche tippe, wird die Musik abgespielt, aber mit reduzierter Lautstärke. Wenn ich auf die soundAction-Schaltfläche tippe, wird das Overlay wiedergegeben, hat aber keinen Einfluss auf die Lautstärke des MPMusicPlayerControllers. Und noch mehr Bugs: Wenn ich den MPMusicPlayerController pausiere und spiele, erhöht sich die Lautstärke der Musik auf den Pegel, den ich hätte, wenn ich AudioSession nicht eingerichtet hätte.

Ich bin interessiert zu wissen, ob jemand anderes diese Erfahrung gemacht hat, und wenn ja, wenn Sie eine Arbeit gefunden haben (oder mir sagen können, dass ich etwas falsch mache). Sonst gehe ich wohl zu Radar.

Vielen Dank,

Levi

Antwort

2

Die Dokumentation ist nicht klar, was das erwartete Verhalten von ducking sein soll, aber was ich gefunden habe, ist, dass, wenn Sie Ihre Audio-Sitzung einrichten für Ducking, wenn Sie die Audio-Session aktivieren, es Enten, und wenn Sie es deaktivieren, esckt sich. Sie müssen also die Audio-Session aktivieren und deaktivieren, um die Musik nur für Ihren Sound-Cue zu entschlüsseln.

Ein Fehler, den ich fand, ist, dass, wenn Sie die Audiositzung innerhalb der Methode Ihrer AVAudioPlayerDelegate deaktivieren, die Ducking nicht entfernt wird, und die Lautstärke auf dem gleichen Niveau gehalten wird. Ich habe bereits ein Radar auf diesem, aber es tut nicht weh, wenn andere ähnliche Dateien. In der Tat wird es wahrscheinlich Druck auf sie ausüben, es zu reparieren.

Sie starten die Audio-Session und halten sie an, so dass sie sich sofort duckt und duckt bleibt, so dass sie die Musik nicht weiter entschlüsselt, wenn Sie einen Sound abspielen. Das Problem, dass die Musiklautstärke nach dem Pausieren und Abspielen der Musik wieder ansteigt, klingt wie ein Fehler.

3

Das Ducken bezieht sich nicht automatisch auf Ihre Spielsounds. Wenn Sie das Ducking einschalten, ertönt Hintergrundgeräusch. Wenn Sie die Ducking-Funktion deaktivieren und Ihre Audiositzung deaktivieren, wird der Hintergrundton wieder auf den ursprünglichen Pegel zurückgesetzt.

So nicht einschalten Ducking in Ihrem viewDidLoad. Schalten Sie es erst ein, wenn Sie gerade den Ton abspielen. Das führt dazu, dass sich der Hintergrundsound duckt. Wenn Ihr Sound abgespielt wurde, schalten Sie das Ducking wieder aus und schalten Sie Ihre Audiositzung wieder aus und wieder aktiv. Das verursacht den Hintergrundsound zum Einklemmen:

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

Ich benutzte diesen Posten, als ich ein ähnliches Problem hatte und Schwierigkeiten hatte, es gleichmäßig zu arbeiten zu lassen. Es würde für eine Weile funktionieren und dann einfach stecken bleiben "duckte". Ich habe viel Zeit damit verbracht, das zu erforschen und zu debuggen, und habe schließlich nur Apple angerufen. Sie sagten mir, ich solle mir den Breadcrumb-Beispielcode ansehen. Ich bin diesem Beispiel gefolgt und alles hat gut funktioniert.

Hier ist Beispielcode von Apple:

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

Der Träger/Entwickler bei Apple sagte, auch die Reihenfolge der sehen, wie und wann sie die Sitzungseigenschaften eingestellt. Das war anscheinend der Trick. Nach dem Lesen vieler Beiträge hier und anderswo hatte ich Einstellungen, die miteinander in Konflikt standen. Von Grund auf neu zu beginnen und dem Brotkrumen-Beispiel zu folgen, hat es funktioniert. Ich hatte seither kein Problem.

gepostet ich die gleiche Antwort hier:

How to unduck AVAudioSession

Für mich ist diese Antwort war grenzwertig Geschäftsgeheimnis, da es so schwierig war, zu erhalten arbeiten und es gab Arbeits Anwendungen auf dem Markt. Für mich war ein funktionierendes Beispiel, das so ziemlich das Geräusch von Ducking und Unducking war, Gold wert.

Auch ich erwähnte Apple, dass dies ein bekanntes Problem war und sie waren nicht einverstanden. Ihnen war hier kein Problem bekannt. Sicher genug, wenn Sie dem Breadcrumb-Beispiel folgen, funktioniert es ohne irgendeine merkwürdige Sitzung, die deaktiviert und reaktiv ist, usw.