My Requirement: I need to get list of all audio tracks from a video then switch to selected audio track.
Approach and Problem: I am using two ways because some time first way do not provide result in that case I am using second one and sometimes both do not get result while VLC media player shows video have audio tracks.
I looked apple documentation https://developer.apple.com/library/mac/releasenotes/AudioVideo/RN-AVFoundation/index.html#//apple_ref/doc/uid/TP40010717-CH1-DontLinkElementID_1 that suggested first way.
My Code for getting Audio tracks -:
- (NSArray *)getAvailableAudioTracks
{
NSMutableArray *allAudioTracks = [NSMutableArray new];
AVURLAsset *asset = (AVURLAsset *)[[self.mPlayer currentItem] asset];
//** 1st Way
AVMediaSelectionGroup *audioTracks = [asset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicAudible];
for (AVMediaSelectionOption *option in audioTracks.options)
{
NSLog(@"Audio Track Display Name: %@", option.displayName);
[allAudioTracks addObject:option];
}
//** 2nd way
NSArray *audiTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
if(allAudioTracks.count == 0) {
allAudioTracks = [NSMutableArray arrayWithArray:audiTracks];
}
[self.audioTracks removeAllObjects];
self.audioTracks = allAudioTracks;
return allAudioTracks;
}
Code for switch to selected track(s)-
- (void)playSelectedAudioTracks:(NSArray *)selectedAudioTracks {
if (selectedAudioTracks.count == 0 || self.audioTracks.count <2) {
return;
}
for (id audioTrack in selectedAudioTracks) {
if ([audioTrack isKindOfClass:[AVMediaSelectionOption class]]) {
[self changeAudioTrackWithSelectedAudioOption: audioTrack];
} else if ([audioTrack isKindOfClass:[AVAssetTrack class]]) {
AVAsset *asset = [[self.mPlayer currentItem] asset];
NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
NSMutableArray *allAudioParams = [NSMutableArray array];
for (AVAssetTrack *track in audioTracks)
{
float trackVolume = 0.0;
if ([selectedAudioTracks containsObject:track]) {
trackVolume = 1.0;
}
AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
[audioInputParams setVolume:trackVolume atTime:kCMTimeZero];
[audioInputParams setTrackID:[track trackID]];
[allAudioParams addObject:audioInputParams];
}
AVMutableAudioMix *audioZeroMix = [AVMutableAudioMix audioMix];
[audioZeroMix setInputParameters:allAudioParams];
dispatch_async(dispatch_get_main_queue(), ^{
[[self.mPlayer currentItem] setAudioMix:audioZeroMix];
});
}
}
}
- (void)changeAudioTrackWithSelectedAudioOption:(AVMediaSelectionOption *)selectedAudioOption {
AVAsset *asset = [[self.mPlayer currentItem] asset];
AVMediaSelectionGroup *audoTracks = [asset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicAudible];
[[self.mPlayer currentItem] selectMediaOption:selectedAudioOption inMediaSelectionGroup:audoTracks];
}
Questions: Q1) Why first way is not working maximum time? What am I doing wrong? What is correct way to find out audio tracks from video?
Q2) I am using two approaches
a)-: Get Audio tacks using 1st way then use changeAudioTrackWithSelectedAudioOption
: this method.
b) Get Audio tracks using 2nd way then adjust volume using AVMutableAudioMixInputParameters
class.
I do not exactly know what is difference b/w these two. Please let me know what is difference b/w these two? I know apple suggest first way but still want two know Is second approach is correct or not?
Thank you....:)