Home>
[Event]

AVPlayerItem's "presentationSize" changes when a video is played using AVPlayer on a low-speed line (3G). The video is played at the expected size for a moment, but it is quickly crushed.
It does not occur during 4G line or Wifi connection.

The value of "presentationSize" before and after the occurrence of this event.
Before: playerItem.presentationSize: (width = 432, height = 768)
After occurrence: playerItem.presentationSize: (width = 1280, height = 720)

[Source code]
// Code when the event occurred
func setMovie (url: URL) {
    let asset = AVURLAsset (url: url)
    playerItem = AVPlayerItem (asset: asset)
    player = AVPlayer (playerItem: playerItem)
    playerLayer = AVPlayerLayer (player: player)
    playerLayer.videoGravity = AVLayerVideoGravity.resizeAspect
    playerLayer.frame = videoBaseView.frame
    videoBaseView.layer.addSublayer (playerLayer)
    NotificationCenter.default.addObserver (self,
                                           selector: #selector (didPlayToEndTime),
                                           name: .AVPlayerItemDidPlayToEndTime, object: playerItem)
    player.play ()
}


Since it is not possible to put the code of the project as it is, the parts that are not relevant are omitted.
Please let me know if there is a lack of information.

[Try it]

Since it occurs only on a low-speed line, it is considered that it is playing without acquiring the video from the URL, and the video acquisition status is monitored with KVO and changed to play after completion Did.

// KVO additional code
func setMovie (url: URL) {
    let asset = AVURLAsset (url: url)
    playerItem = AVPlayerItem (asset: asset)
    player = AVPlayer (playerItem: playerItem)
    // Set KVO for AVPlayerItem
    playerItem.addObserver (self, forKeyPath: "status", options: [.new, .initial], context: nil)
    NotificationCenter.default.addObserver (self,
                                           selector: #selector (didPlayToEndTime),
                                           name: .AVPlayerItemDidPlayToEndTime, object: playerItem)
    player.play ()
}
// KVO
override func observeValue (forKeyPath keyPath: String ?,
                           of object: Any ?,
                           change: [NSKeyValueChangeKey: Any] ?,
                           context: UnsafeMutableRawPointer?) {
    guard let keyPath = keyPath else {
        return
    }
    if keyPath == "status" {
        let status = playerItem.status
        switch status {
        case .unknown:
            return
        case .readyToPlay:
            do {
                playerLayer = AVPlayerLayer (player: player)
                playerLayer.videoGravity = AVLayerVideoGravity.resizeAspect
                playerLayer.frame = videoContentView.frame
                videoBaseView.layer.addSublayer (playerLayer)
                player.play ()
                }
        case .failed:
            return
        }
    }
}


As expected in the above code, the video could only be played when the status was complete, but the event was not resolved. Is it irrelevant whether the video has been acquired?

Thanks for your solution and advice.