Я разрабатываю собственный видеоплеер для потоковой передачи HLS-видео с сервера. Я могу успешно воспроизводить HLS-видео с помощью AVPlayerItem и AVPlayer.
После этого я хочу добавить дорожку субтитров и звуковые дорожки для своего видеоплеера. Поэтому я использовал для этого AVMutableComposition. Итак, теперь проблема в том, что когда я создаю AVURLAsset для HLS Videos, я не могу получить видеодорожки из AVURLAsset. Он всегда дает мне 0 треков. Я попробовал "loadValuesAsynchronously" AVURLAsset, и я попытался добавить KVO для "треков" AVPlayerItem. Но ни один из них не дал мне положительного результата.
Я использую следующий код.
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). У кого-нибудь есть рабочее решение для этого?
or
Как мы можем получить треки из HLS-видео с помощью AVURLAsset? Если это невозможно, то как добиться аналогичного результата?
Пожалуйста, дайте мне знать ваш отзыв.
Большое спасибо заранее.