ブラウザーでffmpegを使用したMP4のHLS

こんにちは!2か月以上の間、私は自分の自由な時間に、emscriptenとffmpegを使用してHLSとDASHをMP4に変換するためのWebアプリケーションを見てきました。

この記事では、ffmpegの編集とパッチのソースコードを引用しません。それらのほとんどは私の膝の上で行われ、私はCがあまり得意ではありません。しかし、今はあなたを助けるのに十分な記事があります。

前書き


2年前、私はオーディオとビデオのトラックを1つのmp4ファイルに結合することを目標としていました。それから私はemscriptenに突入し、基本的に私は多くのことを学んだffmpeg.jsリポジトリを見つけました。その後、私はほぼ目標を達成することができましたが、Cで非常に条件付きでしたが
、ソースコードを理解して、ffmpegはファイルシステムを操作するためのパッチを作成しました。バッファデータをリポジトリに送信するjs関数。

しかし、非同期関数に問題があり、私は正しく解決できませんでした。それらはasyncify(fastcomp)を通じて機能しましたが、正しく機能しなかった場合があります。つまり、wasmでのコードの実行は、js関数からの結果を待たずに停止せず、それだけです故障した。この問題は、EMTERPRETIFY_WHITELISTフラグによって修正されました。これにより、コードが同時にwasmからasmに移動し、速度が低下しました。コールスタックをデバッグし、すべての例外で壊れた関数をリストに追加する必要がありました。

一般に、このような問題があるため、これは実用的なソリューションとは言えず、すべてが小さなデモのままでした。



1年半後


WebAssamblyの新機能 に関するGoogle Dev Summitのレポートを見た後、私はemscriptenがどのように機能しているかを確認し、メッセージを確認しました。
Emscriptenは、バージョン1.39.0(2019年10月)以降、上流のLLVM wasmバックエンドを使用してWebAssemblyを発行し、古いfastcompバックエンドは非推奨になりました

私はリパッカーフォーマットを再構築してみたかったです。約1週間、新しいコンパイルの問題を修正し、最後にすべてをまとめる方法をグーグルで調べました。変更はそれほど多くはありませんでしたが、新しいライブラリリンカーが原因でそれが行われることはなく、少なくとも何かを収集するために必死になっていたため、問題のライブラリを見つけました(結局、ライブラリ自体が接続されており、アセンブリ中に手で指定する必要はありません)。

そして今、それが集まり獲得した瞬間がやってきました!非同期コードの問題はなくなり、何もデバッグする必要がなくなり、最初から問題なく動作しました。

こちらは目標を達成したようですが・・・新しいものが登場しました。

HTTPプロトコルの書き換え


そんな思いが長い間浮かんできました。これにより、HLSまたはDASH、および既製のプレイリストだけでなくライブストリームもダウンロードできます。そして、私はこのようなものをインターネット上で見たことがありません。

短い休憩で少なくとも何かがうまくいくようにするのに約3週間かかりました。私はCを知っていましたが(経験がゼロのとき)、ポインターに多くの問題があり(何がどこにあるか、他の人のコードでさえ追跡するのは困難です)、最終的に何かがエラーなしでコンパイルされました。最初の成功の後、これはアイデアを完了するためにさらに熱意を与えました。

ほんの数週間、そしてようやく私は機能するhttpプロトコルの最初の反復をなんとかしてなんとかしました、そしてそれはすべてのように思われるでしょうか?

大変なことが終わったとき


この時点で、フレームワークの準備ができており、url入力フィールドと開始ボタンを備えた小さなhtmlフォームがありました。しかし、CORSをバイパスしてデータをロードする拡張機能を記述し、チャンクでデータを書き込むストレージを作成し、進行状況を表示するインターフェイスを作成する必要がありました。これらはすべて、異なるブラウザーの問題を修正するためにデバッグされました。ようやく、ようやく使えるようになる時期がやってきました。

基本的に、ユーザースクリプトが作成されました。これは、データをダウンロードするためのffmpegからのフェッチ要求のプロキシです。

数日後、ChromeとFirefoxの拡張機能の準備が整いました。webRequestを使用して、動画を視聴するときにブラウザーがロードするすべてのhlsリンクを収集しました。

結局のところ、Firefoxでは、拡張機能APIを使用して電源を管理することはできません。これにより、コンピューターが不幸にもスリープ状態になるのを防ぐことはできません。

拡張機能は次のように



なります。サイトが少しねじ込まれたマテリアルUIであるページを改善し、ホイップされたすべての場所を確定しました。



データを保存するさまざまな方法をテストした後、私はいくつかの問題を明らかにしました:

Blob -ChromeはそれらをRAMに書き込み、オーバーフローするとディスクにドロップしますが、OSXではメモリがオーバーフローした場合のみ、OSはアカウントを離れ、開いていたすべてのアプリケーションを閉じます。また、Firefoxは通常、常にデータをメモリに保持していました。

キャッシュストレージ-それはIndexedDbのように機能しますが、データを書き込んだ後、Chrome blobではRAMに残りますが(バグまたはFitchaのいずれか)、データはキャッシュストレージに(ディスクに)書き込まれ、メモリがいっぱいになると同様にドロップされますblobとしてディスクにボリューム。

IndexedDb-時計のように動作し、BLOBを保存する方法を知っており、飾り気なくデータを書き込みますが、Firefoxは2GBの量を厳密に制限しています。

少し完成しました。ffmpegプロセスを(ポインターを介して)中断する機能を作成し、フォーマット(ffprobe)の選択方法とネットワークエラーの処理方法を理解しました。





そして今、あなたはここで自分結果を試すことができます

私にとって、これはツイートでストリームを録音したり、VODをダウンロードしたりする必要があるときに不可欠です。また、ラップトップ、ミキサー、およびHLSまたはDASHでコンテンツをブロードキャストする他のサイトでも動作します(残念ながら、ffmpegのDASH実装は非常に条件付きであり、フラグメントリクエストの間隔が考慮されていないため、ライブが正しくダウンロードされない場合があります)。

読んでくれてありがとう!

ffmpegとemscriptenについて質問がある場合は、書いてください。

All Articles