Switch audio trakcs for AVURLAsset with multiple AVAssetTracks of type audio
Asked Answered
W

1

6

I have an AVURLAsset with multiple AVAssetTracks of type audio. I would like to be able to allow user to switch between these different audio track by touching a button. It is working to turn volume of 1st track on and off but other tracks are not heard when volume set to 1.0.

Here is code for adjusting the volume of the tracks (sender is a UIButton with tag set to index of asset in audioTracks).

AVURLAsset *asset = (AVURLAsset*)[[player currentItem] asset];
NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];


NSMutableArray *allAudioParams = [NSMutableArray array];
int i = 0;
NSLog(@"%@", audioTracks);
for (AVAssetTrack *track in audioTracks) {
    AVMutableAudioMixInputParameters *audioInputParams =    [AVMutableAudioMixInputParameters audioMixInputParameters];
    float volume = i == sender.tag ? 1.0 : 0.0;
    [audioInputParams setVolume:volume atTime:kCMTimeZero];
    [audioInputParams setTrackID:[track trackID]];
    [allAudioParams addObject:audioInputParams];
    i++;
}
AVMutableAudioMix *audioZeroMix = [AVMutableAudioMix audioMix];
[audioZeroMix setInputParameters:allAudioParams];

[[player currentItem] setAudioMix:audioZeroMix];

Do I need to do something to bring the desired track to be the active one?

Weissman answered 12/9, 2011 at 18:21 Comment(0)
W
4

Ok found issue. Was not related to above code as this works fine. The problem was the AVAssetTracks for audio other than 1st track were not enabled. To enable them had to recreate the asset using AVMutableComposition:

NSURL *fileURL = [[NSBundle mainBundle]
                  URLForResource:@"movie" withExtension:@"mp4"];

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];

AVMutableComposition *composition = [AVMutableComposition composition];

AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSError* error = NULL;

[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,asset.duration) 
                               ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0] 
                                atTime:kCMTimeZero
                                 error:&error];

NSArray *allAudio = [asset tracksWithMediaType:AVMediaTypeAudio];
for (int i=0; i < [allAudio count]; i++) {
    NSError* error = NULL;
    AVAssetTrack *audioAsset = (AVAssetTrack*)[allAudio objectAtIndex:i];

    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,asset.duration) 
                                   ofTrack:audioAsset
                                    atTime:kCMTimeZero
                                     error:&error];

    NSLog(@"Error : %@", error);

}
Weissman answered 14/9, 2011 at 21:41 Comment(1)
Thank you, thank you, thank you! This was super helpful!Incomparable

© 2022 - 2024 — McMap. All rights reserved.