AVPlayer воспроизводит видео в 6 раз или более быстрее обычной скорости
У меня есть телевизионное приложение, которое используется в фитнес-индустрии, где 6 смарт-телевизоров подключены к Apple TV, и приложение воспроизводит видео с локального сервера. В Unitl tvOS 17.0 все было гладко, но вскоре после этого мы столкнулись со странной проблемой: иногда одно и то же видео воспроизводится в 6 раз или более быстрее обычной скорости только на одном случайном телевизоре. Я вижу, что 12-минутное видео воспроизводится через 1,3 минуты.
Видеокодеки: MPEG-4 AAC, H.264. Влияет ли этот формат на скорость Apple TV?
На телевизорах сначала показываются вступительные видеоролики, затем разминка, затем упражнения и, наконец, охлаждение. Я добавил код для видео с фоновым таймером упражнений, где у меня возникла проблема. Поверх фонового видео циклически воспроизводятся еще 4 видео. Пожалуйста, найдите прикрепленное изображение. Я использую AVPlayer, Swift 5, Xcode 5 и tvOS 17.0, Apple TV 4K.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var workoutCircuitContainerView: UIView!
var workoutCircuitPlayerItem: AVPlayerItem?
var workoutCircuitPlayerLayer: AVPlayerLayer?
var workoutCircuitPlayer: AVPlayer?
var isWorkoutCircuitPlayerObserverAdded: Bool = false
private var workoutCircuitObserverContext = 0
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
initializeWorkoutCircuitPlayer()
}
func initializeWorkoutCircuitPlayer() {
workoutCircuitPlayer?.pause()
workoutCircuitPlayerLayer?.removeFromSuperlayer()
self.removeWorkoutCircuitPlayerObservers()
startWorkoutCircuitPlayer()
}
func startWorkoutCircuitPlayer() {
guard let streamURL = URL(string: "http://192.168.1.116:3001/videos/CARDIO_Work_Circuit1.mp4") else {
return
}
self.workoutCircuitPlayerItem = AVPlayerItem(url: streamURL as URL)
self.workoutCircuitPlayer = AVPlayer(playerItem: self.workoutCircuitPlayerItem)
self.workoutCircuitPlayerLayer = AVPlayerLayer(player: self.workoutCircuitPlayer!)
self.workoutCircuitPlayerLayer!.videoGravity = AVLayerVideoGravity(rawValue: AVLayerVideoGravity.resizeAspectFill.rawValue)
self.workoutCircuitPlayerLayer!.frame = self.workoutCircuitContainerView.bounds
self.workoutCircuitContainerView.layer.addSublayer(self.workoutCircuitPlayerLayer!)
self.workoutCircuitPlayer!.addObserver(self, forKeyPath: "timeControlStatus", options: [.old, .new], context: nil)
self.playWorkoutCircuitPlayer()
self.addWorkoutCircuitPlayerObservers()
}
func playWorkoutCircuitPlayer() {
workoutCircuitPlayer?.play()
}
func addWorkoutCircuitPlayerObservers() {
if !isWorkoutCircuitPlayerObserverAdded {
workoutCircuitPlayer?.addObserver(self,
forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &workoutCircuitObserverContext)
NotificationCenter.default.addObserver(self, selector: #selector(self.workoutCircuitPlayerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: workoutCircuitPlayer?.currentItem)
NotificationCenter.default.addObserver(self, selector: #selector(self.workoutCircuitPlayerStalled(note:)), name: .AVPlayerItemPlaybackStalled, object: self.workoutCircuitPlayer?.currentItem)
isWorkoutCircuitPlayerObserverAdded = true
}
}
@objc func workoutCircuitPlayerDidFinishPlaying(notification: NSNotification) {
// play cool down videos code
}
@objc func workoutCircuitPlayerStalled(note: NSNotification) {
if let playerItem = note.object as? AVPlayerItem {
playerItem.seek(to: (workoutCircuitPlayer?.currentTime())!, completionHandler: nil)
self.workoutCircuitPlayer!.play()
}
}
func removeWorkoutCircuitPlayerObservers() {
if isWorkoutCircuitPlayerObserverAdded {
workoutCircuitPlayer?.removeObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), context: &workoutCircuitObserverContext)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: workoutCircuitPlayer?.currentItem)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemPlaybackStalled, object: workoutCircuitPlayer?.currentItem)
isWorkoutCircuitPlayerObserverAdded = false
}
}
}
Кто-нибудь сталкивается с такими же проблемами или хорошо знает, что происходит в моем случае, пожалуйста, помогите.
После того, как я начал сталкиваться с проблемой быстрой перемотки вперед, попробуйте позвонить на последнюю строку.
workoutCircuitPlayer?.playImmediately(atRate: 1.0)
Но все же я столкнулся с этой проблемой.