All Articles

CarrierwaveとElasticTranscoderを使った動画配信

概要

CarrierwaveElasticTranscoderを使用した動画配信の仕組み作り方の記事です。

ざっくり構成

動画配信の構成

準備

  • オリジナルバケット:オリジナルの動画データを保存
  • 変換済みバケット:変換済みの動画データを保存

を作成します。

Carrierwaveの設定

GitHubに書いてある通りに設定します。

rails generate uploader Avatar
class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader
end

ファイル名の命名はWikiで解説されているやり方に沿います。

class AvatarUploader < CarrierWave::Uploader::Base

  def filename
    "#{secure_token}.#{file.extension}" if original_filename.present?
  end

  protected
  def secure_token
    var = :"@#{mounted_as}_secure_token"
    model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
  end
end

なお、バケット名の設定は「オリジナルバケット」の名前を入れておきます

CarrierwaveのAWS S3設定については、この辺りをご参照ください。keyなど公開したくないものは、credential か環境変数を使用します。

CarrierWave.configure do |config|
  config.fog_credentials = {
    provider:              'AWS',                        # required
    aws_access_key_id:     'xxx',                        # required unless using use_iam_profile
    aws_secret_access_key: 'yyy',                        # required unless using use_iam_profile
    use_iam_profile:       true,                         # optional, defaults to false
    region:                'eu-west-1',                  # optional, defaults to 'us-east-1'
    host:                  's3.example.com',             # optional, defaults to nil
    endpoint:              'https://s3.example.com:8080' # optional, defaults to nil
  }
  config.fog_directory  = 'name_of_bucket'                                      # <- ここはオリジナルバケットの名前
  config.fog_public     = false                                                 # optional, defaults to true
  config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
end

参考: https://github.com/carrierwaveuploader/carrierwave#using-amazon-s3

Elastic Transcoder でパイプラインを作成

  • インプットバケット:オリジナルの方
  • トランスコード済みのファイル:変換済みのバケット
  • サムネイルファイル:変換済みバケット

で作成。このときにパイプラインIDが発行されるので、それをメモしておきます。

パイプラインが正常に動いているかどうかは、ジョブを作成することで確認できます。適当なファイルをオリジナルバケットに入れて、ジョブを走らせてみると良いかと思います。

Lambdaの設定

AWS Lambda関数を作成します。LambdaでElastic Transcoderのジョブを走らせて変換処理を行います。 Lambda関数の中身については、以下の記事をご参照ください。 pipelineIdのところは、先ほどメモしたIDを入れます。

参考: https://tech.medpeer.co.jp/entry/2018/01/18/174542

S3のイベントを作成

  • 名前:適当でOK,わかりやすい名前に
  • イベント:全てのオブジェクト生成イベント
  • プリフィックス:ディレクトリを指定できる。Carrierwaveuploaderstore_dirを指定している場合は入力
  • サフィックス:拡張子を指定できる。mp4だけ指定でも良いが、そうするとmovとかを検知しなくなるので注意
  • 送信先:Lambda関数→先ほど作成した関数

配信側

前提として、オリジナルバケットに入れたファイルと同名で変換済みバケットに入れています。なので、https://変換済みバケットのURL.com/ファイル名によって、変換済みファイルを取得できます。

CloudFront作成

変換済みバケットの動画を配信するためのCloudFrontを作成します。

Carrierwaveのasset_hostを設定

config.asset_host = "https://..." # 先ほど作成した cloudfront URL

拡張子をつないで、video_tagで読み込み

User.first.avatar_url # -> これでcloudfrontから配信されるmp4ファイルのURLを生成できる
# 例: helperとかに書いておく
def avatar_urls(user)
  extensions = %w[.m3u8 .webm .mp4]
  extensions.map { |extension| user.avatar_url.pathmap('%X') + extension }
end
/ こんな感じで呼ぶ
= video_tag avatar_urls(@user)