Amazon Elastic TranscoderのHLS出力方式の違いをまとめてみた

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

はじめに

清水です。Amazon Elastic TranscoderでHLS形式へのトランスコードを行うとき、 Playlist Formatとして「HSLv3」と「HLSv4」の2つが選択できます。 このHLSのv3とv4の違いについて今回はまとめてみます。

et-hls-001

AWSの公式ブログによりますと、Amazon Elastic TranscoderのHLS v4 Support の特徴として、Byte-Range RequestsLate Binding AudioI-Frame Only Playback の3点がリストアップされています。 *1

また、Black Belt Tech Webinar 2015の資料にも以下のようにまとまっています。

HLSv3とHLSv4の大きな違いとしては、Byte-Range RequestsLate Binding Audioの2点かと思います。Byte-Range Requestsにより、これまで大量に生成されていたsegment fileが1つに(厳密には動画、音声ごとの各ビットレートで1つに)まとまります。 また、Late Binding Audioにより動画と音声は別々のsegment fileで扱うことになります。

本エントリでは、上記の違いを踏まえたAmazon Elastic Transocoderでの HLSv3、HLSv4それぞれの形式での、ジョブ作成時の設定方法、 ならびに出力ファイル形式の違いなどをまとめてみます。

また実際にジョブを作成してトランスコードを行い、 出力ファイルを確認、さらに実際のPlayerからどのようにアクセスされているか、 アクセスログを元に確認をしてみました。

ジョブ設定方法と出力ファイルの違い

まずはElastic TranscoderでのHLSv3、HLSv4それぞれでジョブの設定方法と出力ファイルの違いをまとめてみます。

HLSv3

et-hls-002

HLSv3の場合はジョブ作成時にHLS形式のPresetを1つ *2選択します。 このとき、動画と音声両方のトランスコード設定が含まれているものを選びます。
またPlaylistも出力するように設定します。形式は「HLSv3」を指定して、指定したPresetで出力されるOutputを指定します。

Elastic Transcoderから得られる出力としては、 index file(拡張子が.m3u8のファイル)と、segment file(拡張子が.tsのファイル)となります。 index fileについてはおおもととなる本体(図中はPlaylist.m3u8としています)と、そこから読み込まれるもの(図中ではHLS.m3u8)の2つが生成されます。(Playlist.m3u8では実質HLS.m3u8の指定のみを行っています。) segment fileはElasit Transcoderにより自動的に00000, 00001, 00002, ... と連番が振られます。このファイルにはVideoとAudioの両方のデータが含まれています。

Playerが再生するときにはindex fileがPlaylist.m3u8、HLS.m3u8の順に読み込まれて、HLS.m3u8に記載されているsegment fileを順にダウンロードして再生していく、という流れになります。

HLSv4

et-hls-003

HLSv4の場合はジョブ作成時、Presetを動画のみのもの、音声のみのものをそれぞれ指定します。 Playlistも出力するように設定します。形式は「HLSv4」を指定して、HLSv4では2つのPresetそれぞれから出力されるOutput情報を指定します。

Elastic Transcoderから得られる出力としては、HLSv3と同様に大きくindex fil(拡張子.m3u8)とsegment file(拡張子.ts)の2種ですが、それぞれの個数に注目しましょう。index fileについてはおおもととなる本体(図中ではPlaylist.m3u8)と、Video用(HLS_Video_v4.m3u8)、Audio用(HLS_Audio_v4.m3u8)、さらにI-Frame Only用(HLS_Video_iframe.m3u8)の合計4種類となります。segment fileについてはVideo用(HLS_Video.ts)とAudio用(HLS_Audio.ts)の2種類のみとなります。segment fileといいながらファイルとしては1つにまとまっているのが特徴かと思います。

Playerが再生するときにはindex fileが読み込まれます。おおもととなるPlaylist.m3u8からVideo用、Audio用を読み込み、そこに記載されているVideoのみ、Audioのみのファイルをそれぞれダウンロード、再生していきます。このとき、ダウンロードする部分はindex fileのEXT-X-BYTERANGEに記載されている部分のみとなり、これがセグメントに該当します。実際にはHLSv3と同じようにこのセグメント部分を順次ダウンロード、再生していくというに流れになります。

実際にジョブを作成してみた

では実際にElastic Transocoderのジョブを作成して、HLSv3、HLSv4それぞれの形式でトランスコードをしてみます。

Elastic Transcoderのパイプラインは先に作成しておき、 またプリセットについてはデフォルトで用意されているシステムプリセットを使用します。 システムプリセットは下記のページを参考に、PresetIdを控えます。

今回は下記としました。HLSv4については、1. 動画(Video)のみのプリセット2. 音声(Audio)のみのプリセットの2つを使用します。

  • HLSv3
    • HLS v3(Apple HTTP Live Streaming)、1 メガビット/秒
      • PresetId: 1351620000001-200030
  • HLSv4
    • HLS v3 および v4(Apple HTTP Live Streaming)、1 メガビット/秒、動画のみ
      • PresetId: 1351620000001-200035
    • HLS v3 および v4 音声、160k
      • PresetId: 1351620000001-200060

トランスコードの元になる入力ファイルは、尺が1分(厳密には1分と1秒未満)。
またHLSプリセットで指定するSegment DurationはHLSv3、HLSv4ともに6秒としています。

また、今回はジョブの作成の設定をjsonファイルとしてまとめて、 AWS CLIのelastictranscoder create-jobコマンドを使い、--cli-input-jsonオプションの引数とすることで実行しました。

HLSv3でのトランスコードジョブ作成

HLSv3形式のトランスコードジョブを作成するときのポイントとしては以下となります。

  • OutputsのPresetは1つだけ(動画+音声のトランスコード設定が含まれたもの)
  • Playlistでは「HLSv3」を指定。(Management Consoleでは選択)
    • 中身はPresetで指定したものを指定(選択)

この点を含めた設定をSample6_HLSv3.jsonとしてまとめて、 AWS CLIのコマンド
aws elastictranscoder create-job --cli-input-json file://Sample6_HLSv3.json
で実行しました。

{
    "PipelineId": "1234567890123-456789",
    "Input": {
        "Key": "elastictranscoder-input/Sample6.mov"
    },
    "OutputKeyPrefix": "elastictranscoder-output/HLS/v3/",

    "Outputs": [
        {
            "Key": "Sample6/HLS",
            "PresetId": "1351620000001-200030",
            "SegmentDuration": "6"
        }
    ],

    "Playlists": [
        {
            "Name": "Sample6/Playlist",
            "Format": "HLSv3",
            "OutputKeys": [
                "Sample6/HLS"
            ]
        }
    ]
}

HLSv4でのトランスコードジョブ作成

HLSv4形式のトランスコードジョブを作成するときのポイントとしては以下となります。

  • OutputsのPresetは動画のみのプリセット音声のみのプリセットの2つを指定
  • Playlistでは「HLSv4」を指定。
    • 中身はOutputsで指定した2つのPresetを指定

HLSv4でも同じように、この点を含めた設定を以下に示すSample6_HLSv4.jsonとしてまとめて、 AWS CLIで実行しました。

{
    "PipelineId": "1234567890123-456789",
    "Input": {
        "Key": "elastictranscoder-input/Sample6.mov"
    },
    "OutputKeyPrefix": "elastictranscoder-output/HLS/v4/",

    "Outputs": [
        {
            "Key": "Sample6/HLS_Video",
            "PresetId": "1351620000001-200035",
            "SegmentDuration": "6"
        },
        {
            "Key": "Sample6/HLS_Audio",
            "PresetId": "1351620000001-200060",
            "SegmentDuration": "6"
        }
    ],

    "Playlists": [
        {
            "Name": "Sample6/Playlist",
            "Format": "HLSv4",
            "OutputKeys": [
                "Sample6/HLS_Video",
                "Sample6/HLS_Audio"
            ]
        }
    ]
}

生成されたファイルを確認してみた

トランスコードジョブが完了後、生成されたファイルを確認してみました。

ファイル一覧の確認

まずは生成されたファイルについて、index file、segment fileそれぞれがどの位あるのか確認してみます。S3上のファイルなのでaws s3 lsコマンドでS3バケットのディレクトリ一覧を取得しました。

HLSv3ではtsファイルがセグメント個数の分だけ作成されています。 (61秒の尺でセグメントが6秒なので、合計11個。) またPlaylist(m3u8)ファイルは2つだけです。

HLSv4ではその特徴であるように、tsファイルは大量に生成されていません。 Video用とAudio用の2つだけとなります。 またPlaylistについては、おおもとのファイル(Playlist.m3u8)の他、 Video用、Audo用、そしてI-Frame用が生成されました。

HLSv3の生成ファイル

 $ aws s3 ls s3://mys3bucket/elastictranscoder-output/HLS/v3/Sample6/
2016-09-12 18:06:27        441 HLS.m3u8
2016-09-12 18:06:27     835096 HLS00000.ts
2016-09-12 18:06:27     830020 HLS00001.ts
2016-09-12 18:06:27     858408 HLS00002.ts
2016-09-12 18:06:27     771176 HLS00003.ts
2016-09-12 18:06:27     813852 HLS00004.ts
2016-09-12 18:06:27     778132 HLS00005.ts
2016-09-12 18:06:27     782832 HLS00006.ts
2016-09-12 18:06:27     781140 HLS00007.ts
2016-09-12 18:06:27     923644 HLS00008.ts
2016-09-12 18:06:27     992640 HLS00009.ts
2016-09-12 18:06:27     145136 HLS00010.ts
2016-09-12 18:06:29        116 Playlist.m3u8

HLSv4の生成ファイル

 $ aws s3 ls s3://mys3bucket/elastictranscoder-output/HLS/v4/Sample6/
2016-09-12 18:06:46    1383868 HLS_Audio.ts
2016-09-12 18:06:46        802 HLS_Audio_v4.m3u8
2016-09-12 18:06:54    7673972 HLS_Video.ts
2016-09-12 18:06:53       1600 HLS_Video_iframe.m3u8
2016-09-12 18:06:53        871 HLS_Video_v4.m3u8
2016-09-12 18:06:56        458 Playlist.m3u8

各Playlistファイルの内容の確認

続いて、HLSv3、HLSv4それぞれのPalylistのファイルの中身も確認してみます。 こちらもS3バケット内のファイルです。中身をみるために aws s3 cp s3://[ファイルへのパス] -と、s3 cpコマンドのコピー先を-とすることで標準出力に直接書き出しています。

HLSv3のPlaylistファイルの内容

起点となるindex fileはトランスコードジョブ作成時に指定した Playlist.m3u8ですので、まずはこれを確認してみます。

 $ aws s3 cp s3://mys3bucket/elastictranscoder-output/HLS/v3/Sample6/Playlist.m3u8 -
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1203000,RESOLUTION=640x360,CODECS="avc1.4d001f,mp4a.40.2"
HLS.m3u8

こちらから、HLS.m3u8を確認してみます。

 $ aws s3 cp s3://mys3bucket/elastictranscoder-output/HLS/v3
/Sample6/HLS.m3u8 -
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:7
#EXTINF:6.070311,
HLS00000.ts
#EXTINF:6.003600,
HLS00001.ts
#EXTINF:6.003611,
HLS00002.ts
#EXTINF:6.003611,
HLS00003.ts
#EXTINF:6.003611,
HLS00004.ts
#EXTINF:6.003600,
HLS00005.ts
#EXTINF:6.003600,
HLS00006.ts
#EXTINF:6.003600,
HLS00007.ts
#EXTINF:6.003600,
HLS00008.ts
#EXTINF:6.003600,
HLS00009.ts
#EXTINF:0.900533,
HLS00010.ts
#EXT-X-ENDLIST

セグメントファイルが順番に列挙されたファイルでした。 Player側はこのファイルから、時間に応じた該当するセグメントファイルを順次読み込んでいくかたちになります。

HLSv4

HLSv4でも、起点となるのはindex fileはトランスコードジョブ作成時に指定した Playlist.m3u8になります。まずこちらを確認してみます。

 $ aws s3 cp s3://mys3bucket/elastictranscoder-output/HLS/v4/Sample6/Playlist.m3u8 -
#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-0",NAME="Default",AUTOSELECT=YES,DEFAULT=YES,URI="HLS_Audio_v4.m3u8"
#EXT-X-I-FRAME-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=16389000,CODECS="avc1.4d001e",URI="HLS_Video_iframe.m3u8"
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1376000,RESOLUTION=640x360,CODECS="avc1.4d001e,mp4a.40.2",AUDIO="audio-0"
HLS_Video_v4.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=182000,CODECS="mp4a.40.2",AUDIO="audio-0"
HLS_Audio_v4.m3u8

Video、Audioがそれぞれ分かれてPlaylistファイルで指定されています。 まず、HLS_Video_v4.m3u8を確認してみます。

 $ aws s3 cp s3://mys3bucket/elastictranscoder-output/HLS/v4/Sample6/HLS_Video_v4.m3u8 -
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:7
#EXTINF:6.003611,
#EXT-X-BYTERANGE:810656@0
HLS_Video.ts
#EXTINF:6.003611,
#EXT-X-BYTERANGE:742412@810656
HLS_Video.ts
#EXTINF:6.003611000000001,
#EXT-X-BYTERANGE:784712@1553068
HLS_Video.ts
#EXTINF:6.003611999999997,
#EXT-X-BYTERANGE:668152@2337780
HLS_Video.ts
#EXTINF:6.003622,
#EXT-X-BYTERANGE:705000@3005932
HLS_Video.ts
#EXTINF:6.003610999999999,
#EXT-X-BYTERANGE:719288@3710932
HLS_Video.ts
#EXTINF:6.003610999999999,
#EXT-X-BYTERANGE:697480@4430220
HLS_Video.ts
#EXTINF:6.003610999999999,
#EXT-X-BYTERANGE:738276@5127700
HLS_Video.ts
#EXTINF:6.0036110000000065,
#EXT-X-BYTERANGE:777380@5865976
HLS_Video.ts
#EXTINF:6.003610999999999,
#EXT-X-BYTERANGE:896572@6643356
HLS_Video.ts
#EXTINF:0.9005560000000017,
#EXT-X-BYTERANGE:134044@7539928
HLS_Video.ts
#EXT-X-ENDLIST

segment fileはHLS_Video.tsのみで、 EXT-X-BYTERANGEの項目があることが確認できます。 PlayerはHLS_Video.tsを読み込みますが、時間に応じた部分だけ、部分取得を行うことになります。

つづいてAudio側のHLS_Audio_v4.m3u8も確認してみます。

 $ aws s3 cp s3://mys3bucket/elastictranscoder-output/HLS/v4/Sample6/HLS_Audio_v4.m3u8 -
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:7
#EXTINF:6.083633000000001,
#EXT-X-BYTERANGE:138744@0
HLS_Audio.ts
#EXTINF:6.1300669999999995,
#EXT-X-BYTERANGE:139684@138744
HLS_Audio.ts
#EXTINF:6.130066999999999,
#EXT-X-BYTERANGE:138932@278428
HLS_Audio.ts
#EXTINF:6.130066000000003,
#EXT-X-BYTERANGE:137804@417360
HLS_Audio.ts
#EXTINF:6.130067,
#EXT-X-BYTERANGE:138744@555164
HLS_Audio.ts
#EXTINF:6.1300779999999975,
#EXT-X-BYTERANGE:139684@693908
HLS_Audio.ts
#EXTINF:6.130065999999999,
#EXT-X-BYTERANGE:138932@833592
HLS_Audio.ts
#EXTINF:6.130067000000004,
#EXT-X-BYTERANGE:139684@972524
HLS_Audio.ts
#EXTINF:6.106845,
#EXT-X-BYTERANGE:137992@1112208
HLS_Audio.ts
#EXTINF:5.944299999999998,
#EXT-X-BYTERANGE:133668@1250200
HLS_Audio.ts
#EXT-X-ENDLIST

こちらもVideoの場合と同様、 segment fileとしてはHLS_Audio.tsのみで、EXT-X-BYTERANGEを 使って、時間に応じた部分だけ、HLS_Audioから部分取得を行うことがわかります。

なお、変換元動画の尺は1分(厳密には1分と1秒未満)だったので、HLSv3のindex file、 HLSv4のHLS_Video_v4.m3u8でsegment fileにそれぞれ11回アクセスしているのは、 Segment Durationが6秒であることと合致しているのですが、このHLS_Audio_v4.m3u8には segment fileの記述は10個だけでした。こちらについてはどういう仕組かはつかめておりません。

配信時のアクセスログを確認してみた

続いて、配信時のアクセスログを確認することで、Player側が実際にどのようにデータを取得しているか探ってみました。

Elastic Transcoderはトランスコード後のファイルをS3に出力するので、 S3からの配信や、CloudFront+S3な構成で配信することが実践的なやり方ですが、 今回はアクセスログを簡単に確認するため、EC2上のAmazon LinuxにApacheをインストール、 こちらにトランスコード後のファイルをコピーしてApacheから配信しました。 このApacheアクセスログを確認してみます。

PlayerはiPhoneです。SafariでPlaylistのm3u8ファイルに直接アクセスしました。

Apacheアクセスログの詳細は下記にまとめます。アクセスログのフォーマットとして、デフォルトで設定されていたcombinedのフォーマットの末尾に\"%{Range}i\"を付けて、Rangeヘッダについてもログを取るようにしました。最終的には以下のフォーマットとなっています。 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" "\"%{Range}i\" combined

HLSv3の場合はsegment fileの連番を順番に読み込んでいることがわかります。また、Rangeヘッダについてはいずれも特に指定がありませんでした。 HLSv4の場合は、アクセスしているsegment fileはHLS_Video.tsまたはHLS_Audio.tsで、これらに複数回アクセスしています。 ですが、Rangeヘッダのログをみると、それぞれ異なる範囲のデータを取得している事がわかります。また、アクセス回数については、 index fileに記載されていた通り、Videoについては11回、Audioについては10回の合計21回でした。 また、segment fileへのアクセスの際のレスポンスステータスコードは206となり、Partial Content(部分的内容)を行っていることも確認できました。

HLSv3の場合のアクセスログ

49.98.161.76 - - [15/Sep/2016:12:20:31 +0900] "GET /HLS/v3/Sample6/Playlist.m3u8 HTTP/1.1" 200 116 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:31 +0900] "GET /HLS/v3/Sample6/HLS.m3u8 HTTP/1.1" 200 441 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:31 +0900] "GET /HLS/v3/Sample6/HLS00000.ts HTTP/1.1" 200 835096 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:32 +0900] "GET /HLS/v3/Sample6/HLS00001.ts HTTP/1.1" 200 830020 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:32 +0900] "GET /HLS/v3/Sample6/HLS00002.ts HTTP/1.1" 200 858408 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:32 +0900] "GET /HLS/v3/Sample6/HLS00003.ts HTTP/1.1" 200 771176 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:33 +0900] "GET /HLS/v3/Sample6/HLS00004.ts HTTP/1.1" 200 813852 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:33 +0900] "GET /HLS/v3/Sample6/HLS00005.ts HTTP/1.1" 200 778132 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:33 +0900] "GET /HLS/v3/Sample6/HLS00006.ts HTTP/1.1" 200 782832 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:34 +0900] "GET /HLS/v3/Sample6/HLS00007.ts HTTP/1.1" 200 781140 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:34 +0900] "GET /HLS/v3/Sample6/HLS00008.ts HTTP/1.1" 200 923644 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:34 +0900] "GET /HLS/v3/Sample6/HLS00009.ts HTTP/1.1" 200 992640 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:20:35 +0900] "GET /HLS/v3/Sample6/HLS00010.ts HTTP/1.1" 200 145136 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:21:25 +0900] "GET /HLS/v3/Sample6/HLS.m3u8 HTTP/1.1" 200 441 "http://52.192.101.69/HLS/v3/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"

HLSv4の場合のアクセスログ

49.98.161.76 - - [15/Sep/2016:12:22:52 +0900] "GET /HLS/v4/Sample6/Playlist.m3u8 HTTP/1.1" 200 458 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Video_v4.m3u8 HTTP/1.1" 200 871 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Audio_v4.m3u8 HTTP/1.1" 200 802 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 810656 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=0-810655"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 138744 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=0-138743"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 139684 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=138744-278427"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 742412 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=810656-1553067"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 138932 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=278428-417359"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 137804 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=417360-555163"
49.98.161.76 - - [15/Sep/2016:12:22:53 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 784712 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=1553068-2337779"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 138744 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=555164-693907"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 668152 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=2337780-3005931"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 139684 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=693908-833591"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 138932 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=833592-972523"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 705000 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=3005932-3710931"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 139684 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=972524-1112207"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 137992 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=1112208-1250199"
49.98.161.76 - - [15/Sep/2016:12:22:54 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 719288 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=3710932-4430219"
49.98.161.76 - - [15/Sep/2016:12:22:55 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 697480 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=4430220-5127699"
49.98.161.76 - - [15/Sep/2016:12:22:55 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 738276 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=5127700-5865975"
49.98.161.76 - - [15/Sep/2016:12:22:56 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 777380 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=5865976-6643355"
49.98.161.76 - - [15/Sep/2016:12:22:56 +0900] "GET /HLS/v4/Sample6/HLS_Audio.ts HTTP/1.1" 206 133668 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=1250200-1383867"
49.98.161.76 - - [15/Sep/2016:12:22:56 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 896572 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=6643356-7539927"
49.98.161.76 - - [15/Sep/2016:12:22:56 +0900] "GET /HLS/v4/Sample6/HLS_Video.ts HTTP/1.1" 206 134044 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "bytes=7539928-7673971"
49.98.161.76 - - [15/Sep/2016:12:23:46 +0900] "GET /HLS/v4/Sample6/HLS_Video_v4.m3u8 HTTP/1.1" 200 871 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"
49.98.161.76 - - [15/Sep/2016:12:23:46 +0900] "GET /HLS/v4/Sample6/HLS_Audio_v4.m3u8 HTTP/1.1" 200 802 "http://52.192.101.69/HLS/v4/Sample6/Playlist.m3u8" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1" "-"

まとめ

Amazon Elastic TranscodeのHLS形式の出力の際に指定できるPlaylist Format、HLSv3とHLSv4についてまとめてみました。

HLSv4ではByte-Range Requestsが利用できるため、これまで大量に(それこそ数千個単位で!?)作成されていたsegment fileがまとまり、 ファイル管理が容易になりますね。対応バージョンとしてはiOS 5以上、Android 4.4以上ということですので、互換性には少し気をつける必要があるかもしれませんが、 そこがクリアできればぜひ導入を検討してみてはいかがでしょうか?
たくさんの.tsから解放されます!

脚注

  1. 公式ブログでHLSv4のサポートの発表は2014/10/13でした。だいぶ前のことでしたね。。
  2. Adaptive bitrateとするときは複数指定しますが、今回はSingle bitrate配信を前提として進めます。