Probleme bei der Videowiedergabe nur unter iOS 13 mit AVPlayerViewController und AVPlayer bei Verwendung von HLS-Video

8

Ich habe eine App, die Videos wiedergibt. Es ist kompatibel mit iOS 11, 12 und iOS 13. Unter iOS 11 und 12 funktioniert die Videowiedergabe wie erwartet entweder nur AVPlayerViewControlleroder nur ordnungsgemäß AVPlayerLayer.

Unter iOS 13 erhielt ich jedoch Berichte, dass plötzlich für einige Benutzer kein Video geladen wurde (oder nur Audio oder nur das erste Bild geladen wurde), als sie iOS aktualisierten. Es fiel mir wirklich schwer, es zu replizieren, aber einige erwähnten, dass es hauptsächlich bei schlechten Netzwerkverbindungen auftrat, und sicher konnte ich es mit Network Link Conditioner reproduzieren.

Dies betrifft insbesondere HLS-Videos (beispielsweise das ausgefallene Livestream-kompatible Video, das Reddit verwendet). Es funktioniert weiterhin gut mit MP4. Hier ist eine Beispiel-URL, die fehlschlägt: https://v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8

Hier ist ein Network Link Conditioner-Profil, das es auslöst: https://i.imgur.com/XWsKUeM.jpg

Hier ist ein Beispielprojekt, das es auslöst und sowohl AVPlayerViewController als auch AVPlayer zeigt (klicken Sie auf Download, Google ist komisch): https://drive.google.com/file/d/1RS5DvUypdOLFCYJe1Pt2Ig0fQljZDLs2/view

Hier ist ein Beispielcode, der dies mit AVPlayerViewController demonstriert:

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()
}

Wenn ich stattdessen genau denselben Code auf einem iOS 12-Gerät versuche, funktioniert er einwandfrei.

Hat jemand Vorschläge, wie man das Problem beheben kann? Wenn Sie zurück zum Anfang schrubben manchmal können Sie das Video wieder richtig zu spielen, aber nicht zuverlässig genug , um so scheinbar eine Lösung aus , dass zu bauen. Video-Sachen sind definitiv nicht meine Stärke in der iOS-Entwicklung, also fange ich an, mich ein wenig am Kopf zu kratzen. Jede Hilfe wäre sehr dankbar.

Hinweis: Ich bin mir ziemlich bewusst, dass dies (wahrscheinlich) ein iOS-Fehler ist und ich werde ein Radar einreichen, aber ich muss mich jetzt noch damit befassen.

christianselig
quelle
Irgendwelche Fortschrittsaktualisierungen ???
Reimond Hill
Wir stehen auch vor dem gleichen Problem. irgendeine Lösungsmöglichkeit?
Moaz Saeed

Antworten:

0

Sie müssen den Status playerItems kvo, um zu wissen, wann er spielbereit ist. Ändern Sie dann im Status "playerItem" den Status "spielbereit" und rufen Sie "player.play" an.

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
quelle