node.js + phpおよびffmpegを使用したビデオのストリームロードと処理-パート1

私はアウトソーシング会社で働いており、タスクの目的は、アプリケーションの内部ニーズに合わせてさらに処理する可能性のあるビデオをダウンロードすることでした。 最終的に、結果を後でオンラインエディタで使用できるようにクラウドに保存する必要があります。 要件:スケーラビリティ、無制限のビデオサイズ、速度、ブラウザ間の互換性、可視性。



このトピックは非常に広範囲にわたるため、セクションに分割します。



  1. 一般的な問題、私が直面しなければならなかったニュアンス
  2. ビデオのダウンロード(このトピックとこの投稿で既に取り上げているため、このトピックで停止することはおそらくないでしょう。
  3. ビデオ処理。
  4. クラウドに保存します。




パート1



1.クロスブラウザーの互換性

この要件を確保するために、HTML5ファイルアップロードを使用することはできませんでした(すべてのブラウザーに実装されているわけではありません)。 したがって、通常のHTML4フォームを作成し、node.jsを使用してサーバーに送信しました。 ビデオのダウンロード/処理の現在の進行状況を取得するために、AJAXリクエストが作成されました。 フォームには、ランダムに生成された識別子文字列(たとえば、32文字)が含まれていました。 Node.jsは、現在のファイルに関する情報をそれに添付し、各状態リクエストで次のJSONを渡しました。



{ "fileid":"uwrd28a9v71j444d260c55hkj6uli06j", //  "name":"test.FLV", //  "progress":"7.80", //   "status":"uploading", //  "audio":10.02, //   "frame":301, //  ,   "videoProgress":"7.80", //   "audioProgress":"3.73", //   "frameProgress":"3.73", //   "messages":[], // ,      "expectedBytes":5389574, //   "uploadedBytes":420139, //   "bps":91773.48186981214, //  / "uploadEstimated":54, //     "videoEstimated":42, //      "audioEstimated":75, //      "frameEstimated":71 //     }
      
      







これに基づいて、ユーザーにはダウンロードステータスが表示されます。



2.ユーザー認証

PHPのフロントエンド(ユーザー認証もそこで行われている)であるため、何らかの方法でセッションデータをnode.jsサーバーに転送する必要がありました。 これらの目的のために、memcachedが使用されました。 PHP でのセッション置換については、 こちらをご覧ください 。 一番下の行は簡単です。セッションはmemcachedに保存され、フォームを介してロードされると、session_idが渡され、node.jsによって読み取られます。 次に、node.jsは、対応するセッションの検索でmemcachedに変わり、user_idなどを取得します。 重要な点が1つあります。POST要求はHTMLに表示される順序でパラメーターを渡すため、フォーム自体のsession_idを最初に設定する必要があります。 つまり、これを行うと:



 <form method="post" action="http://nodeserver.com/"> <input type="file" name="video"/> <input type="hidden" name="session_id" value="session_id"/> <input type="submit" name="submit"/> </form>
      
      







この場合、ファイル自体は最初にnode.jsに送られ、次にsession_idに送られますが、これは良くありません。 結局、最初にファイルの送信元を確認し、ユーザーが承認されていない場合はキャンセルする必要があります。 上記の例でfileとsession_idを交換する場合、最初にセッションを取得し、ファイルのダウンロードを遅くし、サーバーがユーザーに問題がないことを確認してからダウンロードを続行するまで待機します。 node.jsでは、リクエストを一時停止できます。



3.ストリーミングビデオ

問題は、すべてのビデオをすぐに処理できるわけではないことです。 たとえば、mp4形式の仕様に従って、メタデータはファイルの最後に移動します。 ただし、ビデオのサイズ、ファイル内のトラック、再生時間などをすぐに知る必要があります。 さらに、トランスコーディング中の一部のビデオ形式は、ソースファイルのさまざまな部分にアクセスできる必要があります。 これに基づいて、それぞれ2つのオプションを持つ2つのケースがあります。



1.ダウンロードの開始時に、node.jsを使用してffmpegコマンドを使用してファイル情報をプルします。



 var spawn = require('child_process').spawn; var ffmpeg = spawn('ffmpeg', ['-i', '-']); var ffmpeg_stdout = '' ffmpeg.stderr.on('data', function(buffer) { ffmpeg_stdout += buffer; //     }); // file -     file.on('data', function(buffer) { ffmpeg.stdin.write(buffer); });
      
      







変数ffmpeg_stdoutには、ファイル内にあるすべてのトラックまたはエラーが取得されます。 エラーがある場合、ffmpegはファイルをストリームで処理できません。 この場合、これについてユーザーに警告し、すぐにファイル全体をダウンロードします。その後、必要な操作を実行します。



2.この場合、速度が重要なので、ビデオの読み込みが開始されたらすぐにストーリーボードを開始しようとします。 ただし、形式がストリーミング処理をサポートしていない場合は、完全なダウンロードまで待つ必要があります。

次のアルゴリズムが判明します:メタデータを抽出し、その場でビデオを処理しようとします。これが発生した場合、他のすべての場合は完全なダウンロードを待っています。 実際には、処理を開始するために完全にダウンロードする必要があるビデオはごく少数です。



今日は明日朝の仕事です。



最後に、可能性は無限です。複数のサーバーに負荷を分散し、外出先で結果を表示できます。たとえば、ビデオから最後に完成したフレームを引き出します。 すべてAmazon EC2で動作します。 速度に関しては、ダウンロード速度を確認する方法はありませんでした(チャネルが弱い)が、10メガビット以上であると確信できます。 サーバーの負荷: 中間サーバーのみでは、1つのビデオが約2Mbpsのビデオを引き込みます。つまり、ダウンロードがはるかに進んでおり、処理が追いついていません。 サイズ変更には最も時間がかかります。 ストーリーボードとオーディオトラックを比較的迅速に引き出します。



投稿が気に入ったら、以下の時間で実装と作業のメカニズムをさらに詳しく説明します。



何が起こったかのスクリーンショット。 すぐに予約してください。これは有効なオプションではないため、厳密に判断しないでください。










All Articles