サーバーレスに動画をスケーラブルにオンデマンド配信 !

~「Video on Demand on AWS - AWS のビデオオンデマンド Foundation」を試してみる

2022-02-02
AWS ソリューション紹介

堀内 保大

みなさん、こんにちは。ソリューションアーキテクトの堀内保大です。
私は今年の 4 月に AWS Japan に入社したのですが、一度もオフィスに行くことなくかれこれ半年以上が経過し、時の流れの速さとリモートワーク慣れに驚くばかりです。

さて、builders.flash では定期的に「AWS ソリューションライブラリ ()」からソリューションをピックアップして概要やユースケース、手順のご紹介をする記事の連載を行っています。これまでの記事は こちら の記事カテゴリーで「AWSソリューション紹介」に絞ってご覧ください。

今回紹介するソリューションは、「Video on Demand on AWS」というオンデマンドな動画配信 (ビデオオンデマンド、VOD と呼ばれます) にフォーカスしたソリューションのご紹介をします。

私のように外出を控えている方々は多いと思いますが、そういった昨今の状況に伴い動画配信サービスの利用は増えています。こういった動画配信サービスでは、HTTPS 通信で取得できる、マルチビットレートで配信できる、ファイルを取得しながら再生できる、などのメリットから HLS (HTTP Live Streaming) 形式での配信が一般化しています。HLS 形式で動画配信の際には、 mp4 等の元動画ファイルから HLS に変換をする処理を実装したり、さらにその配信用にサーバーのホスティングが必要となります。

これらをそれぞれ EC2 のようなサーバーを用意して実行していくには、構築の手間もかかりますし、サーバー管理も大変で、こまめに停止させないと起動時間分のコストもかかってしまいます。そういった課題に対し、AWS ではマネージドなサーバーレスサービスをご活用いただくことでスケーラブルかつコストメリット高く動画配信を実装いただくことが可能です。

簡単にオンデマンド配信サービスを作ってみたい、実装方法を知りたいといった方々に向けて、本記事ではAWSのマネージドサービスを利用して動画変換から配信までをシームレスに実装する「Video on Demand on AWS」ソリューションをご紹介していきます。

それでは、「Video on Demand on AWS」がどんなソリューションなのか見ていきましょう。

※AWSソリューションライブラリの中には、すぐにお客様の課題に対応できるよう導入までの手順や AWS CloudFormation のテンプレート等を含めた AWS ソリューション実装 というリファレンスとなる実装パターンが多数掲載されています。

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

この記事のデモを無料でお試しいただけます »

毎月提供されるデベロッパー向けアップデート情報とともに、クレジットコードを受け取ることができます。 


Video on Demand on AWS とは

「Video on Demand on AWS」では、世界中の視聴者に動画配信コンテンツをコスト効率よく配信するための 「AWS のビデオオンデマンド Foundation」と「AWS のビデオオンデマンド」の 2 つのソリューションが提供されています。

「AWS のビデオオンデマンド Foundation」では、アップロードした動画を、AWS Elemental MediaConvert を利用して動画変換し、その配信 URL の公開までをワンストップで行う基礎的な実装が提供されています。「AWS のビデオオンデマンド」では、より拡張した形のソリューションで、動画変換における前後処理のワークフローカスタマイズやデバイスからの再生リクエストに応じた複数フォーマットでの配信等に対応しています。

今回は動画配信ソリューションの基礎として「AWS のビデオオンデマンド Foundation」のご紹介を行います。

クリックすると再生します (英語)

AWS のビデオオンデマンド Foundation

このソリューションは、マネージドな動画変換サービスである AWS Elemental MediaConvert を使用して動画ファイルの配信用フォーマットへの変換を開始できるように設計されています。

また、変換した動画については、Amazon S3 から Amazon CloudFront を通して、オンデマンドに動画を配信することができるため、配信もサーバーレスに実装が可能です。

また、他にもこのソリューションでは次のことができます。

  • S3 にアップロードされた動画を、さまざまなデバイスで再生するのに適した形式に自動的に変換
  • MediaConvert のジョブ設定をカスタマイズ可能 (独自のファイルをアップロードや、入力ごとに異なるジョブ設定の使用等)
  • 変換されたファイルを送信先 S3 バケットに保存し、CloudFront を使用してクライアントに配信
  • S3 への動画アップロードを契機に、動画変換、配信 URL の公開までシームレスに実行

このソリューションによりご自身でサーバーを用意いただく必要なく、従量課金でスケーラブルな動画配信アーキテクチャを構築いただくことが可能です。


使用している AWS サービスは ?

本ソリューションでは、具体的には、次の AWS サービスを使用しています。

Amazon Simple Storage Service (Amazon S3) 動画ファイル (変換前後) やログ (Amazon CloudFront、Amazon S3) のデータ保存に利用します。
ストレージとしてだけでなく、動画配信時のオリジンサーバーとして利用することで、99.99 % の可用性を持った配信サーバーをサーバー管理不要で実現できます。
AWS Elemental MediaConvert メディアファイルをソース形式からスマートフォン、タブレッ ト、PC、その他のデバイスで再生するバージョンに変換します。
Amazon CloudFront 動画配信時の CDN として利用します。 Amazon S3 上の変換された動画ファイルをオリジンとします。
CDN を活用することで、各クライアントにより近いエッジロケーションから動画が配信され、配信時の NW レイテンシの向上が期待できます。
AWS Lambda ジョブ登録 : Amazon S3 上に動画ファイルを置かれたイベントを契機に、AWS Elemental MediaConvert のジョブをキックします。

ジョブ完了 : ジョブ完了通知を行う Amazon SNS を実行します。
Amazon CloudWatch AWS Elemental MediaConvert のエンコードジョブを追跡し、完了時に通知のための AWS Lambda 関数をキックします。
Amazon Simple Notification Service (Amazon SNS) ジョブの完了通知をメールにて送信します。 

これらのサービスは以下のように連携をしており、[1] の S3 への動画アップロードから、[8] の CloudFront での動画配信 URL 公開までシームレスに実行されます。


コスト試算の例

このソリューションを実行するための総コストは、動画のサイズ、作成される出力数、公開コンテンツが Amazon CloudFront を介して受信する閲覧数によって異なります。 詳細については、このソリューションで使用する AWS の各サービスの料金表ウェブページを参照してください。

2021 年 7 月現在、米国東部 (バージニア北部) の AWS リージョンで、次の表に示す各サービスの課金モデルを使用して、動画 60 分でこのソリューションを実行する場合の推定コストは、月額約 7.18 USD です。

サービス 項目 月額料金
Amazon CloudFront デフォルトのジョブ設定で、1,000 ユーザーにストリーミングされる 60 分間のビデオの場合は、およそ次の費用が発生

0.75 MB/秒 * 1,000 ユーザー * 3,600 秒 = 45 GB
45 GB * 0.085 USD/GB = 3.825 USD
$3.83
Amazon S3 動画 60 分では、動画コンテンツの複雑さに応じて、S3 で最大 9 GB のストレージを使用
0.023 USD/GB * 9 GB = 0.207 USD
$0.21
AWS Lambda ファイルごとに 4 件のリクエスト
→100 万件のリクエスト当たり 0.20 USD
$0.00
Amazon CloudWatch 無料利用枠 $0.00
Amazon SNS 無料利用枠 $0.00
AWS Elemental MediaConvert

HLS出力のプロファイル:
・30 fps 以下で 3 SD 解像度
・30 fps 以下で 2 HD 解像度

$3.15
  合計 $7.18

デプロイ方法 / 設定方法

ステップ 1 : AWS CloudFormation スタックの作成

それでは、AWSソリューションのデプロイ方法を見ていきましょう !

本ソリューションにて使用する CloudFormation テンプレートを実行するために、Video on Demand on AWS のランディングページ にアクセスします。

AWS コンソールで起動する」を選択します。

クリックすると拡大します

CloudFormation が起動されて、スタックの作成の画面になります。
このソリューションの実装では、リージョンとして「東京」を選択することが可能です。

「前提条件 - テンプレートの準備」、「テンプレートの指定」は変更せずにそのまま「次へ 」を選択します。

クリックすると拡大します

スタックの名前」に任意の名前を入力します。

パラメータ」には emailAddress として後ほど SNS による通知を受け取り管理用のメールアドレスを設定します。

クリックすると拡大します

スタックオプションの設定」、「詳細オプション」は変更せずに、「次へ」を選択します。

レビュー」で、CloudFormation のパラメータが指定した値で設定されていることを確認します。

クリックすると拡大します

レビューを下へスクロールし、「AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。」にチェックを入れ、「スタックの作成」を選択します。

クリックすると拡大します

スタックの作成中に SNS の確認メールが届くため、 「Confirm subscription」を押下しましょう。

クリックすると拡大します

スタックの作成が成功したことを確認します。

作成完了までに 5 分程度かかります。

ステップ 2 : ジョブ設定ファイルの変更 (オプション)

aws-video-on-demand-on-aws-source から始まるバケットが S3 上に作成されています。これは変換元の動画を配置するバケットです。

クリックすると拡大します

その中の構成は以下のようになっています。

assets01/
    job-settings.json
    jobs-manifest.json

assets01/ 配下に変換したい動画を配置することで、VOD 用に動画が変換されるジョブが自動で走ります。配下の job-settings.json は AWS Elemental MediaConvert のジョブ設定が記載されいます。

以下に job-settings.json を一部抜粋します。

{
    "Queue": "Default",
    "Role": "",
    "Settings": {
(略)
        },
    "AccelerationSettings": {
      "Mode": "PREFERRED"
    },
    "StatusUpdateInterval": "SECONDS_60"
  }

job-manifest.json には AWS Elemental MediaConvert で実行するジョブ情報や、入出力ファイルの詳細が実行後に追加されます。

異なるジョブ設定をサポートするには、以下のように本バケットのルートに追加のフォルダーを作成し、フォルダーごとに異なるジョブ設定 (job-settings.json) を含めます。動画を配置したフォルダ内の設定ファイルに応じて動画が変換されます。

assets01/
    job-settings.json
assets02/
    job-settings.json

ジョブ設定については、AWS Elemental MediaConvert のジョブテンプレートの機能を使って JSON を生成するとやりやすいでしょう。
ジョブテンプレートを使用して AWS Elemental MediaConvert でジョブを作成します。 - MediaConvert (amazon.com) »

ステップ 3 : S3 イベント通知設定の変更 (オプション)

現時点でのデフォルトだと変換元動画を配置する S3 バケットに、こちらの画像にある拡張子の動画ファイルが配置された際に、動画変換のジョブがキックされる設定になっています。

ここに含まれない動画にも対応をさせたい場合は、適宜こちらの S3 イベント通知設定の変更をしてください。

クリックすると拡大します


動作の確認

さて、このソリューションのデプロイが完了した時点で、変換元動画を配置する S3 バケットに動画を配置するだけで、動画がオンデマンド配信されるようになっています。
早速確認をしてみましょう。

変換元動画のアップロード

aws-video-on-demand-on-aws-source から始まる S3 バケット内の job-settings.json が存在する asset01/ 配下に、配信したい動画ファイルをアップロードしてみます。

今回はこちらの画像のように MP4 の動画ファイルをアップロードしてみました。

クリックすると拡大します

SNS によるジョブ完了通知

SNS から AWS-Video-on-Demand-on-AWS: Job COMPLETE id:111111111-xxxxxx のようなタイトルで、ジョブ完了通知のメールがきます。

メールには以下のように、変換元の動画のパスやコーデックなどの詳細情報と、変換後の CloudFront URL が記載されています。

{
  "Id": "1636873705809-etgwi2",
  "InputFile": "s3://aws-video-on-demand-on-aws-source71e471f1-xxxxxxx/assets01/test-video.mp4",
  "InputDetails": {
    "audio": [
      {
        "channels": 2,
        "codec": "AAC",
        "language": "UND",
        "sampleRate": 48000,
        "streamId": 2
      }
    ],
    "id": 1,
    "video": [
      {
        "bitDepth": 8,
        "codec": "H_264",
        "colorFormat": "YUV_420",
        "fourCC": "avc1",
        "frameRate": 25,
        "height": 2160,
        "interlaceMode": "PROGRESSIVE",
        "sar": "1:1",
        "standard": "UNSPECIFIED",
        "streamId": 1,
        "width": 3840
      }
    ]
  },
  "Outputs": {
    "HLS_GROUP": [
      "https://xxxxxxxx.cloudfront.net/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/AppleHLS1/test-video.m3u8"
    ]
  }
}

AWS Elemental MediaConvert のジョブ確認と S3 バケットの確認

AWS Elemental MediaConvert でジョブが実行されていることが確認できます。

入力」に表示されているソースが、上記で動画をアップロードした S3 バケットであることが確認できます。

job-setting.json 内で Output を複数の解像度で定義していたため、それら複数の Output が「出力」に表示されています。AppleHLS1 というリンクをクリックすると変換された動画が配置されている、aws-video-on-demand-on-aws-destination から始まる S3 バケットに画面遷移します。

クリックすると拡大します

こちらの S3 バケットには、HLSの構成要素であるプレイリストファイル (.m3u8) とセグメントファイル (.ts) が配置されています。

このバケットは、上記 SNS にて通知された CloudFront の配信用 URL のオリジンに設定されています。

クリックすると拡大します

配信動画の確認

SNS にて通知された CloudFront の URL を使って配信動画を確認します。
ここでは、OSS の動画再生ライブラリである Video.js を使って確認してみます。

例えば以下のような Video.js を利用して動画再生用の HTML ファイルを作成します。

<html>
  <head>
    <title>Video.js Sample</title>
    <link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet">
  </head>
  <body>
    <video
      id="my-video"
      class="video-js"
      controls
      preload="auto"
      width="640"
      height="360"
      data-setup="{}"
    >
      <source
         src="https://xxxxxxxx.cloudfront.net/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/AppleHLS1/test-video.m3u8"
         type="application/x-mpegURL">
    </video>
    <script src="https://vjs.zencdn.net/7.15.4/video.js"></script>
  </body>
</html>

* <source> タグ内に CloudFront の配信用 URL (http://~~~m3u8) を記載してください。

HTMLファイルを開くと動画再生ページが表示され、再生ボタンにてオンデマンド再生されることを確認できます。

クリックすると拡大します


リソースの削除方法

CloudFormation から、このソリューションを選択して削除します。これにより、 このソリューションで使用されている AWS リソースが、S3 バケットを除きすべて削除されます。

手動で削除すべき S3 バケットはこちらの画像の通り 4 つ (cloudfrontlog, destination, logs, source) あります。

スタック名が先頭についているため、バケット名の検索窓で aws-video-on-demand と入力すると今回のソリューションで作成されたバケットが検索できます。

クリックすると拡大します

以下に自動的に作成された S3 バケットの確認と削除方法を記載します。

まず、コンソールの CloudFormation の中で、スタックの削除の前に、作成されている S3 バケットの名前を CloudFormation スタックのリソースの部分で確認しておきます。

CloudFormation スタック削除後、コンソールの Amazon S3 の中で、事前に確認した S3 バケットの名前を検索して、その S3 バケットを削除します。


実際にオンデマンド動画配信サービスを実装する際の考慮点

さて、ここまで「Video on Demand on AWS」ソリューションをご紹介してきました。

本ソリューションは動画ファイルをオンデマンド配信フォーマットに変換し、 CloudFront から配信するというフローのみにフォーカスしています。既にお気づきの方もいらっしゃるかもしれませんが、実際にオンデマンド動画配信サービスを実装するには、これだけでは不十分です。どういったことを追加で検討する必要があるのか、簡単に以下にまとめます。

アセット管理

今回のソリューションでは、変換前の動画や設定ファイルを直接 S3 にアップロードしていましたが、それでは手順が煩雑になりますし、アップロードされた動画の一覧やその変換状況も逐次統一的に確認できないと、管理も複雑になります。したがって、アセット管理のダッシュボードが実際のサービスには必要でしょう。

例えばアセット管理の参考として、AWS GitHub Samples で公開している AWS Media Asset Preparation System (MAPS) をご紹介します。こちらでは、動画ファイルの S3 へのアップロードやプレビューのためのアセット管理ダッシュボードが展開される以下のようなアーキテクチャがサンプル実装されています。

今回のソリューションでは、最後に CloudFront から配信される動画は URL がわかってしまえば永遠に誰でも動画を確認可能となっていました。

しかし、実際にはオンデマンド動画配信のサービスを想像したとき、会員登録したユーザーにのみ配信をしたい、一定期間のみ配信をしたい等の要件が存在するかと思います。また、コンテンツの無断使用等も避けたいですよね。

したがって、CloudFront 署名付き URL署名付き Cookie の仕組みを使ってアプリケーション側で認証を通ったユーザーに対して専用の URL や Cookie を払い出すことで限定的な公開を実現することになります。

今回のソリューションのように HLS 形式でオンデマンド動画配信を実現する場合、実際に再生される動画コンテンツである複数のセグメントファイル (.ts) と、動画再生のために必要なセグメントファイル情報が記載されているプレイリストファイル (.m3u8) を CloudFront から配信する必要があるため、複数のファイルについて限定的なアクセスを実現する必要があります。従来は、署名付き Cookie を払い出すことで、その Cookie を持っているユーザーであれば一定期間 CloudFront からコンテンツを取得することができるため、シンプルに実装ができ、広くこの方法が使用されています。

S3 上の変換後の配信可能な HLS 形式のコンテンツ

クリックすると拡大します

プレイリストファイル (.m3u8) の中身 (セグメントファイル名がリストされている)

クリックすると拡大します

また、昨今サードパーティー Cookie に対する規制強化の流れに加えて、ファーストパーティー Cookie への制限を厳しくしているベンダーも出てきているため、Cookie を避けた実装も署名付き URL を利用することで可能です。具体的には、CloudFront Functions や Lambda@Edge の機能で、プレイリストファイルをユーザーがリクエストする際に、プレイリストファイル内のセグメントファイル名が署名付きに URL になるように処理を行う実装をすることで、署名付き URL を使ってプライベートな HLS 形式の動画配信が可能です。

署名付き Cookie による実装と署名付き URL による実装を以下の図にまとめました。

Cookie サポートしないシチュエーションで 署名付きURLを利用する実装方法以外にも、以下のブログでは CloudFront Functions を利用して、認証時に取得したセキュアストリームキーをヘッダーに含めることで、CloudFront への再生リクエストを認証する方式が紹介されています。

CloudFront Functions を使用したコンテンツの保護 | Amazon Web Services ブログ

Cookie への対応要否や実装コストを鑑みて上記の中から実装方式を検討いただけると良いかと思います。

上述の項目以外にも、例えば以下のような作りこみが業務フローや別アプリケーションに合わせて必要になるかと思います。

  • 変換後の変換元動画ファイルのコスト削減 → 例) S3 上でのアーカイブ化やオブジェクト削除を後処理に組み込む
  • 様々な再生環境に対する対応 → 例) AWS Elemental MediaPackage のパッケージングを活用した、複数デバイス対応等
  • 広告挿入やDRM(デジタル著作権管理技術)→ 例) AWS Elemental MediaPackage や AWS Elemental MediaTailor の活用

例示したように、必要に応じて、他の Media 系のサービスと組み合わせたり、前後処理を拡充したりすることでカスタマイズをしてみてください。


まとめ

いかがでしたでしょうか。「Video on Demand on AWS - AWS のビデオオンデマンド Foundation」ソリューションにより、オンデマンド動画配信をサーバーレスで簡単に構築することができます。

ソリューションの中では、AWS Elemental MediaConvert を使用して動画ファイルの配信用フォーマットへの変換処理を実施し、変換した動画については、Amazon S3 から Amazon CloudFront を通して、オンデマンドに動画を配信することを実現していました。

本ソリューションが動画配信サービス実装時のリファレンスアーキテクチャやベース実装としてお役に立てば幸いです !


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者プロフィール

堀内 保大
アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト

ソリューションアーキテクトとして、デジタルネイティブビジネスを展開されるお客様を中心に様々なお客様を支援しております。
前職では SIer で、性能試験や性能チューニングをメインに取り組んでいました。AWS では、クラウドを活用してビジネスをスケールしていただけるようにご支援するのが一番の楽しみです。
好きなサービスは、Amazon Elastic Kubernetes Service (EKS)、AWS Fargate でコンテナに関連したサービスに興味があります。
プライベートでは引きこもってひたすら映画やアニメの動画を見ています。

AWS のベストプラクティスを毎月無料でお試しいただけます

さらに最新記事・デベロッパー向けイベントを検索

下記の項目で絞り込む
1

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する