我正在开发一个自定义视频播放器,用于从服务器流式传输HLS视频。我可以使用AVPlayerItem和AVPlayer成功播放HLS视频。
接下来,我想为我的视频播放器添加字幕轨道和音频轨道,因此我使用了AVMutableComposition。现在问题是,当我为HLS视频创建AVURLAsset时,无法从AVURLAsset获取视频轨道。它总是给我0个轨道。我尝试过AVURLAsset的“loadValuesAsynchronously”以及为AVPlayerItem的“tracks”添加KVO,但这些都没有给我任何积极的结果。
我正在使用以下代码:
这个方法对于.mp4视频有效,但不适用于HLS视频(.m3u8)。有没有一些可行的解决方案?
或者
如何使用AVURLAsset从HLS视频中获取轨道?如果这不可能,那么如何实现类似的结果?
请告知您的反馈。
非常感谢。
接下来,我想为我的视频播放器添加字幕轨道和音频轨道,因此我使用了AVMutableComposition。现在问题是,当我为HLS视频创建AVURLAsset时,无法从AVURLAsset获取视频轨道。它总是给我0个轨道。我尝试过AVURLAsset的“loadValuesAsynchronously”以及为AVPlayerItem的“tracks”添加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视频中获取轨道?如果这不可能,那么如何实现类似的结果?
请告知您的反馈。
非常感谢。