lbrt.Net

Pinoy Software Engineer

Category Archives: Uncategorized

IOS: Audiosession: audioplayer ducking on same session

I’ve been busy for almost a year now, just joined a company that is focus on improving developers skills and creating great applications! Learned a lot from my almost 2years of absence in blogging.

Before you continue, I’d like to note that this article assumes you already know or studied AVFoundation Framework and has knowledge to the usage/creation of AVPlayer and AVAudioplayer

So I learned a lot of IoS objective-c coding since my last blog, One of which has no resource on the net yet which is “Audiosession: audioplayer ducking on same session”. I’ve seen a lot of references on which “ducking” was implemented via settings below:

UInt32 value = 1; //1 means YES
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(value), &value);
AudioSessionSetActive(YES);

But that code snippet basically allows ducking of sound from other audio sessions. What if you have two avplayers or one avplayer as background music and one avaudioplayer that well play as warning sound and you basically need the background music to “duck” (e.g. ducking is the lowering of volume of a sound to allow other sound to have emphasis, then increasing again in sound to its previous level once the other sound has finished).

here is a few lines of code credited to my co-worker “Ryan G.”.

-(void) setVolume:(float)volume withTime:(CMTime)time andAudioPlayer:(AVPlayer *)audioPlayer
{
    if(audioPlayer.currentItem.audioMix == nil)
    {
        NSArray *tracks = audioPlayer.currentItem.asset.tracks;
        
        NSMutableArray *params = [NSMutableArray arrayWithCapacity:tracks.count];
        for (AVAssetTrack *track in tracks) {
            AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
            
            [audioInputParams setVolume:volume atTime:time];
            [audioInputParams setTrackID:track.trackID];
            [params addObject:audioInputParams];
        }
        
        AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
        audioMix.inputParameters = params;
        audioPlayer.currentItem.audioMix = audioMix;
    }
    else
    {
        NSArray *params = audioPlayer.currentItem.audioMix.inputParameters;
        
        for (AVMutableAudioMixInputParameters *audioInputParams in params)
        {
            [audioInputParams setVolume:volume atTime:time];
        }
        
        AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
        audioMix.inputParameters = params;
        audioPlayer.currentItem.audioMix = audioMix;
    }
}

From there you basically just use it before and after sound playing of another player e.g.:

- (void) playWarningSound
{
   //Note: self.audioPlayer is a background music which is an instance of AVPlayer
   // self.audioplayer2 is a warning music which is an instance of AVAudioplayer

   //this will lower self.audioPlayer volume to 0.1
   [self setVolume:0.1 withTime:[self.audioPlayer currentTime] andAudioPlayer:self.audioPlayer1];
   self.audioplayer2.delegate = self;
   [self.audioplayer2 play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
   //this will return self.audioPlayer volume to 1
   [self setVolume:1 withTime:[self.audioPlayer currentTime] andAudioPlayer:self.audioPlayer1];
}

Note: self.audioPlayer is a background music which is an instance of AVPlayer, self.audioplayer2 is a warning music which is an instance of AVAudioplayer

So that’s it, your audioplayer2 will have a normal volume while your audioplayer1 will “duck” in volume. Don’t have a working project for download since this is pretty much straight forward if you know objective-c before hand. Happy XCoding!!!

Advertisements