Problemas de reproducción de video solo en iOS 13 con AVPlayerViewController y AVPlayer cuando se usa video HLS

9

Tengo una aplicación que reproduce videos. Es compatible con iOS 11, 12 e iOS 13. En iOS 11 y 12, la reproducción de video funciona correctamente como se esperaba usando cualquiera AVPlayerViewControllero incluso solo AVPlayerLayer.

Sin embargo, en iOS 13 comencé a recibir informes de que de repente el video no se cargaba (o solo cargaba audio, o solo el primer fotograma) para bastantes usuarios cuando actualizaban iOS. Me costó mucho replicarlo, pero algunos mencionaron que ocurrió principalmente con conexiones de red deficientes y, efectivamente, con Network Link Conditioner pude reproducirlo.

Afecta específicamente al video HLS (el elegante compatible con transmisión en vivo que utiliza Reddit, por ejemplo). Sigue funcionando bien con MP4. Aquí hay un ejemplo de URL que falla: https://v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8

Aquí hay un perfil de Network Link Conditioner que lo activa: https://i.imgur.com/XWsKUeM.jpg

Aquí hay un proyecto de muestra que lo desencadena, mostrando AVPlayerViewController y AVPlayer (presione Descargar, Google está siendo extraño): https://drive.google.com/file/d/1RS5DvUypdOLFCYJe1Pt2Ig0fQljZDLs2/view

Aquí hay un código de muestra que lo muestra con AVPlayerViewController:

let assetURL = URL(string: "https://v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8")!

// The following MP4 URL *does* work, for instance
// let assetURL = URL(string: "https://giant.gfycat.com/DependentFreshKissingbug.mp4")!

let player = AVPlayer(url: assetURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player

self.present(playerViewController, animated: true) {
    playerViewController.player!.play()
}

Si intento ese mismo código exacto en un dispositivo iOS 12, funciona perfectamente.

¿Alguien tiene alguna sugerencia sobre cómo solucionarlo? Si retrocede hasta el principio, a veces puede hacer que el video se reproduzca correctamente, pero no lo suficientemente confiable como para aparentemente construir una solución a partir de eso. Las cosas de video definitivamente no son mi fuerte en el desarrollo de iOS, así que estoy empezando a rascarme la cabeza un poco, cualquier ayuda sería muy apreciada.

Nota: Soy bastante consciente de que es (probablemente) un error de iOS y presentaré un Radar, pero todavía tengo que lidiar con eso ahora.

christianselig
fuente
¿Alguna actualización de progreso?
Reimond Hill
También nos enfrentamos al mismo problema. ¿alguna solución?
Moaz Saeed
@christianselig - mejor archivo de un error
sia

Respuestas:

1

Debe saber el estado de los artículos del jugador para saber cuándo está listo para jugar. Luego, en el reproductor, el estado del elemento cambia a listo para jugar, llama a tu player.play.

playerItem.addObserver(self,
                           forKeyPath: #keyPath(AVPlayerItem.status),
                           options: [.old, .new],
                           context: &playerItemContext)


override func observeValue(forKeyPath keyPath: String?,
                           of object: Any?,
                           change: [NSKeyValueChangeKey : Any]?,
                           context: UnsafeMutableRawPointer?) {

    // Only handle observations for the playerItemContext
    guard context == &playerItemContext else {
        super.observeValue(forKeyPath: keyPath,
                           of: object,
                           change: change,
                           context: context)
        return
    }

    if keyPath == #keyPath(AVPlayerItem.status) {
        let status: AVPlayerItemStatus
        if let statusNumber = change?[.newKey] as? NSNumber {
            status = AVPlayerItemStatus(rawValue: statusNumber.intValue)!
        } else {
            status = .unknown
        }

        // Switch over status value
        switch status {
        case .readyToPlay:
            // Player item is ready to play.
        case .failed:
            // Player item failed. See error.
        case .unknown:
            // Player item is not yet ready.
        }
    }
}


Lunarchaos42
fuente