iOS AVFoundation之音频、视频、字幕切换
主要用到的类有AVMediaSelectionGroup
和AVMediaSelectionOption
, 我们大概的可以理解他们的关系为AVMediaSelectionGroup
里面有好多个AVMediaSelectionOption
对象构成的
其中AVMediaSelectionGroup
的options
属性就是多个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];//设置上去
}
}
其他字幕, 音频,或视频的不同轨道也类似