以下の質問に注意してください: すべてのアセットはデバイス上でローカルです。ネットワーク ストリーミングは行われていません。動画には音声トラックが含まれています。
問題のビデオ クリップを開始するために最小限の遅延でビデオ ファイルを再生する必要がある iOS アプリケーションに取り組んでいます。残念ながら、実際に開始する必要があるまで、次の特定のビデオ クリップが何であるかはわかりません。具体的には: 1 つのビデオ クリップが再生されているとき、次の (およそ) 10 個のビデオ クリップのセットが何であるかはわかりますが、次のクリップを「すぐに」再生するときが来るまで、正確にどれがどれかはわかりません。
実際の開始遅延を確認するために私が行ったことはaddBoundaryTimeObserverForTimes
、ビデオ プレーヤーを呼び出して、ビデオが実際に再生を開始した時刻を 1 ミリ秒で確認することです。再生を開始するアセットを示すコード。
これまで見てきたことから、AVAsset
読み込みの組み合わせを使用し、AVPlayerItem
準備ができたらそれから作成し、play を呼び出す前に待機するとAVPlayerStatusReadyToPlay
、開始に 1 ~ 3 秒かかる傾向があることがわかりました。クリップ。
それ以来、私はほぼ同等だと思うものに切り替えました: 呼び出し[AVPlayerItem playerItemWithURL:]
て、再生を待ちAVPlayerItemStatusReadyToPlay
ます。ほぼ同じ性能。
私が観察していることの 1 つは、最初の AVPlayer アイテムの読み込みが残りよりも遅いことです。最初のビデオを再生しようとする前に、短い/空のアセットで AVPlayer をプリフライトすることは、一般的には良い方法かもしれません。[初めてサウンドを再生するときの AVAudioPlayer のスロー スタート
ビデオの開始時間をできるだけ短くしたいと思っています。また、実験するアイデアがいくつかありますが、役立つ可能性のある人からのガイダンスが必要です.
更新: 以下のアイデア 7 では、実装されたままの状態で、約 500 ミリ秒の切り替え時間が得られます。これは改善ですが、これをさらに高速化するとよいでしょう。
アイデア 1: N 個の AVPlayer を使用する (機能しない)
10 個までのオブジェクトを使用し、10AVPPlayer
個までのすべてのクリップを開始して一時停止し、本当に必要なものがわかったら、正しい に切り替えて一時停止を解除AVPlayer
し、次のサイクルのために最初からやり直します。
AVPlayer's
iOS でアクティブにできるのはおよそ 4 つに制限されていると読んだので、これはうまくいかないと思います。ここの StackOverflow でこれについて尋ねる人がいて、4 AVPlayer の制限について知りました: fast-switching-between-videos-using-avfoundation
アイデア 2: AVQueuePlayer を使用する (機能しません)
AVPlayerItems
10 を 1つに押し込むと、AVQueuePlayer
すべてがプリロードされてシームレスに開始 されるとは思えません。AVQueuePlayer
はキューであり、キュー内の次のビデオをすぐに再生できるようにするだけだと思います。10 本の動画のうちどれを再生したいかは、その動画を開始する時が来るまでわかりません。ios-avplayer-video-preloading
アイデア 3: バックグラウンドで読み込み、再生、保持するAVPlayerItems
(まだ 100% 確実ではありませんが、見栄えはよくありません)
各ビデオ クリップの最初の 1 秒をバックグラウンドで読み込んで再生し (ビデオとオーディオの出力を抑制)、それぞれへの参照を保持する利点があるかどうかを調べていますAVPlayerItem
。実際、それを交換し、バックグラウンドの AVPlayer をアクティブな AVPlayer と交換します。すすいで繰り返します。
理論的には、最近再生AVPlayer/AVPlayerItem
された は、その後の再生を高速化する準備済みのリソースをまだ保持している可能性があります。これまでのところ、これによる利点は見られませんでしたがAVPlayerLayer
、背景の設定が正しくない可能性があります。私が見たものから、これが本当に物事を改善するとは思えません。
アイデア 4: 別のファイル形式を使用します。
現在、.m4v (video-MPEG4) H.264 形式を使用しています。H.264 にはさまざまなコーデック オプションが多数あるため、一部のオプションは他のオプションよりもシークが速い可能性があります。ファイルサイズを小さくするより高度な設定を使用すると、シーク時間が長くなることがわかりましたが、逆のオプションは見つかりませんでした。
アイデア 5: ロスレス ビデオ フォーマット + AVQueuePlayer の組み合わせ
ロードが高速であるが、ファイル サイズが非常に大きいビデオ フォーマットがある場合、各ビデオ クリップの最初の 10 秒間を、肥大化するがロードは高速であるが元に戻るバージョンで事前に準備することが 1 つのアイデアかもしれません。 H.264 でエンコードされたアセットでそれが可能になります。AVQueuePlayer を使用し、非圧縮ファイル形式で最初の 10 秒を追加し、その後に H.264 のファイルを追加します。これにより、最大 10 秒の準備/プリロード時間が得られます。したがって、私は両方の世界の「ベスト」を手に入れます: 起動時間が速いだけでなく、よりコンパクトなフォーマットの恩恵も受けます.
アイデア 6: 非標準の AVPlayer を使用する / 自分で作成する / 他のユーザーのものを使用する
私のニーズを考えると、AVPlayer を使用できないかもしれませんが、AVAssetReader に頼る必要があり、最初の数秒をデコードし (おそらく raw ファイルをディスクに書き込みます)、再生に関しては raw 形式を使用して再生する必要があります早く戻る。私には巨大なプロジェクトのように思えます。素朴な方法で取り組むと、不明確であるか、うまく機能する可能性が低くなります。デコードおよび非圧縮の各ビデオ フレームは 2.25 MB です。単純に言えば、ビデオに約 30 fps を使用すると、最終的にディスクからの読み取り要件が約 60 MB/秒になりますが、これはおそらく不可能です。明らかに、ある程度の画像圧縮 (おそらく PVRTC によるネイティブの openGL/es 圧縮形式) を行う必要がありますが、それはちょっとクレイジーです。たぶん、私が使用できるライブラリがそこにありますか?
アイデア 7: すべてを 1 つのムービー アセットに結合し、seekToTime
上記のいくつかよりも簡単なアイデアの 1 つは、すべてを 1 つのムービーに結合し、seekToTime を使用することです。問題は、私たちがあちこち飛び回るということです。映画への基本的なランダム アクセス。これは実際にはうまくいくと思います: avplayer-movie-playing-lag-in-ios5
どのアプローチが最適だと思いますか? これまでのところ、ラグを減らすという点ではそれほど進歩していません。