HTTP Live Streamingで動画を配信してみる2(回線速度に応じてダイナミックに最適な品質の動画にアクセスする)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

前回、HTTP Live Streamingを使用して、基本的なHTTPストリーミングをやってみましたが、 今回は、回線スピードに最適化させるために、ビットレート(品質)の違う複数のデータを用意し、動的にこれを変化させてみたいと思います。
参考:HTTP Live Streamingで動画を配信してみる

2 ビットレート

(1) ffmpeg

元となる動画から、ビットレート(品質)の違うデータを生成するためには、ffmpegを使用します。 ffmpegは、多彩なオプションで動画や音声の変換を行うことができるフリーソフトです。

ffmpegは、Homebrewでインストールが可能です。

$ brew install ffmpeg
$ ffmpeg
$ ffmpeg -version
ffmpeg version 3.0.1 Copyright (c) 2000-2016 the FFmpeg developers
built with Apple LLVM version 7.3.0 (clang-703.0.29)

(2) ビットレートを指定した変換

下記のコマンドは、ffmpegを使用してビットレート250kbpsのデータを作成している例です。

$ ffmpeg -i source.mp4 -b:v 250K -c:a copy  source-250k.mp4

source.mp4が元のデータで、source-250k.mp4 が生成されるファイル名です。-c:a copy は、特にコーディック変換とかは行わないと言う意味で、-b:vでビットレートを指定しています。

この要領で、幾つかのビットレートのデータを生成してみました。

$ ls -la *.mp4
-rw-r--r--@ 1 sin  staff   2343232  6 12 09:18 source-128k.mp4
-rw-r--r--@ 1 sin  staff   8918617  6 12 09:15 source-1000k.mp4
-rw-r--r--@ 1 sin  staff   5324192  6 12 09:26 source-512k.mp4
-rw-r--r--@ 1 sin  staff  21047460  6 11 20:11 source.mp4

サイズは、ビットレートに応じて小さくなっていますが、表示して見ると、同時に動画の質が落ちていることが分かります。

オリジナル 21Mbyte

001

変換(1M bps) 8.9Mbyte

002

変換(512K bps) 5.3Mbyte

003

変換(128K bps) 2.3Mbyte

004

3 MP2作成

幾つかのビットレートのmp4を、前回紹介したmediafilesegmenterで、MP2(ts及びインデックス)に変換します。

-Iスイッチは、後で使用することになる.plistも同時に作成できるように追加しています。 

$ mkdir 1000k
$ mediafilesegmenter -f 1000k -i index.m3u8 -B media- -I source-1000k.mp4
$ mkdir 512k
$ mediafilesegmenter -f 512k -i index.m3u8 -B media- -I source-512k.mp4
$ mkdir 128k
$ mediafilesegmenter -f 128k -i index.m3u8 -B media- -I source-128k.mp4

出来上がったファイルは、下記のようになりました。これを、このままの状態でサーバーに置くことで、ユーザ(開発者)は、自由なビットレート(品質)の動画を指定することが可能です。

007

複数のビットレート(品質)の取得例としては、次のようなものになるでしょう。

<!DOCTYPE html>  
<div>  
  <h2>1M bps</h2>
  <video src="1000k/index.m3u8" width=640 height=360 controls></video>
  <h2>512K bps</h2>
  <video src="512k/index.m3u8" width=640 height=360 controls></video>
  <h2>128k bps</h2>
  <video src="128k/index.m3u8" width=640 height=360 controls></video>
</div>  

4 バリアントプレイリストクリエータ

(1) 代替ストリーム

HTTP Live Streamingでは、この幾つかのビットレートの選択を回線速度に合わせてダイナミックに最適に変化させることができます。

この機能を有効にするためには、今作成したビットレートごとの複数のインデックスを、1つに統合したマスターインデックスを作成し、そこをエンドポイントとします。

006

ここで、マスターインデックスで紐付けされた、各ストリームのデータは、代替ストリームと呼ばれます。

(2) バリアントプレイリストクリエータ

variantplaylistcreatorは、前回紹介した、HTTP Live Streaming Toolsに含まれるツールです。

variantplaylistcreatorを使用して、mediafilesegmenterの出力である代替ストリームのインデックスファイルをリストアップしマスタインデックスファイルを作成します。

variantplaylistcreatorの使用方法は次のとおりです。

variantplaylistcreator -o マスターインデックス名 1つ目のストリームセット 2つ目のストリームセット 3つ目のストリームセット

ストリームセットは、必要なだけ繰り返します。 そして、各ストリームセットの形式は、次の形です。

インデックスファイル名 plistファイル名 -iframe-url iframeファイル名

この形式に従った、実際のコマンドは、次のようになります。 これで、3種類の代替えストリーム(128Kbps,512Kbps,1Mbps)をまとめてた、マスターインデックス(all.m3u8)が生成されます。

$ variantplaylistcreator -o all.m3u8 128k/index.m3u8 source-128k.plist -iframe-url 128k/iframe_index.m3u8 512k/index.m3u8 source-512k.plist -iframe-url 512k/iframe_index.m3u8 1000k/index.m3u8 source-1000k.plist -iframe-url 1000k/iframe_index.m3u8
$ ls -la *.m3u8
-rw-r--r--  1 sin  staff  941  6 12 09:38 all.m3u8

(3) マスターインデックス

all.m3u8の中を見ると次のようになっています。

#EXTM3U
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=305152,BANDWIDTH=435408,CODECS="mp4a.40.2, avc1.64001f",RESOLUTION=1280x720,FRAME-RATE=24.000,CLOSED-CAPTIONS=NONE
128k/index.m3u8
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=18775,BANDWIDTH=158057,CODECS="avc1.64001f",RESOLUTION=1280x720,URI="128k/iframe_index.m3u8"
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=683340,BANDWIDTH=1388042,CODECS="mp4a.40.2, avc1.64001f",RESOLUTION=1280x720,FRAME-RATE=24.000,CLOSED-CAPTIONS=NONE
512k/index.m3u8
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=69403,BANDWIDTH=536518,CODECS="avc1.64001f",RESOLUTION=1280x720,URI="512k/iframe_index.m3u8"
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=1141220,BANDWIDTH=2008141,CODECS="mp4a.40.2, avc1.64001f",RESOLUTION=1280x720,FRAME-RATE=24.000,CLOSED-CAPTIONS=NONE
1000k/index.m3u8
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=118203,BANDWIDTH=820911,CODECS="avc1.64001f",RESOLUTION=1280x720,URI="1000k/iframe_index.m3u8"

注意して見てみると、代替ストリームごとにAVERAGE-BANDWIDTHBANDWIDTHあたりの値が違います。この辺が、ビットレートの違いを表しているのかも知れません。

そして、出来上がったマスターインデックスにアクセスページは、次のようになります。

index.html

<!DOCTYPE html>  
<div>  
  <h2>HTTP Live Streaming</h2>
  <video src="all.m3u8" width=640 height=360 controls></video>
</div>  

5 動作確認

今回は、PC上でWebサーバを起動して、アクセスログを見ながらテストしてみました。

構成は、VirtualBoxでWindows10を立ち上げ、BlackJumboDogでWebサーバを起動しました。 また、共有フォルダの機能で、Mac上の先ほどのリソースをWebサーバのドキュメントルートに設定し、MacのSafariからアクセスしています。

BlackJumboDog(ステマ)

009

Safariでアクセスした際の、Webサーバのログは次のようになりました。

2016/06/19 02:52:30 Web-1:8080  192.168.99.1    GET / HTTP/1.1  
2016/06/19 02:52:30 Web-1:8080  192.168.99.1    GET /all.m3u8 HTTP/1.1  
2016/06/19 02:52:30 Web-1:8080  192.168.99.1    GET /128k/index.m3u8 HTTP/1.1   
2016/06/19 02:52:30 Web-1:8080  192.168.99.1    GET /128k/media-0.ts HTTP/1.1   
2016/06/19 02:52:30 Web-1:8080  192.168.99.1    GET /128k/media-1.ts HTTP/1.1   
2016/06/19 02:52:30 Web-1:8080  192.168.99.1    GET /128k/media-2.ts HTTP/1.1   
2016/06/19 02:52:30 Web-1:8080  192.168.99.1    GET /128k/media-3.ts HTTP/1.1   
2016/06/19 02:52:31 Web-1:8080  192.168.99.1    GET /128k/media-4.ts HTTP/1.1   
2016/06/19 02:52:31 Web-1:8080  192.168.99.1    GET /128k/media-5.ts HTTP/1.1   
2016/06/19 02:52:31 Web-1:8080  192.168.99.1    GET /128k/media-6.ts HTTP/1.1   
2016/06/19 02:52:41 Web-1:8080  192.168.99.1    GET /1000k/index.m3u8 HTTP/1.1  
2016/06/19 02:52:42 Web-1:8080  192.168.99.1    GET /1000k/media-1.ts HTTP/1.1  
2016/06/19 02:52:42 Web-1:8080  192.168.99.1    GET /1000k/media-2.ts HTTP/1.1  
2016/06/19 02:52:42 Web-1:8080  192.168.99.1    GET /1000k/media-3.ts HTTP/1.1  
2016/06/19 02:52:42 Web-1:8080  192.168.99.1    GET /1000k/media-4.ts HTTP/1.1  
2016/06/19 02:52:42 Web-1:8080  192.168.99.1    GET /1000k/media-5.ts HTTP/1.1  
2016/06/19 02:52:42 Web-1:8080  192.168.99.1    GET /1000k/media-6.ts HTTP/1.1  
2016/06/19 02:52:51 Web-1:8080  192.168.99.1    GET /512k/index.m3u8 HTTP/1.1   
2016/06/19 02:52:51 Web-1:8080  192.168.99.1    GET /128k/media-5.ts HTTP/1.1   
2016/06/19 02:52:51 Web-1:8080  192.168.99.1    GET /128k/media-6.ts HTTP/1.1   
2016/06/19 02:52:58 Web-1:8080  192.168.99.1    GET /1000k/media-3.ts HTTP/1.1  
2016/06/19 02:52:58 Web-1:8080  192.168.99.1    GET /1000k/media-4.ts HTTP/1.1  
2016/06/19 02:52:58 Web-1:8080  192.168.99.1    GET /1000k/media-5.ts HTTP/1.1  
2016/06/19 02:52:59 Web-1:8080  192.168.99.1    GET /1000k/media-6.ts HTTP/1.1  
2016/06/19 02:53:03 Web-1:8080  192.168.99.1    GET /512k/index.m3u8 HTTP/1.1   
2016/06/19 02:53:03 Web-1:8080  192.168.99.1    GET /128k/media-5.ts HTTP/1.1   
2016/06/19 02:53:03 Web-1:8080  192.168.99.1    GET /128k/media-6.ts HTTP/1.1   

最初のアクセスでは、ビットレート128kのデータにアクセスしていましたが、その後、safariの動画を全画面表示にしたりすると高品質のデータを改めて取得しているのが分かりました。

どういう状況で、どの品質のデータにアクセスするのかは、ドキュメント化されていないためブラックボックスですが、確かに、複数の代替ストーリームにアクセスしていることは確認できました。

6 代替ストリーム作成上の注意

代替えストリームを作成する際には、次のような注意点が必要であるとドキュメントに記載されています。

  • バリアントプレイリストへ指定する最初のストーリームは、再生開始時に最初にテスト用にアクセスされます。その後の順序は関係ない

  • 可能な限り゙高品質のストリームが供給できるように、十分な代替ストリームを準備する (たとえば150kbps、350kbps、550kbps、900kbps、1500kbps等)

  • 可能であれば、マスターインデックスと各インデックスは相対パスを使用する

  • 代替ストリームのビデオのビデオアスペクト比は、正確に同一でなけれはならない

  • 携帯電話では150kのストリームが推奨され、Wi-Fiでは、240kまたは440kのストリームが推奨される

  • ストリームバリアントにビットレートを指定する場合、所定のストリームで要求される実際の帯域幅にBANDWIDTH属性をほぼ一致させることが重要

詳しくは、ドキュメントをご参照ください。
HTTPライブ ストリーミングの概要

7 最後に

今回は、HTTP Live Streamingで複数ストリームにダイナミックにアクセスする動作を確認してみました。作業は思ったより簡単で、代替ストリームさえ十分に準備すれば、あとは、お任せと言う感じです。

※動画は、ATTRIBUTION LICENSE 3.0 で公開されている、Jay Carpio氏のものを利用させて頂きました。
http://mazwai.com/#/videos/202

8 参考資料


FFmpeg Bitstream Filters Documentation 2.5 h264_mp4toannexb
How to set up HTTP Live Streaming (VOD) on Macbook using Apple's official tools 31 DECEMBER 2015
HTTP Live Streamingで動画を配信してみる
HTTPライブ ストリーミングの概要