以下の質問について注意してください: すべてのアセットはデバイス上でローカルであり、ネットワーク ストリーミングは行われません。ビデオにはオーディオ トラックが含まれます。
私は、問題のビデオ クリップを開始するために、最小限の遅延でビデオ ファイルを再生する必要がある iOS アプリケーションに取り組んでいます。残念ながら、実際に起動するまで、次のビデオ クリップが何であるかはわかりません。具体的には、1 つのビデオ クリップを再生しているとき、次の (およそ) 10 個のビデオ クリップのセットが何であるかはわかりますが、次のクリップを「すぐに」再生するまで、正確にどれであるかはわかりません。
実際の開始遅延を確認するために私が行ったことは、addBoundaryTimeObserverForTimes
ビデオが実際に再生を開始した時間を確認するために 1 ミリ秒の時間間隔でビデオ プレーヤーを呼び出し、そのタイムスタンプと、どのアセットの再生を開始するかを示すコードの最初の場所との差を取得することです。
これまで見てきたことから、AVAsset
読み込み、AVPlayerItem
準備ができたらそれを作成して、AVPlayerStatusReadyToPlay
再生を呼び出す前に待機するという組み合わせを使用すると、クリップの開始に 1 ~ 3 秒かかる傾向があることがわかりました。
それ以来、私はほぼ同等だと思う方法に切り替えました。つまり、呼び出し[AVPlayerItem playerItemWithURL:]
て再生を待つ方法ですAVPlayerItemStatusReadyToPlay
。パフォーマンスはほぼ同じです。
私が観察していることの 1 つは、最初の AVPlayer アイテムの読み込みが他のアイテムよりも遅いことです。最初のビデオを再生する前に、短い / 空のアセットで AVPlayer を事前テストすることが、一般的な良い方法であるように思われます。[サウンドを初めて再生するとき、AVAudioPlayer の起動が遅くなる
ビデオの開始時間をできるだけ短くしたいですし、実験するためのアイデアもいくつかあるのですが、助けてくれる方からのアドバイスもいただければ幸いです。
更新: 以下のアイデア 7 を実装すると、切り替え時間は約 500 ミリ秒になります。これは改善ですが、さらに高速化できればさらに良いでしょう。
アイデア 1: N 個の AVPlayer を使用する (動作しません)
約 10 個のAVPPlayer
オブジェクトを使用して、約 10 個のクリップすべてを開始および一時停止し、実際に必要なものがわかったら、正しい に切り替えて一時停止を解除しAVPlayer
、次のサイクルを最初からやり直します。
iOS ではアクティブなプレイヤーがおよそ 4 人までという制限があると読んだので、これは機能しないと思いますAVPlayer's
。StackOverflow でこれについて質問した人がいて、4 人の AVPlayer 制限について知りました。AVFoundation を使用したビデオ間の高速切り替え
アイデア 2: AVQueuePlayer を使用する (動作しません)
AVPlayerItems
10 個を に押し込めばAVQueuePlayer
、シームレスに開始できるようにすべてが事前に読み込まれるとは思えませんAVQueuePlayer
。 はキューであり、キュー内の次のビデオをすぐに再生できるように準備するだけだと思います。 10 個のビデオのうち、どのビデオを再生したいのかは、そのビデオを開始する時までわかりません。ios-avplayer-ビデオのプリロード
アイデア 3: バックグラウンドで読み込み、再生、保持するAVPlayerItems
(まだ 100% 確実ではありませんが、良さそうです)
各ビデオ クリップの最初の 1 秒をバックグラウンドで読み込んで再生する (ビデオとオーディオの出力を抑制) ことにメリットがあるかどうかを調べています。各 への参照を保持し、AVPlayerItem
実際に再生する必要がある項目がわかったら、その項目を入れ替え、バックグラウンドの AVPlayer をアクティブなものと入れ替えます。これを繰り返します。
理論的には、最近再生された にAVPlayer/AVPlayerItem
は、準備されたリソースがまだいくつか保持されており、後続の再生が速くなる可能性があります。これまでのところ、これによるメリットは確認されていませんが、AVPlayerLayer
バックグラウンドの設定が正しくない可能性があります。私が見た限りでは、これが実際に状況を改善するとは思えません。
アイデア 4: 別のファイル形式を使用する (読み込みが速いものなど)
現在、.m4v (ビデオ MPEG4) の H.264 形式を使用しています。H.264 にはさまざまなコーデック オプションがあるため、一部のオプションでは他のオプションよりもシークが高速になる可能性があります。ファイル サイズを小さくするより高度な設定を使用するとシーク時間が長くなることがわかりましたが、その逆のオプションは見つかりませんでした。
アイデア5: ロスレスビデオフォーマットとAVQueuePlayerの組み合わせ
読み込みは速いがファイル サイズが異常に大きいビデオ形式がある場合、各ビデオ クリップの最初の 10 秒を、サイズは大きいが読み込みが速いバージョンで事前に準備し、それを H.264 でエンコードされたアセットでバックアップするというアイデアがあります。AVQueuePlayer を使用して、最初の 10 秒を非圧縮ファイル形式に追加し、その後に最大 10 秒の準備/事前読み込み時間が得られる H.264 のファイルを追加します。こうすることで、両方の長所、つまり起動時間が速いだけでなく、よりコンパクトな形式のメリットも得られるというメリットが得られます。
アイデア6: 非標準のAVPlayerを使用する/独自のAVPlayerを作成する/他の人のAVPlayerを使用する
私のニーズを考えると、AVPlayer は使えず、AVAssetReader に頼って最初の数秒をデコードし (おそらく raw ファイルをディスクに書き込む)、再生時には raw 形式を使用して高速に再生する必要があるかもしれません。これは私にとっては大規模なプロジェクトのように思えますし、単純な方法で取り組んだ場合、結果が不明確で、改善される可能性も低いでしょう。デコードされて圧縮されていない各ビデオ フレームは 2.25 MB です。単純に言えば、ビデオを ~ 30 fps にすると、ディスクからの読み取り要件が ~60 MB/s になりますが、これはおそらく不可能で無理です。明らかに、ある程度の画像圧縮 (おそらく PVRTC 経由のネイティブ openGL/es 圧縮形式) を行う必要がありますが、それはちょっとおかしいです。使用できるライブラリがあるのでしょうか?
アイデア7: すべてを1つのムービーアセットにまとめ、seekToTime
上記の方法よりも簡単かもしれないアイデアの 1 つは、すべてを 1 つのムービーに結合し、seekToTime を使用することです。問題は、あちこちジャンプすることです。基本的に、ムービーへのランダム アクセスです。これは実際にうまくいくと思います。avplayer ムービー再生の遅延 - iOS5
どのアプローチが最適だと思いますか? 今のところ、ラグを減らすという点ではそれほど進歩していません。
ベストアンサー1
iOS 10.x 以降では、AVPlayer の起動遅延を減らすために、avplayer.automaticallyWaitsToMinimizeStalling = false;
次のように設定しました。これで問題が解決したようです。これにより、他の影響が出る可能性もありますが、まだその影響は出ていません。
このアイデアは以下から得ました:https://stackoverflow.com/a/50598525/9620547