このトピックは非常に広範囲にわたるため、セクションに分割します。
- 一般的な問題、私が直面しなければならなかったニュアンス
- ビデオのダウンロード(このトピックとこの投稿で既に取り上げているため、このトピックで停止することはおそらくないでしょう。
- ビデオ処理。
- クラウドに保存します。
パート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のビデオを引き込みます。つまり、ダウンロードがはるかに進んでおり、処理が追いついていません。 サイズ変更には最も時間がかかります。 ストーリーボードとオーディオトラックを比較的迅速に引き出します。
投稿が気に入ったら、以下の時間で実装と作業のメカニズムをさらに詳しく説明します。
何が起こったかのスクリーンショット。 すぐに予約してください。これは有効なオプションではないため、厳密に判断しないでください。
