こんにちは、動画チームのhagi@streampackです。

はじめに

今回は"Video on demand (VOD) HLSをPCで作成"について書きたいと思います。
mp4をそのまま置いてプログレッシブダウンロードでVODを提供することもできますが、HLSにしてABRや暗号化と組み合わせることでダウンロードをめんどくさくすることが可能な上、再配布も簡単にできないようにすることができます。

環境

配信について

HLSは特別な配信サーバーは必要ないです。
インターネットからアクセスできてプレイヤーが必要なファイルをダウンロードできれば再生できます。

今回は配信環境はs3としますがwebサーバーであれば配信可能です。

HLSの作成

ffmpeg、mediafilesegmenter(OSX)、Media Converter(AWS)などありますが今回は”簡単”に”ローカルPC”で作成という自己テーマなので簡単に利用できるツールと思い、そこでWindows/Mac/Linux用バイナリやソースコードがあるbento4を使います。

動画のHLS作成環境はMAC(OSX)としていますが他のOSでも大きく変わらないと思います。

bento4の準備

bento4とは

bento4(https://www.bento4.com)

A fast, modern, open source C++ toolkit for all your MP4 and MPEG DASH media format needs

要約:MP4とMPEG DASH用のツールキット

あれ、HLSは?

HLSについてはこちらに記述

While Bento4 is an MP4 file format library, and HLS uses the MPEG2 TS (Transport Stream) format, Bento4 includes a set of tools and functions that allow the conversion from MP4 to MPEG2 TS, as well as tools to create the .m3u8 playlists for HLS (HTTP Live Streaming).

意訳:MP4からMPEG2 TSの変換もできるのでHLSもできますよー

ただし入力ファイルはMP4である必要がある。

bento4のインストール

  1. ダウンロードページに行く https://www.bento4.com/downloads/
  2. OSに対応したパッケージをダウンロードする(今回はMAC OSX用)
  3. ダウンロードしたzipファイルを解凍

以上

mp4のhls化

上記で解凍したパッケージにはbinフォルダーがあり、いくつものコマンドが準備されています。各コマンドの一覧や詳細はこちらをご参照ください。

例:

Bento4-SDK-1-5-1-622.universal-apple-macosx/bin
aac2mp4         mp42avc         mp42ts          mp4dashclone        mp4dump         mp4extract      mp4iframeindex      mp4rtphintinfo
libBento4C.dylib    mp42hevc        mp4compact      mp4dcfpackager      mp4edit         mp4fragment     mp4info         mp4split
mp42aac         mp42hls         mp4dash         mp4decrypt      mp4encrypt      mp4hls          mp4mux          mp4tag

HLS化で利用するのが mp42hlsです。

Usage

usage: mp42hls [options]

一番簡単な使い方が

  1. HLSの格納フォルダーを作成 – コマンド実行場所が格納場所となってしまうため。
    $ mkdir <dir>
  2. 作成したフォルダーに移動
    $ cd <dir>
  3. コマンド実行
    $ mp42hls <動画>

例:

$ mkdir demohls
$ cd demohls
$ ../Downloads/Bento4-SDK-1-5-1-622.universal-apple-macosx/bin/mp42hls ../Downloads/Videos/demovid.mp4
$ ls
segment-0.ts    segment-1.ts    segment-2.ts    segment-3.ts    segment-4.ts    segment-5.ts    segment-6.ts    segment-7.ts    stream.m3u8

作成されたファイルについて

コマンドを実行しますと下記のファイルが作成されます。

segment-0.ts    segment-1.ts    segment-2.ts    segment-3.ts    segment-4.ts    segment-5.ts    segment-6.ts    segment-7.ts    stream.m3u8

*.m3u8 – プレイリスト
*.ts – mpeg2 ts データファイル

プレイリスト

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:7
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:7.382375,
segment-0.ts
#EXTINF:6.965292,
segment-1.ts
#EXTINF:7.090417,
segment-2.ts
#EXTINF:6.923583,
segment-3.ts
#EXTINF:6.923583,
segment-4.ts
#EXTINF:7.173833,
segment-5.ts
#EXTINF:7.007000,
segment-6.ts
#EXTINF:0.959292,
segment-7.ts
#EXT-X-ENDLIST

プレイリストには動画再生の順番や各ファイルの再生時間が記述されています。
プレイヤーはこのファイルの情報を元に動画を再生します。

ts データファイル

分割されたデータファイルです。

配信

1.プレイリスト+tsファイルを全てs3にアップロードします。
場合によってはPublicにするのを忘れずに
2.プレーヤーにアップロードされたs3のプレイリストを指定します。(Safariであればそのまま再生ができるはずです。)

https://s3-ap-northeast-1.amazonaws.com/XXXXXXXX/demo/segment.m3u8

オプション例

AES-128暗号化を利用したい

フォーマット

mp42hls --encryption-key --encryption-key-uri <video width="300" height="150">
```実行例
<pre class="brush:shell">
$ mp42hls --encryption-key 47de45c1b3931ab8baf4f7394bbecc02 --encryption-key-uri demo.key demovid.mp4
$ ls
demo.key    segment-0.ts    segment-1.ts    segment-10.ts   segment-2.ts    segment-3.ts    segment-4.ts    segment-5.ts    segment-6.ts    segment-7.ts    segment-8.ts    segment-9.ts    stream.m3u8
</pre>
マニフェスト内容

EXT-X-KEYにAES-128と鍵のURIが記述されていることを確認
<pre class="brush:shell">
$ cat stream.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="demo.key"
#EXTINF:6.715042,
segment-0.ts
#EXTINF:6.506500,
segment-1.ts
#EXTINF:8.133125,
segment-2.ts
#EXTINF:6.965292,
segment-3.ts
#EXTINF:6.464792,
segment-4.ts
#EXTINF:10.093417,
segment-5.ts
#EXTINF:6.506500,
segment-6.ts
#EXTINF:6.589917,
segment-7.ts
#EXTINF:6.673333,
segment-8.ts
#EXTINF:6.339667,
segment-9.ts
#EXTINF:7.507500,
segment-10.ts
#EXT-X-ENDLIST
</pre>
#### AES-128鍵の作成方法

いくつもの方法があると思いますがここではopensslでの作成方法を記述いたします。

適当な16byteの値を使って鍵を作成
<pre class="brush:shell">
$ openssl rand 16 > demo.key
</pre>
鍵のhex値を確認
<pre class="brush:shell">
$ xxd -ps demo.key
47de45c1b3931ab8baf4f7394bbecc02
</pre>
### ファイル名を指定したい

#### マニフェストのみ

フォーマット

$ mp42hls –index-filename .m3u8

実行例

$ mp42hls --index-filename demomanifest.m3u8 demovid.mp4
$ ls
demomanifest.m3u8   segment-0.ts        segment-10.ts       segment-3.ts        segment-5.ts        segment-7.ts        segment-9.ts
demovid.mp4     segment-1.ts        segment-2.ts        segment-4.ts        segment-6.ts        segment-8.ts

マニフェスト+データファイル名

フォーマット

$ mp42hls --index-filename <manifest filename="">.m3u8 --segment-filename-template <segment filename="">.%d.ts --segment-url-template <segment filename="">.%d.ts <video name="">
```</video></segment></segment></manifest>

実行例
<pre class="brush:shell">
$ mp42hls --index-filename demomanifest.m3u8 --segment-filename-template demoseg%d.ts --segment-url-template demoseg%d.ts demovid.mp4
$ ls
demomanifest.m3u8   demoseg1.ts     demoseg2.ts     demoseg4.ts     demoseg6.ts     demoseg8.ts     demovid.mp4
demoseg0.ts     demoseg10.ts        demoseg3.ts     demoseg5.ts     demoseg7.ts     demoseg9.ts
</pre>
マニフェスト内容
<pre class="brush:shell">
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:6.715042,
demoseg0.ts
#EXTINF:6.506500,
demoseg1.ts
#EXTINF:8.133125,
demoseg2.ts
#EXTINF:6.965292,
demoseg3.ts
#EXTINF:6.464792,
demoseg4.ts
#EXTINF:10.093417,
demoseg5.ts
#EXTINF:6.506500,
demoseg6.ts
#EXTINF:6.589917,
demoseg7.ts
#EXTINF:6.673333,
demoseg8.ts
#EXTINF:6.339667,
demoseg9.ts
#EXTINF:7.507500,
demoseg10.ts
#EXT-X-ENDLIST
</pre>
### segment長を指定したい

フォーマット

$ mp42hls –index-filename .m3u8 –segment-filename-template .%d.ts –segment-url-template .%d.ts –segment-duration  

実行例

$ mp42hls --index-filename demomanifest.m3u8 --segment-filename-template demoseg%d.ts --segment-url-template demoseg%d.ts --segment-duration 18 demovid.mp4
$ ls
demomanifest.m3u8   demoseg0.ts     demoseg1.ts     demoseg2.ts     demoseg3.ts     demoseg4.ts     demovid.mp4

マニフェスト内容

EXT-X-TARGETDURATIONをご確認ください。

$ cat demomanifest.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:19
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:18.226542,
demoseg0.ts
#EXTINF:18.435083,
demoseg1.ts
#EXTINF:18.184833,
demoseg2.ts
#EXTINF:19.936583,
demoseg3.ts
#EXTINF:3.712042,
demoseg4.ts
#EXT-X-ENDLIST

最後に

VODのHLS化はだいぶハードルが下がりmp4同様にウェブサーバーからの配信が可能です。
s3から配信すれば設定すらほぼいらずとなります。

またBento4はHLS作成以外にもMP4を操作して動画と音声を分けたり、MPEG-DASHを作成したり、動画に音声をつけたりも可能です。

https://www.bento4.com/documentation/

ぜひお試しください!

元記事はこちら

Video on demand (VOD) HLSをPCで作成