WowzaとAmazonElasticTranscoderを使用したオンラインビデオ

公開: 2022-03-11

今日のWebアプリの成功と採用は、そのパフォーマンス、柔軟性、および使いやすさに大きく依存しています。

特に今日のADHDの世界では、ページの読み込みに時間がかかりすぎると、ユーザーはアプリに対する忍耐力をすぐに失います。 本質的にコンピューティングとI/Oを多用するビデオ処理をサポートする必要のあるWebアプリの場合、この課題は特に深刻です。 それにもかかわらず、ユーザーはますます要求が高まっており、スマートフォンやタブレットで実行している場合でも、ビデオを高品質すばやくロードすることを望んでいます。

また、ユーザーは、好みのブラウザーやデバイスで動作しない、またはロードまたはエクスポートする必要のあるデータ形式をサポートしていないWebアプリに対する許容度を失っています。 したがって、サポートする必要のあるビデオ形式の多様性により、ビデオサポートをWebアプリに組み込むことも特に困難になります。

この投稿では、オープンソーステクノロジーとクラウドベースのサービスを効果的に活用して、PHPベースのWebアプリにビデオ機能を組み込む方法について説明します。

WowzaとAmazonElasticTranscoderを使用したPHPでのオンラインビデオ処理

使用事例

私は、登録ユーザーが自分の動画をアップロードして共有できるYouTubeのようなWebサイトを開発する必要があるチームの一員でした。

システムは、登録ユーザーがサポートされているさまざまな形式でビデオをアップロードし、それを共通形式(MP4)に変換できるようにする必要がありました。 また、ビデオプログレスバーにフレームを表示するためにビデオプレーヤーで使用されるサムネイルのセットと画像のコラージュを生成する必要がありました。

クライアントの要件により、利用可能なCDNまたはトランスコーディングAPIを使用できなかったため、事態はさらに複雑になりました。そのため、ソリューションを最初から開発する必要がありました。

ビデオのアップロード

アップロードプロセス自体はビデオ固有である必要はなかったため(使いやすいファイルアップロード機能が必要でした)、独自のソリューションを使用するのではなく、既存のオープンソースソリューションを使用する方が理にかなっています。 jQuery-File-Uploadを選択したのは、主に、この場合に不可欠な2つの機能をサポートしているためです。 つまり、アップロードの進行状況バーとチャンクされたアップロードです。

チャンクアップロードにより、ユーザーは事実上すべてのサイズのビデオファイルをアップロードできるようになりました(特にHD解像度のビデオファイルをサポートするために重要です)。 このアプローチでは、ファイルはフロントエンドで複数の「チャンク」に分割され、各データチャンク(チャンク番号や合計ファイルサイズなどの各チャンクのメタデータとともに)でアップロードアクションが呼び出されます。 次に、完全なビデオファイルがバックエンドで再アセンブルされます。 ちなみに、一部のブラウザ(Mobile Safariなど)はチャンクをランダムな順序で送信する傾向があるため、メタデータにチャンク番号を含めることが特に重要であることがわかりました。

オンラインビデオ処理

ビデオ処理は、静止画像のようにフレームをキャプチャするのと同じくらい単純な場合もあれば、画像の強調、ビデオストリームの安定化などのより複雑な操作を伴う場合もあります。 この場合、ビデオ処理の要件は、(a)ビデオコーデックとその他の主要なメタデータを抽出し、(b)サムネイルと画像コラージュのセットを生成することだけでした(ビデオプレーヤーでビデオの進行状況にフレームを表示するために使用されます)バー)。

FFmpeg –広く使用され、自由に配布されているオープンソースライブラリ–は、これらの要件を満たすのに非常に役立ちました。 FFmpegは、オーディオおよびビデオファイルを記録、変換、およびストリーミングするための完全なクロスプラットフォームソリューションを提供します。 また、ビデオの変換や簡単な編集(トリミング、切り取り、透かしの追加など)にも使用できます。

私たちの目的のために、FFmpegを使用してビデオを10のセクションに分割し、各セクションのサムネイルをキャプチャして必要な機能を提供することができました。

残念ながら、FFmpegライブラリにはPHP言語のバインディングはありません。 その結果、PHPからFFmpegを活用する唯一の方法は、システムコマンドを使用してコマンドラインからバイナリを呼び出すことです。 PHPでFFmpegを使用するには、基本的に2つの方法があります。

  • libav。 Libavは、2011年にFFmpegからフォークされたフリーソフトウェアプロジェクトであり、マルチメディアデータを処理するためのライブラリとプログラムを作成します。 たとえば、Ubuntuでは、これはコマンドsudo apt-get install libav-tools 。 libavコマンドはFFmpegおよびavconvと互換性があります。 これをプログラムで使用するには、PHPがffmpeg/avconvにコマンドラインでアクセスできる必要があります。
  • PHP-FFMpeg。 PHP-FFMpegは、FFMpegバイナリ用のオブジェクト指向PHPドライバーです。 composer update "php-ffmpeg/php-ffmpeg"を実行するだけでアクセスできます。

PHP-FFMpegを使用したのは、関心のあるFFmpeg機能に簡単にアクセスできるためです。たとえば、このパッケージのFFProbeクラスを使用すると、コーデックや特定のビデオファイルの長さに関する情報を次のように受け取ることができます。

 $ffprobe = FFMpeg\FFProbe::create(); $ffprobe ->format('/path/to/video/mp4') // extracts file informations ->get('duration');

FFmpegを使用すると、ビデオフレームを簡単に保存することもできます。

 $ffmpeg = FFMpeg\FFMpeg::create(); $video = $ffmpeg->open('video.mpg'); $video ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10)) ->save('frame.jpg');

より詳細なサンプルコードはこちらから入手できます。

注意点:一部の特許法により、すべてのコーデックがFFmpegで処理できるわけではなく、一部の形式は適切に(または完全に)サポートされていません。 数年前、たとえば、フィーチャーフォンのサポートが必須だったときに.3gp形式で苦労したことを覚えています。

キューイング

ビデオのコーデックとその他のメタデータを取得した後、ビデオをFIFO(先入れ先出し)変換キューにプッシュします。 キューは、実行するたびに指定された数の未処理のビデオを選択し、それらを変換ユーティリティ(ここで入手可能なサンプルソースコード)に渡す単純なcronスクリプトを使用して実装されました。

変換ユーティリティはFFMpegを呼び出して変換を実行し、各ビデオを処理済みとしてマークします。

また、1分間のビデオを変換する平均時間を計算する簡単な待機時間推定メカニズムを開発しました。 この平均を使用して、動画のアップロードが完了した後、残りの動画の処理時間に基づいて、推定残りの処理時間をユーザーに計算して表示することができます。

ビデオフォーマット変換

すべてのデバイスと画像処理ソフトウェアで基本的にサポートされている静止画像に対して、広く認識されている特定の形式(JPEGやGIFなど)が登場しています。 一部のビデオ形式は他の形式よりも一般的ですが、そのような普遍的にサポートされている形式はまだビデオに登場していません。

私たちの場合、さまざまな形式から単一の共通形式(MPEG-4)に変換する必要があることに加えて、変換されたビデオをモバイルデバイスへのストリーミング用に最適化する必要がありました。

ビデオ形式の変換(少なくとも短期的なニーズ)では、クラウドベースのAmazonElasticTranscoderを使用することが利用可能な最良のオプションでした。 一般的な使いやすさに加えて、トランスコーダーサービスは最適化とすべてのエンコード設定を処理します。 幸い、AWS SDK for PHPが利用可能であり、PHPコードからのサービスの呼び出しが簡単になります。

注: Amazon Elastic Transcoderのようなクラウドベースのサービスを使用すると、すぐに起動して実行したい場合に最適です。 ただし、このオプションは、特にクライアントのビジネスモデルで大きなビデオを広範囲に使用する必要がある場合は、クライアントにとって高額になる可能性があることに注意してください。 考慮すべきもう1つの要素は、クライアントのビデオまたはビジネスモデルが利用規約と互換性があると必ずしも想定する必要がないということです。

Amazonは、基本的なストレージおよびコンピューティング要素であるS3(Simple Storage Service)およびEC2(Elastic Compute Cloud)をAuto ScalingおよびSNS(Simple Notification Service)と組み合わせて使用​​し、事実上瞬時にスケールアップおよびスケールダウンする機能を提供します。

AmazonはComposerでインストール可能なバージョンのパッケージを維持しているため、 aws-sdkのインストールは簡単です。 ”aws/aws-sdk-php": "2.*"composer.jsonファイルに追加し、 composer updateを行うだけです。

もちろん、Amazon Elastic TranscoderにアクセスするにはAmazonアカウントが必要です。そのため、自分(または顧客)がまだアカウントを持っていない場合は、アカウントを設定する必要があります。

Amazon Elastic Transcoderサービスを使用するには、最初にビデオファイルをS3の適切なバケットにアップロードする必要がありました。 次に、トランスコーダージョブにサムネイルのデコードと生成を行わせ、サムネイルが完了すると、指定されたアドレスにHTTPリクエストを送信します。 これにはAWSパネルでの設定が必要ですが、これは非常に単純であり、Amazonはこれを行う方法に関する優れたドキュメントを提供しています。

Symfony 2の統合を簡素化するのに役立つトランスコーダーバンドルを自由に利用してください。これには、使用法の説明が含まれ、処理されたビデオに関する情報を収集するためにAmazonから送信される通知サービスを迅速に実装するためのコントローラーを提供します。 使用例はこちらから入手できます。

さらに、Amazon通知を処理するコントローラーの例がここにあり、サブスクリプションアドレスの確認も実装されています。 サービスは最初にアクセスするURLを投稿して、これが有効な通知受信者であることを確認します。 本当に必要なのは、ビデオを処理済みとしてマークすることだけです。 それ以降は、クラウドに保存されているトランスコードされたビデオを使用できます。

ストリーミング

ビデオストリーミングは、高いパフォーマンスを必要とする機能です。中断のないストリーミングに対するユーザーの期待は高く、遅延に対する許容度は非常に低くなっています。 この課題は、ビデオを複数のクライアントにリアルタイムで同時にストリーミングする必要があるため、悪化することがよくあります。

私たちの場合、各ユーザーが自分のビデオチャンネルを作成して放送を開始できるようにサポートする必要がありました。 私たちのソリューションは、次の3つのコンポーネントで構成されていました。

  • ダッシュボード。 ストリーマーのダッシュボードとして機能し、ビデオを提供する機能を提供するアプリケーション。
  • ビューア。 ビデオストリームを消費して表示するビデオクライアント。
  • ストリーミングエンジン。 クラウドベースのビデオストリーミングサービス。

ビデオオンデマンド(VOD)テクノロジーがまだ進化しているという事実に加えて、私たちが直面したもう1つの問題は、カメラアクセスが十分にサポートされておらず、P2P接続しか提供されていないことでした。 また、私たちの目標は、複数の同時ユーザーにオンライン放送を提供することでした。 さらに、 getUserMedia/Stream API(以前は<device>要素として想定されていた)のサポートは、最新のブラウザー間でまだ一貫していません。 これらの要因に基づいて、私はFlashテクノロジを使用することにしました。これは、Flashテクノロジが本当に唯一の合理的な選択であったためです。 したがって、両方のアプリケーション(DashboardとViewer)は、 FlexとActionScriptを使用して実装されました。

ストリーミングエンジンには、 Wowzaを使用しました。 他にも非商用ソリューション(基本的にWowzaのドロップイン代替品として販売されているRed5など)がありますが、私たちの場合、商用製品のサポートが重要な要素でした。 また、少なくともシステムを構築しているとき、Wowzaはより優れたドキュメントを提供しました。これは追加の利点でした。 (Wowzaの試用版は30日間無料で入手でき、最大180日間使用できる開発者向けの試用版もあります。ただし、いくつかの制限があります。ストリーミングは2つのクライアントでのみ機能し、制限があります。接続の最大数について。)

Wowzaストリーミングエンジン

Wowzaで提供されているLiveStreamアプリケーションを使用しました。 これを構成するには、 applications/app_nameを空のままにし、 conf/app_nameconfカタログからApplication.xmlファイルをコピーします。 ファイルを編集して、次のように<Streams>セクションを構成します。

 <Streams> <StreamType>live</StreamType> <StorageDir>${com.wowza.wms.context.VHostConfigHome}/content</StorageDir> <KeyDir>${com.wowza.wms.context.VHostConfigHome}/keys</KeyDir> <LiveStreamPacketizers></LiveStreamPacketizers> <Properties></Properties> </Streams>

重要なパラメータは<StreamType>live</StreamType>で、これはライブビデオフィード(カメラなど)からのストリームになることを定義します。 このファイルを編集して保存した後、Wowzaを再起動する必要があることに注意してください。

Flash(Flex / ActionScript)アプリケーション

Flashは、カメラとマイクをWowzaストリーミングサーバーに接続するための完全に統合されたシステムを提供します。 これは、ActionScriptの使用経験が限られている場合に特に役立ちます。

アプリケーション全体は、基本的に次のオブジェクト間の相互作用に基づいています。

  • NetConnection。 NetConnectionクラスは、クライアントとサーバーの間に双方向接続を作成します。 クライアントは、FlashPlayerまたはAIRアプリケーションにすることができます。 サーバーは、Webサーバー、Flash Media Server、Flash Remotingを実行しているアプリケーションサーバー、またはAdobeStratusサービスです。
  • カメラ。 Cameraクラスは、クライアントシステムまたはデバイスカメラからビデオをキャプチャするために使用されます。
  • マイクロフォン。 Microphoneクラスは、マイクからのオーディオを監視またはキャプチャするために使用されます。
  • NetStream。 NetStreamクラスは、NetConnectionを介して一方向のストリーミングチャネルを開きます。

まず、NetConnectionインスタンスを使用してWowzaストリーミングサーバーに接続し、次にネットワーク接続ステータスの変更をリッスンするイベントリスナーを接続します。

 nc = new NetConnection(); nc.connect(serverAddress:string); nc.addEventListener( NetStatusEvent.NET_STATUS, // event type eNetStatus, // listener function false, // use capture? 0, // priority true // use weak reference? );

カメラとマイクをストリーミングサーバーに接続するイベントリスナーの最小限の例を次に示します。

 private function eNetStatus(e:NetStatusEvent):void { switch (e.info.code) { case "NetConnection.Connect.Success": camera = Camera.getCamera(); mic = Microphone.getMicrophone(); ns = new NetStream(nc); ns.publish(streamName, "live"); ns.attachCamera(camera); ns.attachAudio(mic); break; case "NetConnection.Connect.Closed": // debug trace... display user message break; }

クライアントコードは非常に似ていますが、ユーザー側にビデオ入力を表示するだけです。 これは、次の簡単な例に示すように、ストリームをVideoオブジェクトに接続することによって行われます。

 if(event.info.code == "NetConnection.Connect.Success") { ns = new NetStream(nc); ns.client = nsClient; ns.addEventListener(NetStatusEvent.NET_STATUS, nsClient.onNetStatus); ns.play(streamName); video = new Video(); addChild(video); // this will display video video.attachNetStream(ns); // connect NetStream to video }

要約

ライブストリーミングとビデオは、モバイルおよびWebアプリケーションでますます重要な役割を果たすことが期待できます。 したがって、Web開発者は、ビデオのトランスコーディング、処理、およびストリーミングに精通することが重要です。 今日、これらの機能をWebアプリケーションに組み込むためのツール、ライブラリ、およびサービスが多数存在します。 この記事では、これらのテクノロジーを活用して統合し、比較的簡単に基本的なYouTubeのようなサイトを作成する方法を説明します。