カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

CloudFrontで署名付きURLによるストリーミング配信をしてみた(Ruby編)

夏の角部屋はパンチ力があるなと痛感している@masudaKです。

AWSにはCloudFrontというCDNがありますが、CloudFrontではストリーミング配信をすることができたりします。

さらに、特定の条件による配信をするために、署名付きURLというものを使うことができます。これによって、特定の期間のみに有効な配信URLを、特定の管理者が作成することができ、それで配信することができたりします。

その署名付きURLによる配信に関して、ちょいと触る機会があったので、備忘録も兼ねて残しておきます。URLの作成は気分的にRubyで。

ちなみに、Python版は以下でできるようです。

qiita.com

CloudFrontでは、配信方式にダウンロードとストリーミングのどちらかが選べるのですが、ストリーミングによる配信について述べます。

ダウンロードに関しては、ぐぐればわりと載ってると思いますので、ぐぐってください。

CloudFront

概要に関しては、CloudFrontの公式ページに載ってますが、CloudFrontではメディアの配信を簡単にすることができます。公式サイトではこんな感じで載っています。

メディアファイルの配信 お客様のアプリケーションに、頻繁にアクセスされるリッチメディア(音声や動画)が含まれる場合、Amazon CloudFront を使用することにより、より低額なデータ転送料金およびデータ転送速度の改善というメリットを活用できます。 Amazon CloudFront には、メディアファイル配信のための複数のオプションがあります。事前に作成されたメディアにもライブメディアにも対応します。

んで、今回扱うのは、以下のRTMPによる配信です。

事前に作成されたメディアのストリーミング: Amazon CloudFront を経由して、Adobe の RTMP(Real Time Messaging Protocol)ストリーミングを利用してオンデマンドのメディアを配信できます。 メディアファイルのオリジナルコピーを Amazon S3 に保管して Amazon CloudFront を利用すれば、少ない待ち時間でメディアコンテンツを配信可能です。 Amazon CloudFront は Amazon S3 と連携しているため、簡単な API を1回呼び出すか、または AWS Management Console で数回クリックするだけでメディアストリーミングを設定できます。 また、Amazon CloudFront を利用すると、高スループットなメディア配信が可能なため、フル HD 品質のコンテンツをユーザーに提供することができます。

なので、S3にデータを保管し、そのデータとCloudFrontを連携して、配信することになります。

S3

ということで、まずS3にデータを保存しましょう。「Create Bucket」から適当に名前をつけて、Bucketを作成しましょう。ロギングとかは任意で。

Bucketができたら、プロパティを確認しておきます。具体的には「Permissions」のところで、「bucket policy」が生成されてないことを確認しておきます。

最初はポリシーができてないので、「Add bucket policy」という表現になっているかと思います。

そしたら、動画をアップロードします。あとで気づくことになるのですが、このアップロードする動画のコーデックとかを意識してないと、音声しか配信されなかったりするので、ほんと気をつけましょう。

テストをしたいなら、Internet Arhichiveの映像検索ページで見つかる動画などはいいかもしれません(権利などもありますので、そのあたりは気をつけてください)。

ストリーミングとしては、flvやmp4のものを使えばよいでしょう。

CloudFront経由でデータにアクセスしますので、必ずしも権限をパブリックにする必要はありません。ポリシーはコンテンツに応じて設定してください。

アップロードが終わったら、プロパティからリンク先を確認し、データにアクセスできるか確認しましょう。

パブリックにしていない場合は、URLが有効であることを確認しておきましょう。

CloudFrontとの連携

S3にデータをアップロードしましたので、次にCloudFrontの設定をします。CloudFrontにアクセスし、「Create Distribution」を選択します。

ここで、ダウンロードにするかストリーミングにするか選択肢が現れますので、ストリーミングを選択しましょう。 その後は以下の点に注意して、項目を選んでください。

  • Origin Domain Name: さきほど作ったS3のBucketを選択してください
  • Grant Read Permissions on Bucket: S3のデータにアクセスしたいので、「Yes, Update Bucket Policy」を選びましょう。
  • Restrict Bucket Access: コンテンツにアクセスする場合に、CloudFrontからのアクセスのみ有効にし、S3のURLからアクセスできないようにします。そのようにしたい人は、Yesを選びましょう。
  • Restrict Viewer Access: これが今回扱いたい署名付きURLの設定ですね。署名付きURLを使いたいので、Yesを選択します。

ロギングやCNAMEなどは必要があれば、設定してください。

作成後、Statusが「In Progress」から「Deployed」に変わることを確認してください。ここは少し時間がかかるようです。

S3との連携ができているかを確認するため、上記で指定したS3のBucketのプロパティを確認します。正しく設定できていれば、Permissionsの項目に、「Edit bucket policy」というのができており、bucket policyを見ることができます。

PrincipalにCloudFrontの項目が見つかれば大丈夫でしょう。

署名付きURLの設定

最後に署名付きURLの設定を行います。 S3のデータにCloudFront経由でアクセスする際に、署名付きURLを用います。これはSDKなどを使わないとできないので、その環境を作ります。

まず、AWSのSSL証明書の画面にアクセスし、CloudFrontの鍵を作ります。 「一対の鍵」で鍵を作成し、「公開鍵をダウンロード」を選択し、ダウンロードしましょう。

次に、適当なサーバで署名付きURLを作成します。今回はRubyでスクリプトを作ります。なので、Rubyを動かしやすい環境を適当に用意してください。

まず、aws_cf_signerのgemをインストールしておきます。

$ gem install aws_cf_signer --no-ri --no-rdoc

こんな感じ。Bundle使ってるかたはそれでも。

そしたら、適当にディレクトリを作り、上記の「公開鍵のダウンロード」で入手した、pemを置いてください。 名前は、「pk-XXXXXXXXX.pem」みたいなものかと思います(Xの部分は環境によって異なります)。

そして、以下のスクリプトを適当に用意してください。

#!/usr/bin/env ruby

require 'aws_cf_signer'
signer = AwsCfSigner.new('./pk-XXXXXXXXXX.pem')
url = signer.sign('rtmp://XXXXXXX.cloudfront.net/cfx/st/mp4:test.mp4', :ending => 'Sat, 14 Nov 2015 22:20:00 GMT')

puts url

signer.signで渡しているURLですが、以下のポリシーになります。

  • プロトコル: rtmp決め打ち
  • ドメイン: CloudFrontの管理画面で「Domain Name」で確認
  • ファイルパス: 「cfx/st/拡張子:ファイル名」

ここでは「ending」のみ設定していますが、ip_rangeや様々な設定をすることができます。色々使ってみるといいかと。 そしたら、スクリプトを保存し、実行します。

実行すると、引数にExpiresやKey-Pair-Idなどが付与されたURLが作成されます。

そしたら、作成したURLからデータにアクセスできるように、jw-playerのウィザードページ などで確認を行いましょう。

このURLもいつまで動くかわかりませんので、不安なかたはjw-playerをローカルで動かせばよいでしょう。 これで、問題なく動画が見られれば、設定は終わりです。

ちなみに、iPhoneで撮影した動画を適当なツールを使って、mp4にしたら、CloudFront経由だと音声しか再生されず、トレースが面倒だったので、気をつけたほうがよいでしょう。

結局コーデックの問題でしたが、HTTP経由でもうまくいくし、S3にあるデータも問題なく再生できるので、RTMPとの相性があるのかもしれません。

終わりに

今回初めてCloudFront触ってみましたが、多少ハマるところはあるものの、それでもたいした時間も工数もかからず、署名付きストリーミング配信が随分と簡単にできるなぁという印象を受けました。

実際運用するとなると、お財布と相談したり、誰が署名するのか、署名するにはGUIがあったほうがいいのかとか、色々考えることはでてきますが、誰でも気軽に署名付きの実装ができるのはいいですね。

AWSではRTMPによる配信になるようですが、ストリーミング技術に関して調べてみると、最近はHTTPでもっといい感じにやってくれる方法などもあるようなので、その辺は今後に期待したいところです。

それにしても、クラウドは使い方次第でめちゃ便利すな。いい時代でございます。

間違い・このほうがいい等あれば、@masudaKまでお願いします。

AWSシリーズ