欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iOS AVFoundation之音频、视频、字幕切换

程序员文章站 2022-07-01 15:28:46
...

主要用到的类有AVMediaSelectionGroupAVMediaSelectionOption, 我们大概的可以理解他们的关系为AVMediaSelectionGroup里面有好多个AVMediaSelectionOption对象构成的

其中AVMediaSelectionGroupoptions属性就是多个AVMediaSelectionOption组成的数组

1.接口

AVMediaSelectionGroup
//里面包含多个AVMediaSelectionOption
@property (nonatomic, readonly) NSArray<AVMediaSelectionOption *> *options;
//默认的AVMediaSelectionOption
@property (nonatomic, readonly, nullable) AVMediaSelectionOption *defaultOption NS_AVAILABLE(10_10, 8_0);
//如果设为YES ,  -[AVPlayerItem selectMediaOption:inMediaSelectionGroup:]的第一个参数可以设为空
@property (nonatomic, readonly) BOOL allowsEmptySelection;
//根据plist从AVMediaSelectionGroup的options取出相对应的AVMediaSelectionOption,没有找到则返回nil
- (nullable AVMediaSelectionOption *)mediaSelectionOptionWithPropertyList:(id)plist;

AVMediaSelectionGroup筛选AVMediaSelectionOption的方法有

//从`AVMediaSelectionOption`数组中获取可播放的`AVMediaSelectionOption`
+ (NSArray<AVMediaSelectionOption *> *)playableMediaSelectionOptionsFromArray:(NSArray<AVMediaSelectionOption *> *)mediaSelectionOptions;
//根据语言筛选出AVMediaSelectionOption, preferredLanguages可以通过+[NSLocale preferredLanguages]获取
+ (NSArray<AVMediaSelectionOption *> *)mediaSelectionOptionsFromArray:(NSArray<AVMediaSelectionOption *> *)mediaSelectionOptions filteredAndSortedAccordingToPreferredLanguages:(NSArray<NSString *> *)preferredLanguages NS_AVAILABLE(10_8, 6_0);
//根据NSLocale筛选
+ (NSArray<AVMediaSelectionOption *> *)mediaSelectionOptionsFromArray:(NSArray<AVMediaSelectionOption *> *)mediaSelectionOptions withLocale:(NSLocale *)locale;
//根据mediaCharacteristics筛选, 具体看AVMediaFormat.h,例如: AVMediaCharacteristicVisual
+ (NSArray<AVMediaSelectionOption *> *)mediaSelectionOptionsFromArray:(NSArray<AVMediaSelectionOption *> *)mediaSelectionOptions withMediaCharacteristics:(NSArray<NSString *> *)mediaCharacteristics;
//这个跟上一个相反, 筛选出除了mediaCharacteristics这个参数之外的AVMediaSelectionOption
+ (NSArray<AVMediaSelectionOption *> *)mediaSelectionOptionsFromArray:(NSArray<AVMediaSelectionOption *> *)mediaSelectionOptions withoutMediaCharacteristics:(NSArray<NSString *> *)mediaCharacteristics;
AVMediaSelectionOption

里面很多属性之前的文章都分析过了, 就不分析了,

//自己和另外一个mediaSelectionGroup的联系(我也不太懂)
- (nullable AVMediaSelectionOption *)associatedMediaSelectionOptionInMediaSelectionGroup:(AVMediaSelectionGroup *)mediaSelectionGroup;
//获取到的内容主要是方便在mediaSelectionGroup的- (nullable AVMediaSelectionOption *)mediaSelectionOptionWithPropertyList:(id)plist;方法查找对应的AVMediaSelectionOption
- (id)propertyList;
//展示的名字,例如:AVMediaCharacteristicLegible中的英语字母操作AVMediaSelectionOption的displayName是English
@property (nonatomic, readonly) NSString *displayName

2.用法

我们看一下常见的用法:
初始化一个AVAsset

   NSURL *videoUrl = [[NSBundle mainBundle] URLForResource:@"hubblecast.m4v" withExtension:nil];
    AVAsset *videoAsset = [AVAsset assetWithURL:videoUrl];
    self.videoAsset = videoAsset;
   AVPlayerItem *videoItem = [AVPlayerItem playerItemWithAsset:videoAsset];
    self.videoItem = videoItem;

获取到这个videoAsset里面能使用的mediaCharacteristics, 一般有AVMediaCharacteristicVisual(视频)AVMediaCharacteristicAudible(音频)AVMediaCharacteristicLegible(字幕)等等;根据这三个可以可以获取到AVMediaSelectionGroup
假如:我们是根据AVMediaCharacteristicVisual获取到的AVMediaSelectionGroup, 里面可能有高清, 标清等不能的视频AVMediaSelectionOptio;根据AVMediaCharacteristicAudible获取到的AVMediaSelectionGroup, 里面可能是英语, 国语等不能的音频AVMediaSelectionOption, 根据AVMediaCharacteristicLegible获取到的AVMediaSelectionGroup, 里面可能是英语, 国语等不能的字幕AVMediaSelectionOption

NSArray *mediaCharacteristics = [self.videoAsset availableMediaCharacteristicsWithMediaSelectionOptions];
    for (NSString *charactteristic in mediaCharacteristics) {
        AVMediaSelectionGroup *group = [self.videoAsset mediaSelectionGroupForMediaCharacteristic:charactteristic];
        NSLog(@"%@", charactteristic);
        for (AVMediaSelectionOption *option in group.options) {
            NSLog(@"%@", option.displayName);
           // AVMediaCharacteristicAudible : English
            /* AVMediaCharacteristicLegible :
               English
               English Forced
               Italian
               Italian Forced
               Portuguese,
               Portuguese Forced
               Russian,
               Russian Forced
             可以看出, 音频只有English一种AVMediaSelectionOption, 字幕有8种AVMediaSelectionOption。
             */
        }
    }

获取到不同轨道的信息, 显示出来给用户做出选择,根据用户的选择来做播放
例如:我要在刚才的例子中播放俄语:

-(void)playRussianAVMediaSelectionOption {
    NSString *legibleString = AVMediaCharacteristicLegible;
    AVMediaSelectionGroup *mediaCharactisticGroup = [self.videoAsset mediaSelectionGroupForMediaCharacteristic:legibleString];//筛选出字幕的轨道

    NSLocale *russianLocale = [NSLocale localeWithLocaleIdentifier:@"ru_RU"];//俄语的标识
    NSArray *options = [AVMediaSelectionGroup mediaSelectionOptionsFromArray:mediaCharactisticGroup.options withLocale:russianLocale];//筛选出俄语字幕的轨道
    if (options.count > 0) {
        AVMediaSelectionOption *option = options.firstObject;//获取一个, 这里虽然返回的是数组,但一般只有一个
        [self.videoItem selectMediaOption:option inMediaSelectionGroup:mediaCharactisticGroup];//设置上去
    }
}

其他字幕, 音频,或视频的不同轨道也类似