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

时间:2018-09-19 15:44:47

标签: swift avfoundation avplayer m3u8 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()
}

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

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

请让我知道您的反馈意见。

非常感谢。

1 个答案:

答案 0 :(得分:-1)

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

改用player.currentItem.presentationSize.widthplayer.currentItem.presentationSize.height

请让我知道它是否有效。