Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pause, Seeking and Seeked events are not emitted when using Airplay mode with the Apple TV remote #446

Open
6 tasks done
nidhik opened this issue Nov 5, 2021 · 0 comments

Comments

@nidhik
Copy link

nidhik commented Nov 5, 2021

Pause, Seeking and Seeked events are not emitted when using Airplay mode with the Apple TV remote

Steps to reproduce:

In our app we have a simple Kaltura Playkit player with a pause/play button, a slider and a MPVolumeView to airplay when available.

  1. Choose airplay to apple tv
  2. Start playing the video
  3. Pause and play again with the apple tv remote controller
  4. Seek with the apple tv remote controller

Result: The pause, seeking and seeked events are never emitted. When the player is paused on the Apple TV, the controllers on the device (iPhone) still look as if it is playing because it's not on paused state.

Expected result: Pause, play, seeking and seeked events are emitted even when interacting with the Apple TV remote controller in airplay mode. The controllers in the device always match the state in the Apple TV

Prerequisites
  • Have you checked for duplicate issues: Yes, there are no duplicates for this issue.
  • Which Player version are you using: 3.21
  • Can you reproduce the issue with our latest release version: Yes
  • Can you reproduce the issue with the latest code from master: Yes
  • What devices and OS versions are you using: iPhone Xs iOS 14.4.2
  • If applicable, add test code or test page to reproduce:
import UIKit
import PlayKit
import MUXSDKKaltura
import MuxCore
import MediaPlayer

class PlayerViewController: UIViewController {
    var kalturaPlayer: Player?
    let kalturaPlayerContainer = PlayerView()
    let playButton = UIButton()
    let closeButton = UIButton()
    let playheadSlider = UISlider()
    let positionLabel = UILabel()
    let durationLabel = UILabel()
    let airplayButton = MPVolumeView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
    
    // MUX
    let playerName = "iOS KalturaPlayer"
    
    private var playerState: PlayerState = .idle {
        didSet {
            // Update player button icon depending on the state
            switch playerState {
            case .idle:
                self.playButton.setImage(UIImage(systemName: "play"), for: .normal)
            case .playing:
                self.playButton.setImage(UIImage(systemName: "pause"), for: .normal)
            case .paused:
                self.playButton.setImage(UIImage(systemName: "play"), for: .normal)
            case .ended:
                self.playButton.setImage(UIImage(systemName: "arrow.clockwise"), for: .normal)
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.setupLayout()
        
        // Load PlayKit player
        self.kalturaPlayer = PlayKitManager.shared.loadPlayer(pluginConfig: nil)
        self.setupKalturaPlayer()
        
        // Setup MUX
        self.setupMUX()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        MUXSDKStats.destroyPlayer(name: self.playerName)
        self.kalturaPlayer?.destroy()
    }
    
    func setupKalturaPlayer() {
        // Set PlayerView as the container for PlayKit Player variable
        self.kalturaPlayer?.view = self.kalturaPlayerContainer
        self.loadMediaKalturaPlayer()
        
        
        // Handle PlayKit events
        self.playerState = .idle
        let events = [
            PlayerEvent.pause,
            PlayerEvent.playing,
            PlayerEvent.ended,
            PlayerEvent.durationChanged
        ]
        
        // Update player state depending on the Playkit events
        self.kalturaPlayer?.addObserver(self, events: events) { [weak self] (event) in
            guard let self = self else { return }

            switch event {
            case is PlayerEvent.Playing:
                self.playerState = .playing
            case is PlayerEvent.Pause:
                self.playerState = .paused
            case is PlayerEvent.Ended:
                self.playerState = .ended
                // Test video change
                self.changeMediaKalturaPlayer()
            case is PlayerEvent.DurationChanged:
                // Observe PlayKit event durationChanged to update the maximum duration of the slider and duration label
                guard let duration = event.duration as? TimeInterval else {
                    return
                }
                
                self.playheadSlider.maximumValue = Float(duration)
                self.durationLabel.text = duration.formattedTimeDisplay
            default:
                break
            }
        }
        
        // Checks media progress to update the player slider and the current position label
        _ = self.kalturaPlayer?.addPeriodicObserver(
            interval: 0.2,
            observeOn: DispatchQueue.main,
            using: { [weak self] currentPosition in
                self?.playheadSlider.value = Float(currentPosition)
                self?.positionLabel.text = currentPosition.formattedTimeDisplay
            }
        )
    }
    
    func loadMediaKalturaPlayer() {
        let mediaConfig = createKalturaMediaConfig(
            contentURL: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8",
            entryId: "sintel"
        )
        
        // Prepare PlayKit player
        self.kalturaPlayer?.prepare(mediaConfig)
    }
    
    func changeMediaKalturaPlayer() {
        let mediaConfig = createKalturaMediaConfig(
            contentURL: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8",
            entryId: "bipbop_16x9"
        )
        
        // Call MUX videoChange before stop, because playkit stop will replace current item for nil
        self.MUXVideoChange()
        
        // Resets The Player And Prepares for Change Media
        self.kalturaPlayer?.stop()
        
        // Prepare PlayKit player
        self.kalturaPlayer?.prepare(mediaConfig)
        
        // Wait for `canPlay` event to play
        self.kalturaPlayer?.addObserver(self, events: [PlayerEvent.canPlay]) { event in
            self.kalturaPlayer?.play()
        }
    }
    
    func createKalturaMediaConfig(contentURL: String, entryId: String) -> MediaConfig {
        // Create PlayKit media source
        let source = PKMediaSource(entryId, contentUrl: URL(string: contentURL), drmData: nil, mediaFormat: .hls)
        
        // Setup PlayKit media entry
        let mediaEntry = PKMediaEntry(entryId, sources: [source])
        
        // Create PlayKit media config
        return MediaConfig(mediaEntry: mediaEntry)
    }
    
    func setupMUX() {
        let playerData = MUXSDKCustomerPlayerData(environmentKey: "YOUR_ENV_KEY_HERE")
        playerData?.playerName = self.playerName
        
        let videoData = MUXSDKCustomerVideoData()
        videoData.videoTitle = "Title Video Kaltura"
        videoData.videoId = "sintel"
        videoData.videoSeries = "animation"
        
        let viewData = MUXSDKCustomerViewData()
        viewData.viewSessionId = "my session id"
        
        let customData = MUXSDKCustomData()
        customData.customData1 = "Kaltura test"
        customData.customData2 = "Custom Data 2"
        
        let viewerData = MUXSDKCustomerViewerData()
        viewerData.viewerApplicationName = "MUX Kaltura DemoApp"
        
        let customerData = MUXSDKCustomerData(
            customerPlayerData: playerData,
            videoData: videoData,
            viewData: viewData,
            customData: customData,
            viewerData: viewerData
        )
        
        guard let player = self.kalturaPlayer, let data = customerData else {
            return
        }
        
        MUXSDKStats.monitorPlayer(
            player: player,
            playerName: self.playerName,
            customerData: data
        )
    }
    
    func MUXVideoChange() {
        let playerData = MUXSDKCustomerPlayerData(environmentKey: "shqcbkagevf0r4jh9joir48kp")
        playerData?.playerName = self.playerName
        
        let videoData = MUXSDKCustomerVideoData()
        videoData.videoTitle = "Apple Video Kaltura"
        videoData.videoId = "apple"
        videoData.videoSeries = "conference"
        
        let viewData = MUXSDKCustomerViewData()
        viewData.viewSessionId = "my second session id"
        
        let customData = MUXSDKCustomData()
        customData.customData1 = "Kaltura test video change"
        
        let viewerData = MUXSDKCustomerViewerData()
        viewerData.viewerApplicationName = "MUX Kaltura DemoApp"
        
        guard let customerData = MUXSDKCustomerData(
            customerPlayerData: playerData,
            videoData: videoData,
            viewData: viewData,
            customData: customData,
            viewerData: viewerData
        ) else {
            return
        }
        
        MUXSDKStats.videoChangeForPlayer(name: self.playerName, customerData: customerData)
    }
    
    @objc func playButtonPressed() {
        guard let player = self.kalturaPlayer else {
            return
        }
        
        // Handle PlayKit events
        switch playerState {
        case .playing:
            player.pause()
        case .idle:
            player.play()
        case .paused:
            player.play()
        case .ended:
            player.seek(to: 0)
            player.play()
        }
    }
    
    @objc func closeButtonPressed() {
        self.navigationController?.popToRootViewController(animated: true)
    }
    
    @objc func playheadValueChanged() {
        guard let player = self.kalturaPlayer else {
            return
        }
        
        if self.playerState == .ended && self.playheadSlider.value < self.playheadSlider.maximumValue {
            self.playerState = .paused
        }
        
        player.currentTime = TimeInterval(self.playheadSlider.value)
    }
}

extension PlayerViewController {
    enum PlayerState {
        case idle
        case playing
        case paused
        case ended
    }
}

extension PlayerViewController {
    func setupLayout() {
        self.view.backgroundColor = .black
        self.view.addSubview(self.kalturaPlayerContainer)
        
        // Constraint PlayKit player container to safe area layout guide
        self.kalturaPlayerContainer.translatesAutoresizingMaskIntoConstraints = false
        let guide = self.view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            self.kalturaPlayerContainer.topAnchor.constraint(equalTo: guide.topAnchor),
            self.kalturaPlayerContainer.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
            self.kalturaPlayerContainer.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
            self.kalturaPlayerContainer.trailingAnchor.constraint(equalTo: guide.trailingAnchor)
        ])
        
        let actionsContainer = UIStackView()
        actionsContainer.axis = .vertical
        actionsContainer.isLayoutMarginsRelativeArrangement = true
        actionsContainer.layoutMargins = UIEdgeInsets(top: 0, left: 8.0, bottom: 0, right: 8.0)
        actionsContainer.translatesAutoresizingMaskIntoConstraints = false
        self.kalturaPlayerContainer.addSubview(actionsContainer)
        NSLayoutConstraint.activate([
            actionsContainer.bottomAnchor.constraint(equalTo: self.kalturaPlayerContainer.bottomAnchor),
            actionsContainer.leadingAnchor.constraint(equalTo: self.kalturaPlayerContainer.leadingAnchor),
            actionsContainer.trailingAnchor.constraint(equalTo: self.kalturaPlayerContainer.trailingAnchor)
        ])
        
        // Add airplay button
        self.airplayButton.showsVolumeSlider = false
        NSLayoutConstraint.activate([
            self.airplayButton.widthAnchor.constraint(equalToConstant: 44.0),
            self.airplayButton.heightAnchor.constraint(equalToConstant: 44.0)
        ])
        
        let airplayRowStack = UIStackView()
        airplayRowStack.axis = .horizontal
        airplayRowStack.addArrangedSubview(UIView())
        airplayRowStack.addArrangedSubview(airplayButton)
        actionsContainer.addArrangedSubview(airplayRowStack)
        
        let actionsRowStack = UIStackView()
        actionsRowStack.axis = .horizontal
        actionsRowStack.spacing = 6.0
        actionsContainer.addArrangedSubview(actionsRowStack)
        NSLayoutConstraint.activate([
            actionsRowStack.heightAnchor.constraint(equalToConstant: 44.0)
        ])
        
        // Add play/pause button
        self.playButton.addTarget(self, action: #selector(self.playButtonPressed), for: .touchUpInside)
        self.playButton.contentEdgeInsets = UIEdgeInsets(top: 10, left: 4, bottom: 10, right: 4)
        self.playButton.contentHorizontalAlignment = .fill
        self.playButton.contentVerticalAlignment = .fill
        actionsRowStack.addArrangedSubview(self.playButton)
        NSLayoutConstraint.activate([
            self.playButton.widthAnchor.constraint(equalToConstant: 28.0)
        ])
        
        self.positionLabel.textColor = .lightText
        self.positionLabel.text = TimeInterval.zero.formattedTimeDisplay
        actionsRowStack.addArrangedSubview(self.positionLabel)
        
        self.playheadSlider.addTarget(self, action: #selector(self.playheadValueChanged), for: .valueChanged)
        actionsRowStack.addArrangedSubview(self.playheadSlider)
        
        self.durationLabel.textColor = .lightText
        self.durationLabel.text = TimeInterval.zero.formattedTimeDisplay
        actionsRowStack.addArrangedSubview(self.durationLabel)
        
        // Add close button
        self.closeButton.translatesAutoresizingMaskIntoConstraints = false
        self.closeButton.addTarget(self, action: #selector(self.closeButtonPressed), for: .touchUpInside)
        self.closeButton.setImage(UIImage(systemName: "xmark.square"), for: .normal)
        self.closeButton.contentVerticalAlignment = .fill
        self.closeButton.contentHorizontalAlignment = .fill
        self.kalturaPlayerContainer.addSubview(self.closeButton)
        NSLayoutConstraint.activate([
            self.closeButton.heightAnchor.constraint(equalToConstant: 32.0),
            self.closeButton.widthAnchor.constraint(equalToConstant: 32.0),
            self.closeButton.trailingAnchor.constraint(equalTo: self.kalturaPlayerContainer.trailingAnchor, constant: -24.0),
            self.closeButton.topAnchor.constraint(equalTo: self.kalturaPlayerContainer.topAnchor, constant: 24.0)
        ])
    }
}
Expected behavior

It's a simple kaltura playkit player with the button to airplay. I reproduce in airplay mode, when I pause or seek with the apple tv remote, I get kaltura PlayEvents for Pause, Seeking and Seeked. The UI in the device is in sync with the apple tv player, for example:if it is pause it shows the play button and viceversa.

Actual behavior

I reproduce in airplay mode, when I pause or seek with the apple tv remote, I don't get any of the following kaltura PlayEvents: Pause, Seeking and Seeked. The UI in the device is not in sync with the apple tv player, for example: if it is paused in apple tv it still shows the pause button on the device, even though it should be showing the play button instead.

Console output
2021-11-05 2:06:04.139 PM [Debug] [DefaultAssetHandler.swift:88] build(from:readyCallback:) > Creating clear AVURLAsset
2021-11-05 2:06:04.178 PM [Debug] [AVPlayerEngine.swift:147] startPosition > set startPosition: nan
2021-11-05 2:06:04.179 PM [Debug] [AVPlayerEngine.swift:76] asset > The asset status changed to: preparing
2021-11-05 2:06:04.179 PM [Debug] [NetworkUtils.swift:57] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Sending Kava Event type: 1
2021-11-05 2:06:04.180 PM [Debug] [NetworkUtils.swift:57] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Sending Kava Event type: 2
2021-11-05 2:06:04.181 PM [Debug] [PlayerController+TimeMonitor.swift:16] addPeriodicObserver(interval:observeOn:using:) > add periodic observer with interval: 0.2, on queue: Optional(<OS_dispatch_queue_main: com.apple.main-thread[0x105668c80] = { xref = -2147483648, ref = -2147483648, sref = 1, target = com.apple.root.default-qos.overcommit[0x105669100], width = 0x1, state = 0x001ffe9000000300, dirty, in-flight = 0, thread = 0x303 }>)
2021-11-05 2:06:04.181 PM [Debug] [PlayerController+TimeMonitor.swift:18] addPeriodicObserver(interval:observeOn:using:) > periodic observer added with token: 6503F1FF-68E4-4E8C-9011-DAD6B36BDE6E
2021-11-05 2:06:04.184 PM [Debug] [PlayerController+TimeMonitor.swift:16] addPeriodicObserver(interval:observeOn:using:) > add periodic observer with interval: 0.1, on queue: nil
2021-11-05 2:06:04.184 PM [Debug] [PlayerController+TimeMonitor.swift:18] addPeriodicObserver(interval:observeOn:using:) > periodic observer added with token: 1AE02AF5-F7F5-484C-A19A-1A94BF991B47
2021-11-05 2:06:04.287 PM [Debug] [AVPlayerEngine.swift:76] asset > The asset status changed to: prepared
2021-11-05 2:06:04.288 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
2021-11-05 2:06:04.288 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Idle old:Idle
2021-11-05 2:06:04.288 PM [Error] [AVPlayerEngine+Observation.swift:176] observeValue(forKeyPath:of:change:context:) > unknown player item status
2021-11-05 2:06:04.289 PM [Debug] [AVPlayerEngine+Observation.swift:365] handleDurationChanged() > Duration in seconds: 888.0
2021-11-05 2:06:04.289 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Buffering old:Idle
2021-11-05 2:06:04.289 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Idle old:Buffering
2021-11-05 2:06:04.303 PM [Debug] [AVPlayerEngine+Observation.swift:236] handle(status:) > player is ready to play player items
2021-11-05 2:06:04.303 PM [Debug] [AVPlayerEngine+Observation.swift:239] handle(status:) > duration in seconds: 888.0
2021-11-05 2:06:04.402 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:06:04.430 PM [Debug] [AVPlayerEngine+Observation.swift:75] onAccessLogEntryNotification(notification:) > event log:
 event log: averageAudioBitrate - 378256.0
 event log: averageVideoBitrate - 0.0
 event log: indicatedAverageBitrate - -1.0
 event log: indicatedBitrate - 6214307.0
 event log: observedBitrate - nan
 event log: observedMaxBitrate - 0.0
 event log: observedMinBitrate - -1.0
 event log: switchBitrate - -1.0
 event log: numberOfBytesTransferred - 94564
 event log: numberOfStalls - 0
 event log: URI - 'https://bitdash-a.akamaihd.net/content/sintel/hls/video/6000kbit.m3u8'
 event log: startupTime - -1.0
2021-11-05 2:06:04.543 PM [Warning] [AVPlayerEngine+Observation.swift:91] onErrorLogEntryNotification(notification:) > error description: Optional("Segment exceeds specified bandwidth for variant"), error domain: CoreMediaErrorDomain, error code: -12318
2021-11-05 2:06:04.555 PM [Debug] [AVPlayerEngine+Observation.swift:365] handleDurationChanged() > Duration in seconds: 888.0
2021-11-05 2:06:04.556 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Idle
2021-11-05 2:06:04.562 PM [Debug] [TracksManager.swift:38] handleTracks(item:cea608CaptionsEnabled:block:) > audio tracks:: Optional([<PlayKit.Track: 0x28057a540>, <PlayKit.Track: 0x28057a600>]), text tracks:: Optional([<PlayKit.Track: 0x28057aa80>, <PlayKit.Track: 0x28057a7c0>, <PlayKit.Track: 0x28057a840>, <PlayKit.Track: 0x28057a900>, <PlayKit.Track: 0x28057aa00>])
2021-11-05 2:06:04.562 PM [Debug] [AVPlayerEngine+Observation.swift:274] handle(playerItemStatus:) > duration in seconds: 888.0
2021-11-05 2:06:04.562 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Ready
2021-11-05 2:06:04.954 PM [Debug] [NetworkUtils.swift:55] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Response:
Status Code: 0
Error: 
Data: {
    time = "1636142765.009";
    viewEventsEnabled = 1;
}
2021-11-05 2:06:05.371 PM [Debug] [NetworkUtils.swift:55] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Response:
Status Code: 0
Error: 
Data: {
    time = "1636142765.427";
    viewEventsEnabled = 1;
}
2021-11-05 2:06:07.092 PM [Debug] [AVPlayerEngine.swift:294] play() > Play player
2021-11-05 2:06:07.092 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 1.0
2021-11-05 2:06:08.000 PM [Debug] [AVPlayerEngine+Observation.swift:75] onAccessLogEntryNotification(notification:) > event log:
 event log: averageAudioBitrate - 0.0
 event log: averageVideoBitrate - 41360.0
 event log: indicatedAverageBitrate - -1.0
 event log: indicatedBitrate - 1558322.0
 event log: observedBitrate - 32336999.91437678
 event log: observedMaxBitrate - 94714957.2420789
 event log: observedMinBitrate - 2296042.501051438
 event log: switchBitrate - -1.0
 event log: numberOfBytesTransferred - 10340
 event log: numberOfStalls - 0
 event log: URI - 'https://bitdash-a.akamaihd.net/content/sintel/hls/video/1500kbit.m3u8'
 event log: startupTime - 0.0
MUXSDK-INFO - Switch advertised bitrate from: 6214307.0 to: 1558322.0
2021-11-05 2:06:08.018 PM [Warning] [AVPlayerEngine+Observation.swift:91] onErrorLogEntryNotification(notification:) > error description: Optional("Segment exceeds specified bandwidth for variant"), error domain: CoreMediaErrorDomain, error code: -12318
2021-11-05 2:06:11.296 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Ready
2021-11-05 2:06:24.329 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:06:33.309 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:03.311 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:05.396 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:07.314 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:09.319 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:11.312 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:13.312 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:17.036 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
2021-11-05 2:07:17.312 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:34.309 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Buffering old:Ready
2021-11-05 2:07:34.646 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 8.0
2021-11-05 2:07:35.607 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 24.0
2021-11-05 2:07:40.318 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
2021-11-05 2:07:42.236 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 1.0
2021-11-05 2:07:42.236 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Buffering
2021-11-05 2:07:55.237 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:08:01.814 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
@nidhik nidhik changed the title Pause, Seeking and Seeked events are not emitted when using Airplay mode with the Apple TV remote controller Pause, Seeking and Seeked events are not emitted when using Airplay mode with the Apple TV remote Nov 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant