読者です 読者をやめる 読者になる 読者になる

料理動画を支える技術

インフラ

インフラストラクチャー部 星野(@con_mame)です。

少し前から、一部レシピページに料理動画を掲載していました。当初はYoutubeを使用していましたが、本日から自社配信に切り替わりました。現在はまだ掲載数は少ないですが、今後掲載数を増やしていきたいと考えております。

そこで、今回は、動画配信プラットフォームの裏側がどうなっているかという点を簡単にですがご紹介したいと思います。

構成図

構成図を見ていただくのが一番わかり易いと思うので、最初に掲載します。

structure

見て分かる通り、今回は全てAWSのサービスを使用して構築しています。

今回使用したサービスは

  • エンコード: Elastic Transcoder
  • データストア: DynamoDB + DynamicDynamoDB
  • ストレージ・配信: S3 + CloudFront
  • エンコード通知など: SNS

今回、構築までの期間とエンコードや動画というデータサイズの大きなコンテンツ配信を安定して提供するためにこのような構成を取りました。動画形式は、PCやスマートフォンで使用するネットワークに合わせて、Adaptive BitrateのHLSで配信を行っています。

動画のエンコードに関しては、Elastic Transcoderを用いて、1jobにて複数BitrateのHLSとサムネイルを同時に生成しています。Elastic Transcoderを使用したことによって、動画変換サーバの構築・運用やJOBキューイング、負荷状況に応じたサーバスペックの調整が不要になりリリースまで、そしてその後のサービスの安定化・開発効率を維持できるようにしています。

また、クライアントからのUploadはS3に直接行い、STSを使って一時的な認証情報を発行するToken vending machine (TVM)方式を取ってます。この方法にした理由は、動画投稿はアップロードするコンテンツサイズが大きくなってしまうため、長期間S3とProxyするサーバのセッションを確保されてしまうのを防ぐためと、安定性のためです。

簡単な動作

  1. 動画をアップロードする端末がTVMからSTS経由でS3の特定のBucketにPUTする権限のついた認証情報を取得
  2. その認証情報を用いて動画ファイルをPUTし、APIにむけて通知を送る
  3. APIはDynamoDBに情報を書き込み、Elastic Transcoderにjobを投げる
  4. エンコード状態の変化・完了通知はSNSを経由してAPIサーバに通知され、適時DynamoDBの中身を書き換える
  5. エンコード完了したファイルはS3に書きだされ、CloudFront経由で配信
  6. 動画表示時は、アプリケーションサーバがAPIサーバ経由で情報を取得し、DynamoDBから情報の読み書きを行なう

といったシンプルなものになっています。 アプリケーションサーバや管理用のサーバにはInternal ELB経由で接続し、DynamoDBはDynamic DynamoDBを用いることによってリクエスト数の増減に対応しています。

また、Dynamic DynamoDB自体は、AutoScalingを用いてSelf Healを行っております。

まとめと罠

今回、ほぼAWSのサービスで動画配信プラットフォームを構築することで、リリースまでの時間短縮や安定した基盤を作ることが出来ました。

今回の構成では、基本的にはAPIサーバだけを管理すればいいので、今後の用途の増加にも対応しやすい構成になったと思っています。

注意点としては、ブラウザからS3への直接UPの際はBucketのCORS設定もお忘れなく。

今後は、DynamoDBとRedshift連携したデータ解析やKinesisを使った何かなども組み込んでいきたいところです。

最後に、Elastic Transcoderはあまり利用事例が無いようで、エンコード完了通知に動画の再生時間作成されたサムネイルの枚数が通知されないなど細かいところで改善して欲しいところはありますが、コスト・安定性的にいいソリューションの1つではないかと思います。

COOKPAD料理動画はこちら!!

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/