无法从 AVURLAsset 获取 AVPlayer 的 HLS 视频(.m3u8 格式)的视频轨道?

Uma*_*ddi 8 avfoundation avplayer m3u8 swift avkit

我正在开发一个自定义视频播放器来从服务器流式传输 HLS 视频。我可以使用 AVPlayerItem 和 AVPlayer 成功播放 HLS 视频。

之后我想为我的视频播放器添加字幕轨道和音轨。所以我使用 AVMutableComposition 来做到这一点。所以现在的问题是,当我为 HLS 视频创建 AVURLAsset 时,我无法从 AVURLAsset 获取视频轨道。它总是给我 0 个曲目。我尝试了 AVURLAsset 的“loadValuesAsynchronously”,并尝试为 AVPlayerItem 的“轨道”添加 KVO。但这些都没有给我带来任何积极的结果。

我正在使用以下代码。

  func playVideo() {
    let videoAsset = AVURLAsset(url: videoURL!)
    let composition = AVMutableComposition()
    // Video
    let videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
    do {
        let tracks = videoAsset.tracks(withMediaType: .video)
        guard let track = tracks.first else {
            print("Can't get first video track")
            return
        }
        try videoTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: track, at: kCMTimeZero)
    } catch {
        print(error)
        return
    }
    guard let subtitlesUrl = Bundle.main.url(forResource: "en", withExtension: "vtt") else {
        print("Can't load en.vtt from bundle")
        return
    }
    //Subtitles
    let subtitleAsset = AVURLAsset(url: subtitlesUrl)
    let subtitleTrack = composition.addMutableTrack(withMediaType: .text, preferredTrackID: kCMPersistentTrackID_Invalid)
    do {
        let subTracks = subtitleAsset.tracks(withMediaType: AVMediaType.text)
        guard let subTrack = subTracks.first else {
            print("Can't get first subtitles track")
            return
        }
        try subtitleTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: subTrack, at: kCMTimeZero)
    } catch {
        print(error)
        return
    }
    // Prepare item and play it
    let item = AVPlayerItem(asset: composition)
    self.player = AVPlayer(playerItem: item)
    self.playerLayer = AVPlayerLayer.init()
    self.playerLayer.frame = self.bounds
    self.playerLayer.contentsGravity = kCAGravityResizeAspect
    self.playerLayer.player = player
    self.layer.addSublayer(self.playerLayer)
    self.player.addObserver(self, forKeyPath: "currentItem.loadedTimeRanges", options: .new, context: nil)
    self.player.play()
}
Run Code Online (Sandbox Code Playgroud)

此过程适用于 .mp4 视频,但不适用于 HLS 视频 (.m3u8)。有人对此有一些可行的解决方案吗?

或者

我们如何使用 AVURLAsset 从 HLS 视频中获取曲目?如果这是不可能的,那么如何才能达到类似的结果呢?

请让我知道您的反馈。

预先感谢更多。

小智 1

对于 HLS 视频tracks(withMediaType: .video)将返回一个空数组。

使用这个代替:player.currentItem.presentationSize.widthplayer.currentItem.presentationSize.height

请告诉我是否有效。