Schooの録画配信の裏側

## はじめに
本投稿は、Schooの2016年末特別企画「Schoo advent calendar 2016」の2日目の記事になります。

うちのマネジャーがどうしてもクリスマスまでの全日程を埋めたいらしくネタを探していたので連続ではありますが、2日目もネタを投下することになりましたｗ
（私が喋りたがりなので良いんですけどね。。。あっ、登壇依頼はいつでもWelcomeですｗ）

とはいえ、折角ですので中途半端なものにはしたくないので、Schooのシステム群の中から配信周りについて、更に今回は録画動画の配信に至るまでの手前の構成と、その処理の流れがどんな感じになっているかを記事化したいと思います。

## VOD（録画動画）の配信システム構成図
今回もまずは全体の構成図を貼り付けておきます。
ちなみに、たぶんこの資料は外部には（記事とかでは）初出しの資料かと思います！
<img width="1241" alt="スクリーンショット 2016-12-01 17.14.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/44355/c5ad5893-6f8b-6fe6-354c-66c142b1f816.png">

ザックリと説明するなら、AWSとAkamaiとを組み合わせた構成ですかね。。。
今回はこの中から、配信手前までの処理部分（AWSの部分）を以降にて説明したいと思います。

## 動画エンコードの仕組み
Schooの生放送をご覧になったことがある方はご存知かもしれませんが、弊社の放送は本放送の開始前と終了後に「チャイム」というような差込の動画が入っています。
録画動画の元ネタとなるRaw映像には、この部分が含まれていません。
手動での編集作業で組み込むことも可能にはなっていますが、この「チャイム動画」を動画の前後に挟み込んで一つの動画ファイルとしてエンコードする必要があるために、バッチ処理による再エンコード処理を実施する仕組みとなっています。

上記までの構成図だと、すこし簡略化しちゃっている部分でもあるので、このあたりのみを切り出した画像が以下になります。
<img width="1241" alt="スクリーンショット 2016-12-01 17.02.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/44355/6602c29d-0e42-cc84-7f2b-1ff9e0aa7eb3.png">

以降で、もう少し詳しく一つ一つを説明します。

### ①動画ファイルのアップロード
上記までの図でいうところの一番左側の弊社からの①の作業部分です。
先述しましたが、生放送のRaw動画はそのまま利用する場合もあれば、一部見辛い部分などを編集したものを録画用動画として用意します。
元ネタとなる動画のエンコードは社内にあるエンコード用のPCで、MP4コンテナでH.264+AACといったフォーマットでエンコードをします。
これをS3へとSFTPなどでアップロードします。

### ②エンコードQueueの登録
上記までの図の②の部分です。
SchooのバックエンドにはSQSを中心としたQueueベースのパイプライン処理が可能なBatch処理のシステムが存在しているのですが、この流れに乗せるためにS3のファイルアップロードイベントを利用しています。
このS3のイベント駆動でLambdaを動かす構成、よくあるパターンに今ではなっていますよね。
Schooでは、Lambdaは稼働時間とメモリ使用量でChargeされるので、「元動画がアップロードされたからエンコードしてくれ！」というQueueをSQSに書き込むだけの最小処理にしています。

### ③動画エンコード処理
③のこの部分、細かく書き始めるとチューニングが諸々してあり長くなりそうなところなので、ザックリと概要ベースで説明します。
Schooでは利用者の環境に合わせて、最終的に配信される動画のビットレートを基本3つ用意しています。
（授業によっては、もっと高ビットレートの配信をしている場合もありますが・・・）

* 1200kbps：高詳細動画としてWiFiや固定回線利用者向け
* 800kbps ：中画質動画として広く利用可能なビットレート
* 480kbps ：低画質動画として主にモバイル向け

弊社の動画はCDN（Akamai）で最終的には皆さんの手元に配信されるのですが、ラスト1マイルの通信環境をSchoo側からでは知ることができません。（当たり前ですが）
そこで、マルチビットレートで動画ファイルを用意して、動画配信先の通信速度にあわせたビットレートでの配信をしています。
つまりは、動画Player上でビットレートを指定することもできますが、デフォルトでは800kbpsで出して、回線速度が速ければ1200kbpsへ、遅ければ480kbpsへとシームレスにPlayer側で自動的に切り替えています。
（シームレスといってもHLSでの配信なので、セグメント単位になり10秒毎にはなっていますが・・・）

少し話が脱線気味なので、元に戻すと、、、
上記までの理由があり、3パターンのビットレートへと動画変換処理をQueueを利用して非同期で処理する仕組みになっています。
また、ここでは先にも書きましたが「チャイム動画」の動画の前後に連結する処理も行っています。
ちなみにこの処理の開始時と終了時に図では省略していますが、RDS（Aurora）に「動画エンコード中」の旨のステータス更新も行っています。
そして最後に、3つのビットレートで動画エンコードが正常に修了したら、これらをまとめてS3へとアップロードします。

### ④アップロードQueueの登録
3パターンのビットレートへの動画エンコードと「チャイム動画」の前後への連結が終わった動画はS3へとアップロードされ、それを②と同様にS3のイベントとして検知し起動するLambdaファンクションがあります。
ここのLambdaファンクションでは最終的に配信するCDN（Akamai）のストレージ（Netstorage）へと「エンコードが完了した授業動画があるからファイルをアップロードしてくれ！」というQueueをSQSへと登録します。

### ⑤ファイルのアップロード
④で登録されたQueueをアップローダが検知し、CDN（Akamai）のストレージ（Netstorage）へと動画ファイルをアップロードします。
またあわせてここではアップロード完了後の処理として、図では省略していますが、「録画配信の準備完了」の旨へのステータス変更をRDS（Aurora）に対して行っています。

ここまでが録画動画の公開前までの自動化された処理になります。

## まとめ
本システムの構築にあたっては、「いつ録画動画の編集がどんな形で（Outputとして）完了するか？」が作業者に委ねられているため、

* 非同期で動画エンコードを実行してくれる
* 動画エンコードの間に何らかの処理を組み込める（チャイムの結合など）

といったことが要件として必要でした。
そのためにアップロードに至るまでの処理を細分化し、各処理を非同期実行できるようにしました。

また現在は、更に進捗が確認できるようにするために各処理のステップ毎にSlackへの進捗通知もされるようになっています。
たとえばエンコード完了時は以下のような通知（一部マスクしてります）が飛んできます。
<img width="436" alt="スクリーンショット 2016-12-01 18.15.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/44355/f9682a7e-8915-d690-8b65-d27801ed9944.png">


さて、今回は「Schooといえば動画配信でしょ！？」というリクエストもあったので、動画配信周りを記事にしてみました。

前回の開発環境に引き続き2日連続でAdvent Calenderを担当しましたが、Schooでは結構色々と自動化のための仕組みを作り込んであったり、かなりAWS依存度も高い構成だったりもしますが、興味があり一緒に「システムを作っていきたい！」などの思いを持たれたら[Wantedlyにも募集ページ](https://www.wantedly.com/companies/schooWEBcampus/projects)がありますので、是非ご応募ください！

それでは、3日連続は無いと思いますが、次のかた宜しくお願いします！！