Adobe HTTP Dynamic Streamingを使ってみた
先日、Adobeから「Adobe HTTP Dynamic Streaming」が公開されたので、使ってみました。
これは、動画ファイルの配信や従来はRTMPなどを使用していたLive配信をHTTPで配信出来るようにするもので、HTTPを使用するため、80番ポートを開けておくだけでよく運用も楽になり、配信されるフラグメントファイルも従来のキャッシュサーバにキャッシュ出来ます。
また、Apacheやキャッシュサーバを増やすだけでスケールが可能になります。
動画データを全て読み込むのではなく、順次フラグメントファイルを要求するので、フラグメントファイルの転送が遅いと再生が止まってしまいます。シーク時にはシーク先の時間に該当するフラグメントファイルから読込みをするだけなので、シーク後すぐに再生が開始されます。
クライアントとしては、Flash Player10.1から対応していて、同時に公開された、Open Source Media Framework(OSMF)を使用することで簡単に動画Playerを作成する事が可能になりました。
Adobe Flash Accessを使用した動画のライセンス管理も簡単に行える構造になっています。
仕組み
HTTP Dynamic Streamingを利用するにはApache2.2が必要です
ApacheにHTTP Origin Moduleを導入するだけで利用可能になります
しかし、動画をそのまま配置するだけではダメで、同時に配布されているFile Packagerを使用して変換する必要があります
対応動画形式は
- F4V/MP4 compatible files
- FLV
です
File Packagerは動画ファイルから
- f4f 動画ファイル本体。内部はセグメントに分割されている
- f4m マニフェストファイル。この中に動画情報が格納されており、可変ビットレートやライセンス管理の情報も記述される
- f4x インデックスファイル。Playerから要求される各フラグメントファイルのf4fファイル中でのインデックスを持っている
以上の3つのファイルを生成します
サーバでの処理の流れは
- Playerにはマニフェストファイルのアドレスを渡します
- ApacheはOrigin Moduleに処理を渡して、Origin ModuleからPlayerにマニフェストファイルが返される
- Playerはマニフェストファイル中のBootstrapセクションを参照してタイムコード(segment#/fragment#)に変換する
- Playerが「http://www.hoge.com/media/fugaSeg1-Frag1」のようなアドレスを生成しリクエストを投げます
- ApacheはOrigin Moduleに処理を渡し、Origin Moduleはセグメント番号とフラグメント番号からf4fファイルのビットオフセットを算出し指定のフラグメントをPlayerに返します
このような流れで動画が再生されます
シークバーを動かした時は、シーク先の時間に対応するフラグメントが要求されるのでキャッシュサーバにキャッシュがあればOrigin Moduleに処理が渡らずキャッシュサーバ中のキャッシュを返すだけです
可変ビットレートな動画使用する時は、動画の変換時に指定します
導入してみる
http://www.adobe.com/jp/products/httpdynamicstreaming/のリンクから
- HTTP Origin Module
- File Packager
- OSMFのサンプル
をダウンロードしておきます
Windows用とLinux用があるので使用する環境にあったものをダウンロードしてください。今回はCentOS5.5で試しています
- HTTP Origin Moduleの導入
- ダウンロードしたファイルを解凍し、Apacheのmodulesディレクトリに必要なファイルをコピーします
unzip adobe_f4f_apache_module100_linux_x86.zip cd /adobe_f4f_apache_module100_linux_x86/adobe/f4fmodule cp libF4V.so /etc/httpd/modules cp libexpat.so.1 /etc/httpd/modules cp mod_f4fhttp.so /etc/httpd/modules
-
- 配信用ファイルを配置するディレクトリを作成
mkdir -p /var/www/vod
-
- configファイルを作成
今回はhttp://www.piyo.com/vod/***でアクセスされた場合にOrigin Moduleに処理を渡します
Live配信用の設定項目などはhttp://help.adobe.com/en_US/HTTPStreaming/1.0/Using/WS7b362c044b7dd076-735e76121260080a90e-7ffc.html#WS8ec1569f90918c1b-457ae32d1282caecc18-8000を参照してください
vim /etc/httpd/conf.d/dstreaming.conf
LoadModule f4fhttp_module modules/mod_f4fhttp.so
<Location /vod>
HttpStreamingEnabled true
HttpStreamingContentPath "/var/www/vod"
</Location>
-
- Apacheを再起動
- 動画を変換
- Packagerを解凍します
unzip adobe_f4fpackager100_linux_x86.zip
cd adobe_f4fpackager100_linux_x86/adobe/f4fpackager
-
- 動画を変換します
リファレンス:
Adobe HTTP Dynamic Streaming * File Packager reference
Adobe HTTP Dynamic Streaming * Packaging on-demand media
./f4fpackager --input-file 変換元動画 --output-file 変換後動画情報を書出すディレクトリ
これだけです。
可変ビットレート対応にするには
f4fpackager --input-file=sample1_150kbps.f4v --bitrate=150 f4fpackager --input-file=sample1_700kbps.f4v --manifest-file=sample1_150kbps.f4m --bitrate=700 f4fpackager --input-file=sample1_1500kbps.f4v --manifest-file=sample1_700kbps.f4m --bitrate=1500
の様にビットレートの低い動画から変換を行い、変換時に生成されたコンフィグファイルを使用して次の動画を変換していきます
Playerに指定するマニフェストファイルは一番ビットレートの高い動画の物を指定します。このマニフェストファイルには全てのビットレートの情報が入っているためです
-
- 生成されたファイルを先程していしたパスに配置します
OSMFサンプルプレイヤーで再生してみる
OSFMPlayer_zeri2.zipを解凍して、配置してブラウザからアクセスします
取り出しボタンを押すとアドレスが指定出来るので、マニフェストファイルのアドレスを指定すれば再生出来ます
http://www.hoge.com/OSMFPlayer.html?url=http://www.hoge.com/vod/piyo.f4m
とURLで再生ファイルを指定出来ます
Apacheのログを見ると
/vod/hogeSeg1-Frag19
のようなアドレスでフラグメント毎にリクエストが来ている様子が分かります
Nginxでキャッシュしてみた
シークする度にオフセット計算して、指定位置のファイルを生成して送り返す処理をいちいちやるのはなんなのでフラグメントファイルをキャッシュします
今回は、nginx0.7.67を使用しました
- インストール
wget http://sysoev.ru/nginx/nginx-0.7.67.tar.gz tar xzvf nginx-0.7.67.tar.gz cd nginx-0.7.67 ./configure --without-http_rewrite_module --without-http_fastcgi_module make make install
- 設定
- 今回は同一ホストでApcheとngixを動作させ、nginxを80番ポートで動かすので、Apacheのポートを80番意外にします(今回は81)
- キャッシュ置き場は「/tmp/nginx/cache」
worker_processes 4; error_log logs/error.log; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; access_log logs/access.log; sendfile on; keepalive_timeout 0; gzip on; proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=STATIC:10m max_size=1g inactive=24h; server { listen 80; server_name cache.hoge.com location / { proxy_pass http://127.0.0.1:81; proxy_set_header Host $host; proxy_cache STATIC; proxy_cache_valid 200 1d; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
cache関係のディレクティブの解説は
HttpProxyModule
を参照してください
-
- confファイルの確認
/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
- nginx起動
/usr/local/nginx/sbin/nginx
後はログを見ると、初回アクセスのみApacheにアクセスがいき、その後の同一フラグメントへのアクセスはキャッシュから返されている事がわかります
動画へのアクセス急増時にはキャッシュサーバを増やすだけで対応が可能です
メタデータが気になったから
<metadata> AgAKb25NZXRhRGF0YQgAAAAAAAhkdXJhdGlvbgBAdTtHrhR64QAMYXVkaW9jb2RlY2lkAgAEbXA0YQAFd2lkdGgAQI 4AAAAAAAAABmhlaWdodABAhoAAAAAAAAAMdmlkZW9jb2RlY2lkAgAEYXZjMQAKYXZjcHJvZmlsZQBAWQAAAAAAAAAI YXZjbGV2ZWwAQD8AAAAAAAAABmFhY2FvdAAAAAAAAAAAAAAPYXVkaW9zYW1wbGVyYXRlAEDliIAAAAAAAA1hdWRpb2 NoYW5uZWxzAEAAAAAAAAAAAA52aWRlb2ZyYW1lcmF0ZQBAPerJYubiRgAJdHJhY2tpbmZvCgAAAAIDAAZsZW5ndGgA QWySeGAAAAAACXRpbWVzY2FsZQBA5YiAAAAAAAAIbGFuZ3VhZ2UCAAN1bmQAAAkDAAZsZW5ndGgAQWNiYUAAAAAACX RpbWVzY2FsZQBA3TdAAAAAAAAIbGFuZ3VhZ2UCAAN1bmQAAAkAB2N1c3RkZWYKAAAAAAAACQ== </metadata>
Base64でデコード
\002\000\nonMetaData\b\000\000\000\000\000\bduration\000@u;G\256\024z\341\000
\faudiocodecid\002\000\004mp4a\000\005width\000@\216\000\000\000\000\000\000
\000\006height\000@\206\200\000\000\000\000\000\000\fvideocodecid\002\000\004avc1\000
\navcprofile\000@Y\000\000\000\000\000\000\000\bavclevel\000@?\000\000\000\000\000
\000\000\006aacaot\000\000\000\000\000\000\000\000\000\000\017audiosamplerate\000@
\345\210\200\000\000\000\000\000\raudiochannels\000@\000\000\000\000\000\000\000\000
\016videoframerate\000@=\352\311b\346\342F\000\ttrackinfo\n\000\000\000\002\003\000
\006length\000Al\222x`\000\000\000\000\ttimescale\000@\345\210\200\000\000\000\000
\000\blanguage\002\000\003und\000\000\t\003\000\006length\000Acba@\000\000\000\000
\ttimescale\000@\3357@\000\000\000\000\000\blanguage\002\000\003und\000\000\t\000
\acustdeb\200\000\000\000\000\000\002
こんな感じでした