ios 7 non deprecated solution to resuming background music from duck

1.5k views Asked by At

I am able to duck my background audio while playing new sounds. However I am unable to resume the background audio level to maximum again. When my delegate tries to "unduck" it just keeps being ducked. The normal fix for this is AudiosessionSetProperty, but that's deprecated in iOS 7 and Apple doesn't give any hints in the deprecation warnings or documentation.

I call this method on load of view.

- (void) configureAVAudioSession
{
    //get your app's audioSession singleton object
    AVAudioSession* session = [AVAudioSession sharedInstance];

    //error handling
    BOOL success;
    NSError* error;


     success=[session setCategory:AVAudioSessionCategoryPlayback
                 withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];



    if (!success)
    {
         NSLog(@"AVAudioSession error :%@",error);

    }
    else
    {

    }
    success = [session setActive:YES error:&error];

    if (!success) {
        NSLog(@"Error setting active %@",error);
    }
    else
    {
        NSLog(@"succes settings active");
    }


}

This is when I play audio

-(void)playTimeOnGo
{


    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                         pathForResource:@"just-like-magic"
                                         ofType:@"mp3"]];
    self.audioPlayer = [[AVAudioPlayer alloc]
                        initWithContentsOfURL:url
                        error:nil];
      self.audioPlayer.delegate=(id<AVAudioPlayerDelegate>)self;

    //get your app's audioSession singleton object
    AVAudioSession* session = [AVAudioSession sharedInstance];

    //error handling
    BOOL success;
    NSError* error;


    success=[session setCategory:AVAudioSessionCategoryPlayback
                     withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error];

    [self.audioPlayer prepareToPlay];
    [self.audioPlayer play];


    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}

This is my delegate when audio is done to resume background audio and undock audio

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)data successfully:(BOOL)flag{

    [self configureAVAudioSession];

    NSLog(@"playback ended");

}

So how do I unduck the background music again without deprecated APIs? calling [self configureAVAudioSession]; apparently doesn't work....

1

There are 1 answers

0
aZtraL-EnForceR On

Ladies an gentlemen, I provide you with a non-deprecated working example of how to properly use ducking in iOS 7.

In your whatever "view load method" call this method, where the bool is set to YES. this will mix the background audio and prepare it for ducking

  - (void) configureAVAudioSession:(bool) active
    {
        //get your app's audioSession singleton object
        AVAudioSession* session = [AVAudioSession sharedInstance];

        //error handling
        BOOL success;
        NSError* error;


         success=[session setCategory:AVAudioSessionCategoryPlayback
                     withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];



        if (!success)
        {
             NSLog(@"AVAudioSession error :%@",error);

        }
        else
        {

        }
        success = [session setActive:active error:&error];

        if (!success) {
            NSLog(@"Error setting active %@",error);
        }
        else
        {
            //NSLog(@"success settings active");
        }

 }

Play you audio file with this method. Watch how ducking happens.. remember to set the delegate as i have in this example EVERY time you play a new audio alert. dont set it once in view load methods.

-(void)playTimeOnGo
{


    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                         //alertName is the name of your audio file without extention. extenstions is, doh extenstion like "mp" 
                       pathForResource:_dataManager.optionsSettings.setStarts.alertName
                                        ofType:_dataManager.optionsSettings.setStarts.alertExtension]];
    self.audioPlayer = [[AVAudioPlayer alloc]
                        initWithContentsOfURL:url
                        error:nil];
    self.audioPlayer.delegate=(id<AVAudioPlayerDelegate>)self;

    //get your app's audioSession singleton object
    AVAudioSession* session = [AVAudioSession sharedInstance];

    //error handling
    BOOL success;
    NSError* error;


    success=[session setCategory:AVAudioSessionCategoryPlayback
                     withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error];

    [self.audioPlayer prepareToPlay];
    [self.audioPlayer play];


    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}

the delegate will call this method after playback and turn up the volume of background music :) Please dont get confused that i am using a thread for this. u can just call the method if you wish but this stalls the main thread about a second maybe even two seconds. So it thats okay with you, dont use a thread and just call [self configureAVAudioSession:NO];

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)data successfully:(BOOL)flag
{
    _playBackFinishedDelegateThead = [[NSThread alloc] initWithTarget:self selector:@selector(configureAVAudioSession:) object:NO];
    [_playBackFinishedDelegateThead start];

}

This example IS 100% tested and working in my app.