テスト用のHTTP Live Streamingの環境構築


# 目的、前提条件
- AndroidやiOSのプレイヤーでHLSの視聴時のアクセスログを確かめたい。
- そのためのHLSの配信環境をmacOS上で構築する。
- ローカルネットワークでの確認のため、CDNへの配置は行わない。
- macOS上のファイルストレージにHLSのファイルを書き出し、それをApacheでStreamingできるようにする。

# 使うもの
- macOS 10.14.6（18G3020）
- Apache2
- [shaka-streamer](https://google.github.io/shaka-streamer/)
- python3


# インストール・設定・動作確認

使用するpython3のバージョンは以下の通り。インストールは割愛。

```
$ python3 -V
Python 3.7.4
$ pip3 -V
pip 19.1.1 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)
```

## Apache2

### インストール

```
$ brew install httpd
```

### 動作確認
使い方を探っているといろんなホームページが出てきてどれが一番いいかわからなかったのだけど、 `brew info` コマンドを使えば色々情報が得られた。これは他のソフトウェアで困った時にも思い出したい。
（あとでわかったのだけど、インストール時にちゃんと同じような情報が表示されていた。今度からちゃんと読もう。。）

```
$ brew info httpd
httpd: stable 2.4.41 (bottled)
Apache HTTP server
https://httpd.apache.org/
/usr/local/Cellar/httpd/2.4.41_1 (1,652 files, 27.2MB) *
  Poured from bottle on 2020-02-06 at 22:00:02
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/httpd.rb
==> Dependencies
Required: apr ✔, apr-util ✔, brotli ✔, nghttp2 ✔, openssl@1.1 ✔, pcre ✔
==> Caveats
DocumentRoot is /usr/local/var/www.

The default ports have been set in /usr/local/etc/httpd/httpd.conf to 8080 and in
/usr/local/etc/httpd/extra/httpd-ssl.conf to 8443 so that httpd can run without sudo.

To have launchd start httpd now and restart at login:
  brew services start httpd
Or, if you don't want/need a background service you can just run:
  apachectl start

...
```

起動してみて、 `http://127.0.0.1:8080/` で動いていることを確認してみる。

```
$ sudo brew services start httpd
```

デフォルトのdocument rootは `/usr/local/var/www` のようなので、適当な作業ディレクトリ（`$WORKDIR`とする）を作成してそのシンボリックリンクを作っておく。

```
$ cd /usr/local/var/www
$ ln -s $WORKDIR/www streaming
$ touch $WORKDIR/www/index.html
$ echo 'hogehoge' > $WORKDIR/www/index.html

ブラウザで http://127.0.0.1:8080/streaming/ を開いて確認
```

今回の目的は「アクセスログの確認」なので、アクセスログも確認。

```
$ tail -f /usr/local/var/log/httpd/access_log
```

一旦これでApache2の確認終了。

## shaka-streamer

[shaka-streamerの公式のドキュメント](https://google.github.io/shaka-streamer/)を参考にする。

```
$ pip3 install --user --upgrade shaka-streamer
```

`pip3 show -f shaka-streamer`で内容を確認すると、実行バイナリが`$HOME/Library/Python/3.7/bin/shaka-streamer` にインストールされてい流ようであるのが確認できた。念の為、helpがちゃんと表示されるか確認する。

```
$ python3 $HOME/Library/Python/3.7/bin/shaka-streamer --help
```

### 必要な他のソフトウェア
shaka-streamerの動作のためには以下もインストールが必要なようなので、これもインストールする。
[こちらのページ](https://google.github.io/shaka-streamer/prerequisites.html)を参考。

- Python “yaml” module
- Shaka Packager
- FFmpeg

インストールはpip3やbrewを使って可能なので割愛。 Shaka Packagerはバイナリをダウンロードした方が楽。
Shaka PackagerとFFmpegのバイナリファイルのパスは、環境変数PATHに加えておく。

### 試してみる

[shaka-streamerのリポジトリのconfig_files](https://github.com/google/shaka-streamer/tree/master/config_files)から、 `input_looped_file_config.yaml` と `pipeline_live_config.yaml` をダウンロードして編集する。

- 編集したものはそれぞれ`$WORKDIR/input.yaml` `$WORKDIR/pipeline.yaml`とする
- また使用する動画は`my_video.mp4`とし`$WORKDIR`に配置しているものとする



#### 入力設定（$WORKDIR/input.yamlの編集）

```yaml:$WORKDIR/input.yaml
inputs:
  - input_type: looped_file
    name: my_video.mp4
    media_type: video

  - input_type: looped_file
    name: my_video.mp4
    media_type: audio
```

#### 出力設定（$WORKDIR/pipeline.yamlの編集）
色々変更してますが、説明はあとで。

```yaml:$WORKDIR/pipeline.yaml
streaming_mode: live
resolutions:
  - 360p
  - 144p
channels: 1
audio_codecs:
  - aac
video_codecs:
  - h264
manifest_format:
  - hls

segment_size: 4
availability_window: 300
presentation_delay: 30
update_period: 8
```

- resolutionsは小さめで（FFmpegでのエンコードにあまり負荷がかからないようにするため）
- manifest_formatはhlsだけで（今回MPEG-DASHは確認しないため）
- segment_sizeおよびsegment_size以降は、オリジナルのファイルから変えていない

### shaka-streamerを実行

用意が完了したらshaka-streamerを実行してみる。

```
$ python3 $HOME/Library/Python/3.7/bin/shaka-streamer \
    -i $WORKDIR/input.yaml \
    -p $WORKDIR/pipeline.yaml \
    -o $WORKDIR/www/
```

問題がなければ `http://127.0.0.1:8080/streaming/hls.m3u8` というファイルがダウンロードできるようになる。 `ffplay` or Safariで再生をして確かめてみる。

再生ができたらしばらく再生を続け問題が出ないか確認しておく。


### （追記）pipelineの修正

このままだと全体で300秒程度のウィンドウとなった。
検証に使用するLiveのストリーミングはもう少し小さくてもいいので、以下のようにする。

```
segment_size: 2
availability_window: 10
presentation_delay: 10
update_period: 4
```

`curl`でm3u8を確認すると、以下のようなm3u8が得られるようになった。理想通り。
（configのドキュメントを確認していないため、この設定が最適な値かどうかでいうと確認していない。**あくまで他のサービスのHLSと似たようなストリームになればいい、というレベルの設定であり、また少しいじったらすぐ理想な出力になったので調査を全く行っていない。妥当な設定であるかどうかは不明であることはご了承いただきたい。**）

```
$ curl http://127.0.0.1:8080/streaming/hls.m3u8
#EXTM3U
## Generated with https://github.com/google/shaka-packager version v2.4.1-c731217-release

#EXT-X-MEDIA:TYPE=AUDIO,URI="stream_0.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="1"

#EXT-X-STREAM-INF:BANDWIDTH=902931,AVERAGE-BANDWIDTH=590832,CODECS="avc1.42c01e,mp4a.40.2",RESOLUTION=640x360,FRAME-RATE=24.000,AUDIO="default-audio-group"
stream_1.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=328135,AVERAGE-BANDWIDTH=255892,CODECS="avc1.42c00c,mp4a.40.2",RESOLUTION=256x144,FRAME-RATE=24.000,AUDIO="default-audio-group"
stream_2.m3u8


$ curl http://127.0.0.1:8080/streaming/stream_1.m3u8
#EXTM3U
#EXT-X-VERSION:6
## Generated with https://github.com/google/shaka-packager version v2.4.1-c731217-release
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:22
#EXT-X-MAP:URI="video_360p_400k_init.mp4"
#EXTINF:2.000,
video_360p_400k_23.mp4
#EXTINF:2.000,
video_360p_400k_24.mp4
#EXTINF:2.000,
video_360p_400k_25.mp4
#EXTINF:2.000,
video_360p_400k_26.mp4
#EXTINF:2.000,
video_360p_400k_27.mp4
#EXTINF:2.000,
video_360p_400k_28.mp4
```

上記の設定で出来上がったHLSのストリームを再生するAndroid/iOSのアプリ、およびアプリで再生した際の確認結果については、別途書く。