如何在tvOS/iOS的AVPlayer中动态切换HLS的AAC与AC-3音频组
在tvOS/iOS中使用AVPlayer播放HLS流时启用AC-3音频的解决方案
场景描述
我在tvOS/iOS平台使用AVPlayer播放HLS流,主播放列表包含两个独立的AUDIO组:AAC(立体声)和AC-3(5.1),示例清单如下:
# AUDIO groups #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-212",LANGUAGE="dut",NAME="Dutch; Flemish",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2" #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-212",LANGUAGE="gos",NAME="audio_214401_gos",AUTOSELECT=YES,CHANNELS="2",URI="37194-audio_214401_gos=212400.m3u8" #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-ac-3-706",LANGUAGE="dut",NAME="Dutch; Flemish",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="6" # VARIANTS #EXT-X-STREAM-INF:BANDWIDTH=906000,CODECS="mp4a.40.2,avc1.4D401E",AUDIO="audio-aacl-212",SUBTITLES="textstream" 37194-audio_214400_dut=212400-video=556400.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1481000,CODECS="ac-3,avc1.4D401E",AUDIO="audio-ac-3-706",SUBTITLES="textstream" 37194-audio_708002_dut=706000-video=556400.m3u8
观察到的AVFoundation行为
readyToPlay触发后,asset.availableMediaCharacteristicsWithMediaSelectionOptions仅显示一个audible组;asset.mediaSelectionGroup(forMediaCharacteristic: .audible)仅提供AAC组内的语言选项(如dut、gos),可通过select(_:in:)切换;- 完全无法看到AC-3组。
问题
针对这种AAC与AC-3分属独立AUDIO组的主播放列表,如何在tvOS/iOS的AVPlayer中启用/强制使用杜比数字(AC-3)音频?
- 是否支持通过AVFoundation API在运行时切换活跃AUDIO组(从
audio-aacl-212到audio-ac-3-706)? - 还是必须启动(或重启)到引用
AUDIO="audio-ac-3-706"的变体流才能获取AC-3音频?
注:无法修改服务器端的HLS清单,仅需正确的AVFoundation实现方案。环境:tvOS 16、AVFoundation(AVPlayer/AVPlayerItem)
解决方案
核心结论
要获取AC-3音频,必须切换到绑定audio-ac-3-706的变体流,AVFoundation不支持跨AUDIO组的直接运行时切换——因为这两个AUDIO组属于不同的HLS变体,每个变体流绑定了固定的音频组,媒体选择API仅能操作当前变体关联的音频选项。
具体实现步骤
- 获取目标变体流:从
AVAsset的availableVariants属性中遍历所有变体,筛选出绑定audio-ac-3-706的变体:
guard let asset = player.currentItem?.asset as? AVURLAsset else { return } let targetVariant = asset.availableVariants.first { variant in variant.audioGroupID == "audio-ac-3-706" }
- 切换到目标变体:使用
AVPlayerItem的select(_:completionHandler:)方法切换变体,此操作无需重启播放器,可在运行时完成:
if let targetVariant = targetVariant { player.currentItem?.select(targetVariant) { success in if success { // 变体切换成功,获取并选择AC-3音频组的默认选项 if let ac3AudioGroup = player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .audible), let defaultOption = ac3AudioGroup.defaultOption { player.currentItem?.select(defaultOption, in: ac3AudioGroup) } } else { // 处理变体切换失败的逻辑 } } }
- 验证切换结果:变体切换成功后,
asset.availableMediaCharacteristicsWithMediaSelectionOptions会更新,此时可以获取到AC-3对应的音频组,并进行语言选择(此场景下AC-3组仅包含dut语言选项)。
问题解答
- 不支持直接跨AUDIO组切换——因为两个AUDIO组属于不同的HLS变体,媒体选择API的作用范围仅限于当前变体流绑定的音频组。
- 不需要重启播放器,只需通过
AVPlayerItem.select(_:completionHandler:)方法切换到引用audio-ac-3-706的变体流,即可获取AC-3音频。
内容的提问来源于stack exchange,提问作者Александр Уткин
相关产品推荐
相关产品推荐

