AVPlayer playing video 6x or more faster than normal rate

56 views Asked by At

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.enter image description here 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.

0

There are 0 answers