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.
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
}
}
}
Is anyone facing same issues or have a good knowledge of what happening in my case please help.
After I started facing fast forward issue try calling the last line
workoutCircuitPlayer?.playImmediately(atRate: 1.0)
But still I am facing the issue.