iOS - How to get all audio tracks from a video fil

2019-04-13 07:31发布

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....:)

0条回答
登录 后发表回答