我正在做一个tvOS应用,在这个应用中,我使用的是 AVPlayer
播放HLS播放列表,该列表为某些语言提供两种格式的音频。例如:法语(AAC)。
我试图显示一个自定义对话框,允许用户在这些曲目中进行选择。
播放列表看起来像这样。
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-mp4a.40.2",NAME="Français",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fr",URI="..."
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-ec-3",NAME="Français",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="fr",URI="..."
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-mp4a.40.2",NAME="English",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="en",URI="..."
问题是,据我所知... ... AVPlayer
按语言分组,但它从未返回所有的3个音轨。
(lldb) po player?.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .audible)
▿ Optional<AVMediaSelectionGroup>
- some : <AVAssetMediaSelectionGroup: 0x283961940, options = (
"<AVMediaSelectionKeyValueOption: 0x2839a5a00, language = fr, mediaType = 'soun', title = Français, default = YES>",
"<AVMediaSelectionKeyValueOption: 0x2839a5b00, language = en, mediaType = 'soun', title = English>"
), allowsEmptySelection = YES>
我深入研究了法语项目(player?.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .audible)?.options.first
)但我还是找不到任何有用的东西。我还试着从 AVPlayer
但没有成功。
即使我使用 AVPlayerViewController
我只看到两个音轨可供选择。
有什么方法可以得到所有可用的音轨?
所以这里的问题实际上是播放列表。如果你查看 HLS 规范,在 Rendition Groups 子项下有一些说明,解释了这个问题。EXT-X-MEDIA
(https:/datatracker.ietf.orgdochtmldraft-pantos-hls-rfc8216bis-07#section-4.4.6.1.1))
一个播放列表可以包含多个相同类型的组,以提供该媒体类型的多种编码。 如果这样做,每个相同类型的组必须有相同的成员集,每个对应的成员必须有相同的属性,但URI和CHANNELS属性除外。
一般来说,思考的方式是,在一个给定的 GROUP-ID
是可以被用户选择的(所以AVFoundation会向你揭示它)。但是哪个 GROUP-ID
是由玩家选择的,(对于这个场景)这是由 AUDIO
的属性 EXT-X-STREAM-INF
播放器所选择的音轨。
如果您希望环绕声轨可以选择,那么它需要存在于相同的 GROUP-ID
如同其他 AUDIO
轨道。如果你没有控制清单,你可以通过重新编写的 GROUP-ID
(使用类似Charles Proxy的东西)的环绕法语音轨,来自于 audio-ec-3
到 audio-mp4a.40.2
之后,它应该出现在AVFoundation中。但要提醒的是,为了使HLS保持有效,必须要有以下条件 CODECS
的所有属性。EXT-X-STREAM-INF
标签必须更新以包括 CODECS
环绕音轨所定义的(否则可能会出现播放失败)。
如果你想让播放器自行选择,而你又没有环绕声英文音轨,你仍然必须在环绕声组中给出英文选项才能保持有效的HLS,但你可以只留下 URI
与立体声组中定义的相同。同样 CODECS
将不得不在这种情况下进行更新。
WWDC的这段视频对所有这些都做了很好的解释(相关部分从42:39左右开始)。https:/developer.apple.comvideosplaywwdc2018502。