我正在开发一个自定义视频播放器,以从服务器流式传输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视频中获取曲目?如果这不可能,那么如何获得类似的结果?
请让我知道您的反馈意见。
非常感谢。
答案 0 :(得分:-1)
对于HLS视频,tracks(withMediaType: .video)
将返回一个空数组。
改用player.currentItem.presentationSize.width
和player.currentItem.presentationSize.height
。
请让我知道它是否有效。