HLSビデオ使用時のAVPlayerViewControllerとAVPlayerを備えたiOS 13でのみビデオ再生の問題


8

動画を再生するアプリがあります。iOS 11、12、およびiOS 13と互換性があります。iOS11および12では、どちらか、AVPlayerViewControllerまたはを使用しても、ビデオ再生は正常に機能しますAVPlayerLayer

しかし、iOS 13では、iOSを更新したときにかなりの数のユーザーに対して突然ビデオが読み込まれなかった(またはオーディオのみが読み込まれる、または最初のフレームのみが読み込まれる)というレポートが届き始めました。私はそれを複製するのに本当に苦労しましたが、一部はネットワークの接続不良が原因で発生したと述べ、ネットワークリンクコンディショナーでそれを再現することができたと確信しています。

これは特にHLSビデオに影響します(たとえば、Redditが使用するファンシーライブストリーム互換のもの)。MP4でも問題なく動作します。失敗したURLの例を次に示します。https//v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8

これをトリガーするネットワークリンクコンディショナープロファイルは次のとおりです。https//i.imgur.com/XWsKUeM.jpg

これをトリガーするサンプルプロジェクトは、AVPlayerViewControllerとAVPlayerの両方を示しています(ダウンロードがヒットし、Googleは奇妙です):https ://drive.google.com/file/d/1RS5DvUypdOLFCYJe1Pt2Ig0fQljZDLs2/view

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

iOS 12デバイスでまったく同じコードを試すと、完全に機能します。

誰かがそれを修正する方法について何か提案がありますか?先頭にスクラブすると、ビデオを適切に再生できる場合がありますが、一見してソリューションを構築できるほどの信頼性はありません。iOSの開発では、ビデオに関するものは間違いなく私の強みではないので、少し頭を悩ませ始めています。ご協力いただければ幸いです。

注:これはiOSのバグである可能性が高いことを十分に認識しており、レーダーを提出しますが、今でも対処する必要があります。


進行状況の更新はありますか?
レイモンドヒル

私たちも同じ問題に直面しています。解決策はありますか?
Moaz Saeed

回答:


0

いつ再生できるかを知るには、playerItemsステータスをkvoする必要があります。次に、playerItemステータスが再生可能に変更されたら、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.
        }
    }
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.