Posts

Post not yet marked as solved
0 Replies
405 Views
0 I have a TV app which is used in Fitness industry where 6 smart TVs connected to Apple TVs and the App playing videos from a local server. Unitl tvOS 17.0 everything was smooth but soon after that we are facing a strange issue in that sometimes same Video is playing 6x or more faster than normal rate only in 1 random TV. I can see 12 min video finished playing in 1.3 min. Video Codecs: MPEG-4 AAC, H.264. Is these format affects speed in Apple TV? TVs are initially runs Intro videos, then warm up, then exercise and at last cooldown. I added the code for exercise background timer video where I am facing issue. On top on background video there are other 4 videos playing in loop. Please find attached image. I am using AVPlayer, Swift 5, Xcode 5 and tvOS 17.0, Apple TV 4K. code-block 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 } } }
Posted Last updated
.