如何在iOS客户端上将外部WebVTT字幕添加到HTTP Live Stream中

我们有通过bitmovin.com编码的video,并作为HTTP Live Streams(Fairplay HLS)提供,但是字幕虽然是WebVTT格式,但是作为整个文件的直接URL单独公开,而不是单个段,并且不是HLS m3u8播放列表的一部分。

我正在寻找单独下载的外部.vtt文件如何仍然可以包含在HLS流中并在AVPlayer中作为副标题使用的方式。

我知道Apple的建议是将分段的VTT字幕包含到HLS播放列表中,但我现在无法改变服务器实现,因此我想澄清是否有可能为AVPlayer提供副标题以与HLS流一起播放。

关于这个主题的唯一有效post声称它是可能的: AVPlayer / MPMoviePlayerController的字幕 。 但是,示例代码从bundle加载本地mp4文件,我很难通过AVURLAsset使其适用于m3u8播放列表。 实际上,我有问题从远程m3u8流获取videoTrack,因为asset.tracks(withMediaType: AVMediaTypeVideo)返回空数组。 任何想法,如果这种方法可以用于真正的HLS流? 或者有没有其他方法可以使用HLS流播放单独的WebVTT字幕,而不将它们包含在服务器上的HLS播放列表中? 谢谢。

 func playFpsVideo(with asset: AVURLAsset, at context: UIViewController) { let composition = AVMutableComposition() // Video let videoTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) do { let tracks = asset.tracks(withMediaType: AVMediaTypeVideo) // ==> The code breaks here, tracks is an empty array guard let track = tracks.first else { Log.error("Can't get first video track") return } try videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, asset.duration), of: track, at: kCMTimeZero) } catch { Log.error(error) return } // Subtitle, some test from the bundle.. guard let subsUrl = Bundle.main.url(forResource: "subs", withExtension: "vtt") else { Log.error("Can't load subs.vtt from bundle") return } let subtitleAsset = AVURLAsset(url: subsUrl) let subtitleTrack = composition.addMutableTrack(withMediaType: AVMediaTypeText, preferredTrackID: kCMPersistentTrackID_Invalid) do { let subTracks = subtitleAsset.tracks(withMediaType: AVMediaTypeText) guard let subTrack = subTracks.first else { Log.error("Can't get first subs track") return } try subtitleTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, asset.duration), of: subTrack, at: kCMTimeZero) } catch { Log.error(error) return } // Prepare item and play it let item = AVPlayerItem(asset: composition) let player = AVPlayer(playerItem: item) let playerViewController = AVPlayerViewController() playerViewController.player = player self.playerViewController = playerViewController context.present(playerViewController, animated: true) { playerViewController.player?.play() } }