S3設置トリガーで自動変換は難しくないですが、key(≒ファイル名)がURLエンコードでスペースがプラスに変換される所だけ、トラブルになりそうなポイント。
CMAFをAESで暗号化は、変換できたものの再生できず。
そもそもMediaConvertがMPEG-DASH(以降、DASHと記載)のClearKeyに対応してなさそうなのと、HLSだとAES128が選べますが、CMAFだとSAMPLE_AESしか選べず。
SAMPLE_AESのブラウザサポートは限られてそうなのと、ClearKeyが使えないとなると、DRMなしで暗号化したい場合はDASHを使う意味がなくなってしまう。

Class: Aws::MediaConvert::Types::DashIsoGroupSettings — AWS SDK for Ruby V2
Class: Aws::MediaConvert::Types::HlsGroupSettings — AWS SDK for Ruby V2
Class: Aws::MediaConvert::Types::CmafGroupSettings — AWS SDK for Ruby V2

S3設置トリガーで自動変換

Lambda関数のコード修正

MediaConvertでHLSをAESで暗号化してみる で作成したLambdaを使います。

最新のコードこちら → https://dev.azure.com/nightonly/_git/lambda-origin?path=/createMediaConvertJob/lambda_function.py

+ import urllib.parse
+    print(event)
+
-    input_bucket = 's3://input-media-cdn.nightonly.com/' # 対象動画のバケット
+    input_bucket = 's3://' + event['Records'][0]['s3']['bucket']['name'] + '/' # 対象動画のバケット
-    input_file = 'Big Buck Bunny.mp4' # 対象動画のフォルダを含むファイル名
+    input_file = event['Records'][0]['s3']['object']['key'] # 対象動画のフォルダを含むファイル名
+    input_file = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key']) # 対象動画のフォルダを含むファイル名

key(≒ファイル名)がURLエンコードでスペースがプラスに変換される為、unquote_plusで戻してあげる。MediaConvertにはKeyではなく、ファイル名である必要がある。

Amazon S3 インベントリ – Amazon Simple Storage Service

キー名 – バケット内のオブジェクトを一意に識別するオブジェクトのキー名 (またはキー)。CSV ファイル形式を使用すると、キー名は URL エンコードされるため、これをデコードしてから使用する必要があります。

意地悪テスト(Macだと:が使えないので、S3の画面から作成)

ファイル名: てス都_&_$_@_=_;_:_+_ _  _,_?/Big Buck Bunny.mp3
key: %E3%81%A6%E3%82%B9%E9%83%BD_%26_%24_%40_%3D_%3B_%3A_%2B_+_++_%2C_%3F/Big+Buck+Bunny.mp3
unquote_plus(key): てス都_&_$_@_=_;_:_+_ _  _,_?/Big Buck Bunny.mp3

デプロイしてテスト

テストイベントで、s3-putを選択して、バケットとファイル名をアップロードしたものに変更。

        "bucket": {
-          "name": "example-bucket",
+          "name": "input-media-cdn.nightonly.com",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
-          "key": "test%2Fkey",
+          "key": "Big Buck Bunny.mp4",
+          "key": "Big+Buck+Bunny.mp4",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }

トリガーを追加

サフィックス(≒拡張子)は未設定にして、全てのファイルを対象にしました。
サポートされている入力コーデックとコンテナ – MediaConvert


同じトリガーが既にあるとエラーになる

> Configuration is ambiguously defined. Cannot have overlapping suffixes in two rules if the prefixes are overlapping for the same event type. (Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument ・・・

今回は別のLambda関数で設定して、関数自体は削除したが、トリガーは残るみたいでエラーに。
S3 → プロパティ → イベント通知 で不要なのを削除。


動作確認

対象のS3に動画ファイルをアップロード(またはコピー)

正常に通れば、MediaConvertのジョブに表示される
https://ap-northeast-1.console.aws.amazon.com/mediaconvert/home?region=ap-northeast-1#/jobs/list

上手く行かない場合は、CloudWatch Logsで確認して対応
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:log-groups

CMAFを暗号化してみる(未解決)

MediaConvertのジョブテンプレート作成

DASH単体も試したので、ジョブテンプレートに「DASH_1Mbps」と「CMAF_1Mbps」を追加。
設定方法は割愛。前回までの記事を参照頂ければと。
MediaConvertでHLSをAESで暗号化してみる
API Gateway(WebSocket API)のフロントをNuxtで実装する

Lambda関数のコード修正

MediaConvertでHLSをAESで暗号化してみる で作成したLambdaを使います。

DAHSで試す場合

                'OutputGroupSettings': {
-                    'HlsGroupSettings': {
+                    'DashIsoGroupSettings': {
                        'Destination': 's3://' + OUTPUT_BUCKET + '/' + output_path,
-                        'Encryption': {
-                            'EncryptionMethod': 'AES128',
-                            'StaticKeyProvider': {
-                                'StaticKeyValue': key_value,
-                                'Url': os.path.basename(output_path + key_file)
-                            },
-                            'Type': 'STATIC_KEY'
-                        }
                    }
                }

CMAFで試す場合

                'OutputGroupSettings': {
-                    'HlsGroupSettings': {
+                    'CmafGroupSettings': {
                        'Destination": 's3://' + OUTPUT_BUCKET + '/' + output_path,
                        'Encryption': {
-                            'EncryptionMethod': 'AES128',
+                            'EncryptionMethod': 'SAMPLE_AES',
                            'StaticKeyProvider': {
                                'StaticKeyValue': key_value,
                                'Url': os.path.basename(output_path + key_file)
                            },
                            'Type': 'STATIC_KEY'
                        }
                    }
                }

Lambda関数の環境変数変更

MEDIACONVERT_JOB_TEMPLATE
「HLS_1Mbps」 → 「DASH_1Mbps」または「CMAF_1Mbps」

デプロイしてテスト

DASHで、Encryption以下が存在する場合

EncryptionMethodの階層は、PlaybackDeviceCompatibilityかSpekeKeyProviderのいずれか。
StaticKeyProviderやTypeも同様

Response
{
  "errorMessage": "Parameter validation failed:\nUnknown parameter in Settings.OutputGroups[0].OutputGroupSettings.DashIsoGroupSettings.Encryption: \"EncryptionMethod\", must be one of: PlaybackDeviceCompatibility, SpekeKeyProvider\nUnknown parameter in Settings.OutputGroups[0].OutputGroupSettings.DashIsoGroupSettings.Encryption: \"StaticKeyProvider\", must be one of: PlaybackDeviceCompatibility, SpekeKeyProvider\nUnknown parameter in Settings.OutputGroups[0].OutputGroupSettings.DashIsoGroupSettings.Encryption: \"Type\", must be one of: PlaybackDeviceCompatibility, SpekeKeyProvider",
  "errorType": "ParamValidationError",

StaticKeyProviderは、PlaybackDeviceCompatibilityかSpekeKeyProviderのいずれかで、StaticKeyProviderもない。

Response
{
  "errorMessage": "Parameter validation failed:\nUnknown parameter in Settings.OutputGroups[0].OutputGroupSettings.DashIsoGroupSettings.Encryption: \"StaticKeyProvider\", must be one of: PlaybackDeviceCompatibility, SpekeKeyProvider\nUnknown parameter in Settings.OutputGroups[0].OutputGroupSettings.DashIsoGroupSettings.Encryption: \"Type\", must be one of: PlaybackDeviceCompatibility, SpekeKeyProvider",
  "errorType": "ParamValidationError",

DASHで、Encryption以下が存在しない場合

通るけど、暗号化されない。DRM使わないと暗号化できなそう。

Dash JavaScript Player
https://reference.dashif.org/dash.js/v4.3.0/samples/dash-if-reference-player/index.html

今回は下記(しばらく残しておきます)
https://cdn.nightonly.com/Big%20Buck%20Bunny_20220424025914/Big%20Buck%20Bunny.mpd

CMAFで、EncryptionMethodがAES128の場合

Response
{
  "errorMessage": "An error occurred (BadRequestException) when calling the CreateJob operation: The request could not be interpreted.",
  "errorType": "BadRequestException",

CMAFで、EncryptionMethodがAES_CTRの場合

encryptionMethodは、SAMPLE_AESのみ。

Response
{
  "errorMessage": "An error occurred (BadRequestException) when calling the CreateJob operation: /outputGroups/0/outputGroupSettings/cmafGroupSettings/encryption/staticKeyProvider: Should match all dependencies: See other errors for more details | /outputGroups/0/outputGroupSettings/cmafGroupSettings/encryption/encryptionMethod: Must be SAMPLE_AES",
  "errorType": "BadRequestException",

CMAFで、EncryptionMethodがSAMPLE_AESの場合

通るけど、再生できない。

Dash JavaScript Player
https://reference.dashif.org/dash.js/v4.3.0/samples/dash-if-reference-player/index.html

hls.js demo
https://hls-js.netlify.app/demo/

今回は下記(しばらく残しておきます)
https://cdn.nightonly.com/Big%20Buck%20Bunny_20220424030802/Big%20Buck%20Bunny.mpd
https://cdn.nightonly.com/Big%20Buck%20Bunny_20220424030802/Big%20Buck%20Bunny.m3u8

ここを参考にKeyも変えてみましたが、状況変わらず。
ここはやり方や対応ブラウザを把握できれば出来るかもしれないけど、DASHはマニフェスト(mpd)の定義が違いそうなので、MediaConvertのみで対応するのは難しそう。
Using Sample AES Encryption for HLS with Unified Origin — Unified Streaming

結論

AES128で暗号化かつ、MediaConvertのみで実現したい場合でHLS使うのが良さそう(今の所)

S3設置トリガーで自動変換と、MediaConvertでCMAFを暗号化(未解決)してみる” に対して3件のコメントがあります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です