## やったこと
**要点**
250時間程度で動画のストリーミング配信及びサブスクリプションモデルを採用したwebサービスのバックエンドと一部インフラの実装を完遂
**詳細**
フロントエンジニア、インフラエンジニアと自分の合計3名で、業務委託という形でサービスの要件定義からローンチまですべてのバックエンド及び動画アップロード変換周りにおけるインフラの担当をしました。
2020年10月頃から要件定義を始め、年始から本格的に開発に着手しました。
副業という形なので月の稼働が50-60時間という中で、5月頭にリリースをしたので開発時間としては250時間程度でした。
## サービス概要
**要点**
認証済みスポーツ関係の方が動画を上げ、その投稿主のコミュニティに有料サブスク登録すると動画を見ることができる
**詳細**
こちらの審査のもと、オーナーとして登録されたスポーツ関係の職に従事しているユーザが関連する動画やイベント情報を公開でき、一般ユーザはオーナーにサブスクリプションすることでそれらのリソースを閲覧できるサービスです。
リリースから2ヶ月経った今も安定稼働しており、SLOなどの指標については現在は契約解除の関係で明記できませんがクリティカルな障害はリリース後まだなく、売上も着実に伸びてきているサービスとなっています。
## 技術詳細
**要点**
- API: golang
- サブスク: Stripe
- 動画まわり: elemental MediaConvert, lambda, S3, python
- そのた: github Actions, RDS, Elasticache, ECS
**詳細**
この開発ではGolangを用いてすべてのバックエンドのAPIを実装しました。
サブスクリプション周りについてはStripeを用いています。
インフラはすべてAWSに乗っており、自分はその中でも
- 動画をmp4やMOV形式のものからストリーミング形式であるm3u8に変換するためのelemental media convertのパラメータチューニング
- ユーザの動画アップロードトリガーで上記変換処理に投げるためのlambda
の実装をしました。
また、github actionsによるCICD環境や正規化されたテーブル設計、ログやエラーハンドリングなど、サービス開発に必要なものは一通り組み込まれています。
なお事業フェーズや開発スピード優先などの状況を考慮して、TerraformなどのIaCは利用せずにコンソールで構築しています。
## 技術的工夫ポイント
### ストレスのない動画アップロードの仕組みづくり
ユーザが動画をアップロードする際の体験にストレスを与えないために、アップロードに進捗率の概念をもたせつつ、動画の再アップロード時には **前回途中までアップロードしていた箇所の続きからアップロードを再開** させるようにさせました。
既存ライブラリがあるのですが、HTTPにしか対応しておらずSSL化させたAPIにその実装を乗せるのに苦労しました。
結論フロント側でHTTPヘッダをいじることで解決できたのですが、そこの調査でかなりサーバ側でも苦戦しました。
### 動画の変換
ユーザは基本的にmp4やMOVなどの形式で動画をアップロードしたいはずですが、それをそのままストレージに保存させると、アップロードした動画を視聴する際にストリーミング形式で閲覧できないため、動画視聴の体験がかなり損なわれてしまいます。
そこで、 **動画アップロード時にストリーミングに対応しているm3u8形式に変換させる** という対応をサーバ・インフラ側で入れました。
mp4でアップロードしてきたらまずS3にその動画を保存させ、その後裏でS3のアップロードをトリガーにしたLambdaが、elemental MediaConvertというAWSのマネージドサービスを呼び出してm3u8に変換させ、再度それをS3に保管させるという設計です。
こうすることで、動画アップロードと変換の作業を切り離せたのでユーザにとって最短で動画アップロードできるようにしつつも視聴者側はストリーミング形式で動画を閲覧できるようになりました。
### サービスの切り離し
動画アップロードにはかなりのメモリを専有されてしまうため、普通のAPIサーバとマシンを同居させるわけには行きませんでした。
そのため **動画アップロードのコンポーネントのみインフラを切り離してアプリ側も別でサービスを作成** しました。
ついでにそのサービスに動画のサムネアップロードも含めています。
アップロードのコンポーネントには通常のAPIサーバとhttpでやり取りしていて、動画アップロードの権限があるのかのチェックも挟んでいてマイクロサービスのような切り離し方をしています。