0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQS を使った動画配信基盤

Posted at

目的

私が実装した動画配信の仕組みを見ながら、動画配信に必要な基本知識を理解することが目的です。

インフラ構成

  • 以下に今回使用したリソースを挙げます
    • CloudFront
    • S3
    • SQS
    • EventBridge
    • Cognito
    • Mediaconvert
    • EKS
    • Aurora
  • 以前は SNS + ラムダの構成でしたが、以下の理由でSQSに移行しました。
    • ラムダから EKS の api を叩く方法だと、EKS が落ちたらジョブが失われてしまう
    • ラムダの保守性が低い

流れ

アップロード

  1. ユーザは cognito にログイン
    1. ユーザは SDK を通じて cognito からトークンを取得します
  2. ユーザは、先ほどもらったアクセストークンを使って、S3 にアクセスするための identityId, STS トークンを Cognito から取得します
  3. ユーザはアプリに動画作成のリクエストを送ります
    1. もちろん、ここでは動画のメタ情報をアプリDB(Aurora)に登録するだけです
    2. ステータスは UserUploadPrepared にします
    3. 同時に、S3 のアップロードのエンドポイントをもらいます
      1. フロントで S3 のアップロードのエンドポイントを構築してもいいです
  4. ユーザは、STSトークンを使って、S3に直接動画をアップロードします
    1. IAM Policy の設定により、S3 内の自分のフォルダ(identityId によって判別)以外へのアップロードは禁止されています
    2. 本プロジェクトのフロントは、簡易的な C++ デスクトップアプリで実装したので、SDK For C++ を使いました
      1. TransferManager クラスを使うことで、進捗を把握するためのプログレスバーを実装することができます
  5. S3 へのアップロードが完了したら、S3 イベント通知により SQS キュー(video upload queue)にメッセージが送信されます
  6. EKS 上のワーカーが5秒間隔で SQS をポーリングし、アップロードされたファイルを処理します
    1. ファイルの拡張子とContent-Typeの整合性をチェック(こちらの記事を参考)
      1. 拡張子とContent-Typeが一致しない場合、ステータスを UserUploadInvalidPath に設定
      2. 整合性チェックに通った場合、まずステータスを UserUploadComplete に設定
    2. 画像ファイル(PNG, JPG)の場合は MediaConvert 処理をスキップして処理完了
    3. 動画ファイルの場合、MediaConvert の Probe API を使用して解像度、フレームレート、再生時間を取得
      1. 取得した情報:幅(Width)、高さ(Height)、FPS(Numerator/Denominator)、再生時間(Duration)
    4. MediaConvert にジョブを作成し、ステータスを MediaconvertJobCreated に更新
  7. MediaConvert はアップロードされた mp4 や mov を、ストリーミング再生可能な HLS に変換して、S3 に配置します
    1. HLS は、各セグメントのメタデータを保持する m3u8 ファイルと、実際の動画データを持つ ts ファイルから構成されます
  8. EventBridge は、MediaConvert の状態変化を監視し、完了通知を SQS キューに送信します
    1. MediaConvert のステータスは、["SUBMITTED", "INPUT_INFORMATION", "PROGRESSING", "STATUS_UPDATE", "COMPLETE", "ERROR", "CANCELED"] のいずれかです(詳細はこちら
  9. EKS 上の別のワーカーが5秒間隔で SQS をポーリングし、MediaConvert の完了通知を処理します
  10. 完了通知を受けたワーカーは、アプリDB(Aurora)の動画ステータスを COMPLETE などに更新します
    1. アプリの動画のステータスが COMPLETE になっていれば、ユーザがその動画にアクセスできます

動画再生

  1. ユーザはアプリから動画のメタデータを取得します
    1. アプリは S3 のエンドポイントから cloudfront のエンドポイントに変換して、ユーザに返します
    2. 必要に応じて、cloudfront のエンドポイントに署名します
      1. 署名付きURLと署名付きクッキーが選択肢としてありますが、HLSは複数ファイルにアクセスするため、署名付きクッキーが推奨されています
  2. ユーザは、取得した cloudfront のエンドポイントを使って、動画をストリーミング再生します

Youtube

署名付きURL or 署名付きクッキー

上述したように、ストリーミング再生では、複数のセグメントファイルへのアクセスが必要なので、署名付きURLではなくて署名付きクッキーが一般的に推奨されている。
しかし、Youtube のネットワークタブを見ると、署名付きクッキーではなくて、署名付きURLが使われていた。おそらく、m3u8 ファイルだけではなくて、全ての ts ファイルのエンドポイントに対しても署名しているのだと思う。m3u8 ファイル上の全ての ts ファイルのエンドポイントを署名付きURLに変更するのは、かなり技術的に難しそう。
ただ、署名付きクッキーが使えない場合は、このように実装するしかないのかもしれない。例えば、C++ の Qt ライブラリや、Unreal Engine の Media Player は、ヘッダーを持たせることができないので、どうしてもアクセスを制限したい場合は、署名付きURLを採用するしかない。
(そもそも、HLS じゃなくて DASH 使っているとか、細かい部分は違うかもしれないが、大まかなイメージはこんな感じだと思う)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?