Cloud Functions を用いた自動エンコードの実装

Prev Next

Classic/VPC環境で利用できます。

VOD Station商品は Object Storageバケットと連携してエンコードを実行しますが、バケットにファイルがアップロードされたかを検知して自動エンコードする機能は提供しません。しかし Object Storageのイベント管理機能と Cloud Functionsを用いて類似の機能を実装できます。

自動エンコードの Flow

自動エンコードを実装する手順は次の通りです。

  1. Object Storageのメディアファイルをアップロード
  2. Object Storageでアップロードイベントトリガー
  3. Cloud Functionsで VOD Stationのエンコード APIをリクエスト
  4. VOD Stationでエンコードを実行

実装ガイド

Object Storageと Cloud Functions、VOD Station APIを利用して自動エンコードを実装する例は次の通りです。

  1. Object Storageのソースファイルを保存するバケットにイベントを設定
    1. Object Storage > Bucket Management > イベントを設定するバケットのイベント管理メニューをクリック
    2. イベント管理ポップアップ > 作成ボタンをクリック
    3. バケットイベントを作成
      • イベント名を入力
      • フィルタの設定: オブジェクトに対してイベントフィルタリングを行う際に使用する条件を入力
        • 正規表現で入力してください。(例) 接頭辞 images/:^images/)
        • フィルタはオブジェクトのパスに適用され、入力しない場合はすべてのオブジェクトに対してイベントが発生します。
      • イベントタイプ: オブジェクト作成(PUT)
        • 新規ファイルをアップロードする場合、POSTと PUTの二つのイベントが同時に発生します。そのため、POSTと PUTをすべて選択するとエンコードアクショントリガーが二回発生することがあります。
        • 上書きの場合、PUTイベントだけ発生します。
      • 対象: Cloud Functions
        • 予め作成しておいたトリガーがない場合、トリガー作成ボタンをクリックしてトリガーを作成します。
          • トリガー作成のポップアップには、名前だけ入力して作成ボタンをクリックします。
          • トリガーに接続するアクション(実行するロジック)を設定します。ただし、作成済みのアクションがない場合は省略します。
        • 作成したトリガーを選択
          • この段階では接続したアクションがなくても構いません。
        • 再帰呼び出しの注意のご案内を確認してチェックします。
  2. Cloud Functionsで Actionを設定
    1. Cloud Functions > Action > Action作成ボタンをクリック
    2. Action作成ページでトリガーの条件を設定
      • トリガーの種類: Object Storageを選択します。
      • 名前: 前段階で作成しておいたトリガーを選択して追加ボタンをクリックします。
      • 再帰呼び出しの注意のご案内を確認してチェックします。
    3. Actionのロジックを設定
      • パッケージ: パッケージ(グループ)を選択します。選択したいパッケージがない場合、新規作成します。
      • タイプ: 基本(必要に応じてシーケンスを選択可能)
      • 名前: 作成するアクションを名前を入力します。
      • ソースコード: 作成するアクションで実行するビジネスロジックをお客様が直接実装します。このガイドの下部にあるソースコードの例をご参照ください。
      • VPC接続情報 : 選択した Platformが VPC環境の場合、接続する VPCと Subnetを選択し、ない場合は新規作成します。

自動エンコード Actionのソースコード設定

Cloud Functionsの設定例は、次の通りです。

参考

サンプルコードは正常動作を保障しないため、実際の実装時に参考として活用してください。

  • Example parameter
    • Default Parameter (JSON Object)
      • 以下のように設定します。
      {
          "base_url": "https://vodstation.apigw.ntruss.com",
          "api_url": "/api/v2/category/{CATEGORY-ID}/add-files",
          "access_key": "{API-ACCESS-KEY}",
          "secret_key": "{API-SECRET-KEY}"
      }
      
      • {CATEGORY-ID}: エンコードを実行するカテゴリ ID値に置き換えます。
      • {API-ACCESS-KEY}: ユーザーの Access Key値に置き換えます。
      • {API-SECRET-KEY}: ユーザーの Secret Key値に置き換えます。
参考

CATEGORY-IDカテゴリリストの照会 APIによって確認でき、API-ACCESS-KEYAPI-SECRET-KEY認証キーの管理で確認できます。

  • Example source code
    • 例は Python 3.7で実装したものです。他の言語で実装することもできます。
    import hashlib
    import hmac
    import base64
    import requests
    import time
    import json
    
    
    def make_signature(url, timestamp, access_key, secret_key):
        timestamp = int(time.time() * 1000)
        timestamp = str(timestamp)
    
        secret_key = bytes(secret_key, "UTF-8")
    
        method = "PUT"
    
        message = method + " " + url + "\n" + timestamp + "\n" + access_key
        message = bytes(message, "UTF-8")
        sign_key = base64.b64encode(
            hmac.new(secret_key, message, digestmod=hashlib.sha256).digest()
        )
        print(sign_key)
        return sign_key
    
    
    def make_header(timestamp, access_key, sign_key):
        headers = {
            "Content-Type": "application/json; charset=utf-8",
            "x-ncp-apigw-timestamp": timestamp,
            "x-ncp-iam-access-key": access_key,
            "x-ncp-apigw-signature-v2": sign_key,
        }
        return headers
    
    
    def main(args):
        object_name = args.get("object_name")
        input_bucket_name = args.get("container_name")
    
        api_url = args["api_url"]
        full_url = f'{args["base_url"]}{api_url}'
        timestamp = str(int(time.time() * 1000))
    
        sign_key = make_signature(
            api_url, timestamp, args["access_key"], args["secret_key"]
        )
        headers = make_header(timestamp, args["access_key"], sign_key)
    
        try:
            res = requests.put(full_url, headers=headers, data=json.dumps({'bucketName' : input_bucket_name, 'pathList': [ object_name ] }))
    
            if res.status_code == 200:
                return {"input_bucket": input_bucket_name, "object_path": object_name, "res": res.text, "done": True}
            else:
                raise Exception({"done": False, "error_message": res.text})
    
        except Exception as e:
            raise Exception({"done": False, "error_message": str(e)})