[新機能] AWS Elemental MediaLiveでチャンネル設定をJSONでExport/Importする機能が追加されました!
はじめに
清水です。先日東京リージョンでも利用可能になったAWS Elemental MediaLiveですが、新たにチャンネル設定をJSON形式でExport/Inportする機能が追加されました。
- AWS Elemental MediaLive adds Live Channel Configuration Export and Import via JSON
- AWS Developer Forums: AWS Elemental MediaLive adds Live Channel Configuration Export and Import via JSON
これまでも設定済みのテンプレートを利用する、既存チャンネルをCloneするという機能はあったのですが、これでカスタマイズしたチャンネル設定を残しておくこと、また別アカウント/別リージョンにチャンネル設定を移す、ということが容易にできるようになりました。これまで別リージョンで使っていたチャンネル設定を東京リージョンで利用したい、なんてときにとても便利ですね!ナイスタイミングでとてもうれしいアップデードです。本エントリではこのJSONでのExport/Inport機能を実際に試してみたのでまとめてみます。
MediaLiveのチャンネル設定をJSONでExportしてみる
MediaLiveのチャンネル設定をExportするため、まずはオレゴンリージョンでチャンネルを作成してみます。チャンネル設定としては設定済みのテンプレート「Live event」を選択しました。
これをそのままExportしてもおもしろくないので… 出力設定を少しカスタマイズしてみます。まずはABR設定の一番高ビットレート、高解像度の設定になる、Output 1に登録されている「_1080p30」の設定を削除します。
削除すると、このようにOutput 1は2つ目のABR設定だった「_720p30」がOutput 1となります。
ついで、出力設定にHLSの他、Archive出力も追加してみます。以下のように出力先はS3を設定しました。これで[Create channel]ボタンを押下して、チャンネルを作成します。
チャンネル作成後、チャンネル詳細ページに[Create custom template]のボタンがありますね。こちらをダウンロードすると、チャンネル設定がJSONでダウンロードできます。
[チャンネル名].jsonという名称でダウンロードできますね。ダウンロードしてみたJSONはこちらのようになりました。(けっこう長めのJSONです… 500行超)
{ "name": "MediaLiveChannel0208", "id": "XXXXXXX", "arn": "arn:aws:medialive:us-west-2:123456789012:channel:XXXXXXX", "inputAttachments": [ { "inputId": "XXXXXXX", "inputSettings": { "networkInputSettings": { "serverValidation": "CHECK_CRYPTOGRAPHY_AND_VALIDATE_NAME" }, "sourceEndBehavior": "CONTINUE", "inputFilter": "AUTO", "filterStrength": 1, "deblockFilter": "DISABLED", "denoiseFilter": "DISABLED", "audioSelectors": [], "captionSelectors": [ { "selectorSettings": { "embeddedSourceSettings": { "source608ChannelNumber": 1, "source608TrackNumber": 1, "convert608To708": "DISABLED", "scte20Detection": "OFF" } }, "name": "EmbeddedSelector" } ] } } ], "state": "RUNNING", "pipelinesRunningCount": 2, "destinations": [ { "id": "destination1", "settings": [ { "url": "mediastoressl://XXXXXXXXXXXXXX.data.mediastore.us-west-2.amazonaws.com/live/mystream", "username": "", "passwordParam": "" }, { "url": "mediastoressl://XXXXXXXXXXXXXX.data.mediastore.us-west-2.amazonaws.com/live/mystream", "username": "", "passwordParam": "" } ] }, { "id": "k805s", "settings": [ { "url": "s3ssl://XXXXXXXXXXXXXXXXXXXX/medialive-archive/MediaLiveChannel0208/delivery", "username": "", "passwordParam": "" }, { "url": "s3ssl://XXXXXXXXXXXXXXXXXXXX/medialive-archive/MediaLiveChannel0208/backup", "username": "", "passwordParam": "" } ] } ], "egressEndpoints": [ { "sourceIp": "XX.XX.XX.XX" }, { "sourceIp": "XX.XX.XX.XX" } ], "encoderSettings": { "audioDescriptions": [ { "codecSettings": { "aacSettings": { "inputType": "NORMAL", "bitrate": 128000, "codingMode": "CODING_MODE_2_0", "rawFormat": "NONE", "spec": "MPEG4", "profile": "LC", "rateControlMode": "CBR", "sampleRate": 48000 } }, "audioTypeControl": "FOLLOW_INPUT", "languageCodeControl": "FOLLOW_INPUT", "name": "audio_2" }, { "codecSettings": { "aacSettings": { "inputType": "NORMAL", "bitrate": 192000, "codingMode": "CODING_MODE_2_0", "rawFormat": "NONE", "spec": "MPEG4", "profile": "LC", "rateControlMode": "CBR", "sampleRate": 48000 } }, "audioTypeControl": "FOLLOW_INPUT", "languageCodeControl": "FOLLOW_INPUT", "name": "audio_za9dzo" }, { "codecSettings": { "aacSettings": { "inputType": "NORMAL", "bitrate": 192000, "codingMode": "CODING_MODE_2_0", "rawFormat": "NONE", "spec": "MPEG4", "profile": "LC", "rateControlMode": "CBR", "sampleRate": 48000 } }, "audioTypeControl": "FOLLOW_INPUT", "languageCodeControl": "FOLLOW_INPUT", "name": "audio_40bxb2" }, { "codecSettings": { "aacSettings": { "inputType": "NORMAL", "bitrate": 192000, "codingMode": "CODING_MODE_2_0", "rawFormat": "NONE", "spec": "MPEG4", "profile": "LC", "rateControlMode": "CBR", "sampleRate": 48000 } }, "audioTypeControl": "FOLLOW_INPUT", "languageCodeControl": "FOLLOW_INPUT", "name": "audio_n4q6tr" } ], "captionDescriptions": [], "outputGroups": [ { "outputGroupSettings": { "hlsGroupSettings": { "adMarkers": [], "captionLanguageSetting": "OMIT", "captionLanguageMappings": [], "hlsCdnSettings": { "hlsWebdavSettings": { "numRetries": 10, "connectionRetryInterval": 1, "restartDelay": 15, "filecacheDuration": 300, "httpTransferMode": "NON_CHUNKED" } }, "inputLossAction": "EMIT_OUTPUT", "manifestCompression": "NONE", "destination": { "destinationRefId": "destination1" }, "ivInManifest": "INCLUDE", "ivSource": "FOLLOWS_SEGMENT_NUMBER", "clientCache": "ENABLED", "tsFileMode": "SEGMENTED_FILES", "manifestDurationFormat": "INTEGER", "segmentationMode": "USE_SEGMENT_DURATION", "outputSelection": "MANIFESTS_AND_SEGMENTS", "streamInfResolution": "INCLUDE", "indexNSegments": 10, "programDateTime": "EXCLUDE", "programDateTimePeriod": 600, "keepSegments": 21, "segmentLength": 6, "timedMetadataId3Frame": "PRIV", "timedMetadataId3Period": 10, "codecSpecification": "RFC_4281", "directoryStructure": "SINGLE_DIRECTORY", "segmentsPerSubdirectory": 10000, "mode": "LIVE" } }, "name": "HD", "outputs": [ { "outputSettings": { "hlsOutputSettings": { "nameModifier": "_720p30", "hlsSettings": { "standardHlsSettings": { "m3u8Settings": { "audioFramesPerPes": 4, "audioPids": "492-498", "ecmPid": "8182", "pcrControl": "PCR_EVERY_PES_PACKET", "pmtPid": "480", "programNum": 1, "scte35Pid": "500", "scte35Behavior": "NO_PASSTHROUGH", "timedMetadataBehavior": "NO_PASSTHROUGH", "videoPid": "481" }, "audioRenditionSets": "PROGRAM_AUDIO" } } } }, "videoDescriptionName": "video_720p30", "audioDescriptionNames": [ "audio_2" ], "captionDescriptionNames": [] }, { "outputSettings": { "hlsOutputSettings": { "nameModifier": "_480p30", "hlsSettings": { "standardHlsSettings": { "m3u8Settings": { "audioFramesPerPes": 4, "audioPids": "492-498", "ecmPid": "8182", "pcrControl": "PCR_EVERY_PES_PACKET", "pmtPid": "480", "programNum": 1, "scte35Pid": "500", "scte35Behavior": "NO_PASSTHROUGH", "timedMetadataBehavior": "NO_PASSTHROUGH", "videoPid": "481" }, "audioRenditionSets": "PROGRAM_AUDIO" } } } }, "videoDescriptionName": "video_480p30", "audioDescriptionNames": [ "audio_za9dzo" ], "captionDescriptionNames": [] }, { "outputSettings": { "hlsOutputSettings": { "nameModifier": "_240p30", "hlsSettings": { "standardHlsSettings": { "m3u8Settings": { "audioFramesPerPes": 4, "audioPids": "492-498", "ecmPid": "8182", "pcrControl": "PCR_EVERY_PES_PACKET", "pmtPid": "480", "programNum": 1, "scte35Pid": "500", "scte35Behavior": "NO_PASSTHROUGH", "timedMetadataBehavior": "NO_PASSTHROUGH", "videoPid": "481" }, "audioRenditionSets": "PROGRAM_AUDIO" } } } }, "videoDescriptionName": "video_240p30", "audioDescriptionNames": [ "audio_40bxb2" ], "captionDescriptionNames": [] } ] }, { "outputGroupSettings": { "archiveGroupSettings": { "destination": { "destinationRefId": "k805s" }, "rolloverInterval": 600 } }, "name": "MediaLiveChannel0208", "outputs": [ { "outputSettings": { "archiveOutputSettings": { "nameModifier": "_1", "containerSettings": { "m2tsSettings": { "ccDescriptor": "DISABLED", "ebif": "NONE", "programNum": 1, "patInterval": 100, "pmtInterval": 100, "pcrControl": "PCR_EVERY_PES_PACKET", "pcrPeriod": 40, "timedMetadataBehavior": "NO_PASSTHROUGH", "bufferModel": "MULTIPLEX", "rateMode": "CBR", "audioBufferModel": "ATSC", "audioStreamType": "DVB", "audioFramesPerPes": 2, "segmentationStyle": "MAINTAIN_CADENCE", "segmentationMarkers": "NONE", "ebpPlacement": "VIDEO_AND_AUDIO_PIDS", "ebpAudioInterval": "VIDEO_INTERVAL", "esRateInPes": "EXCLUDE", "arib": "DISABLED", "aribCaptionsPidControl": "AUTO", "absentInputAudioBehavior": "ENCODE_SILENCE", "pmtPid": "480", "videoPid": "481", "audioPids": "482-498", "dvbTeletextPid": "499", "dvbSubPids": "460-479", "scte27Pids": "450-459", "scte35Pid": "500", "scte35Control": "NONE", "klv": "NONE", "klvDataPids": "501", "timedMetadataPid": "502", "etvPlatformPid": "504", "etvSignalPid": "505", "ecmPid": "506", "aribCaptionsPid": "507" } } } }, "outputName": "fydhcj", "videoDescriptionName": "video_pxpv4", "audioDescriptionNames": [ "audio_n4q6tr" ], "captionDescriptionNames": [] } ] } ], "timecodeConfig": { "source": "EMBEDDED" }, "videoDescriptions": [ { "codecSettings": { "h264Settings": { "afdSignaling": "NONE", "colorMetadata": "INSERT", "adaptiveQuantization": "HIGH", "bitrate": 3000000, "entropyEncoding": "CABAC", "flickerAq": "ENABLED", "framerateControl": "SPECIFIED", "framerateNumerator": 30, "framerateDenominator": 1, "gopBReference": "ENABLED", "gopClosedCadence": 1, "gopNumBFrames": 3, "gopSize": 60, "gopSizeUnits": "FRAMES", "scanType": "PROGRESSIVE", "level": "H264_LEVEL_AUTO", "lookAheadRateControl": "HIGH", "numRefFrames": 3, "parControl": "INITIALIZE_FROM_SOURCE", "profile": "HIGH", "rateControlMode": "CBR", "syntax": "DEFAULT", "sceneChangeDetect": "ENABLED", "slices": 1, "spatialAq": "ENABLED", "temporalAq": "ENABLED", "timecodeInsertion": "DISABLED" } }, "height": 720, "name": "video_720p30", "respondToAfd": "NONE", "sharpness": 100, "scalingBehavior": "DEFAULT", "width": 1280 }, { "codecSettings": { "h264Settings": { "afdSignaling": "NONE", "colorMetadata": "INSERT", "adaptiveQuantization": "HIGH", "bitrate": 1500000, "entropyEncoding": "CABAC", "flickerAq": "ENABLED", "framerateControl": "SPECIFIED", "framerateNumerator": 30, "framerateDenominator": 1, "gopBReference": "ENABLED", "gopClosedCadence": 1, "gopNumBFrames": 3, "gopSize": 60, "gopSizeUnits": "FRAMES", "scanType": "PROGRESSIVE", "level": "H264_LEVEL_AUTO", "lookAheadRateControl": "HIGH", "numRefFrames": 3, "parControl": "SPECIFIED", "parNumerator": 4, "parDenominator": 3, "profile": "MAIN", "rateControlMode": "CBR", "syntax": "DEFAULT", "sceneChangeDetect": "ENABLED", "slices": 1, "spatialAq": "ENABLED", "temporalAq": "ENABLED", "timecodeInsertion": "DISABLED" } }, "height": 480, "name": "video_480p30", "respondToAfd": "NONE", "sharpness": 100, "scalingBehavior": "STRETCH_TO_OUTPUT", "width": 640 }, { "codecSettings": { "h264Settings": { "afdSignaling": "NONE", "colorMetadata": "INSERT", "adaptiveQuantization": "HIGH", "bitrate": 750000, "entropyEncoding": "CABAC", "flickerAq": "ENABLED", "framerateControl": "SPECIFIED", "framerateNumerator": 30, "framerateDenominator": 1, "gopBReference": "ENABLED", "gopClosedCadence": 1, "gopNumBFrames": 3, "gopSize": 60, "gopSizeUnits": "FRAMES", "scanType": "PROGRESSIVE", "level": "H264_LEVEL_AUTO", "lookAheadRateControl": "HIGH", "numRefFrames": 3, "parControl": "SPECIFIED", "parNumerator": 4, "parDenominator": 3, "profile": "MAIN", "rateControlMode": "CBR", "syntax": "DEFAULT", "sceneChangeDetect": "ENABLED", "slices": 1, "spatialAq": "ENABLED", "temporalAq": "ENABLED", "timecodeInsertion": "DISABLED" } }, "height": 240, "name": "video_240p30", "respondToAfd": "NONE", "sharpness": 100, "scalingBehavior": "STRETCH_TO_OUTPUT", "width": 320 }, { "codecSettings": { "h264Settings": { "afdSignaling": "NONE", "colorMetadata": "INSERT", "adaptiveQuantization": "MEDIUM", "bitrate": 5000000, "entropyEncoding": "CABAC", "flickerAq": "ENABLED", "framerateControl": "INITIALIZE_FROM_SOURCE", "gopBReference": "DISABLED", "gopClosedCadence": 1, "gopNumBFrames": 2, "gopSize": 90, "gopSizeUnits": "FRAMES", "scanType": "PROGRESSIVE", "level": "H264_LEVEL_AUTO", "lookAheadRateControl": "MEDIUM", "numRefFrames": 1, "parControl": "INITIALIZE_FROM_SOURCE", "profile": "MAIN", "rateControlMode": "CBR", "syntax": "DEFAULT", "sceneChangeDetect": "ENABLED", "spatialAq": "ENABLED", "temporalAq": "ENABLED", "timecodeInsertion": "DISABLED" } }, "name": "video_pxpv4", "respondToAfd": "NONE", "sharpness": 50, "scalingBehavior": "DEFAULT" } ] }, "roleArn": "arn:aws:iam::123456789012:role/MediaLiveAccessRole", "inputSpecification": { "codec": "AVC", "resolution": "HD", "maximumBitrate": "MAX_20_MBPS" } }
MediaLiveのチャンネル設定をJSONからImportしてみる
今度はExportしたJSONを、Importしてみます。せっかくなのでサービスリリースされたばかりの東京リージョンでImportして、新たにチャンネルを作成してみましょう。Create channelページの最下部にある、Channel templateの箇所で[Select custom template]のボタンをクリックし、さきほどダウンロードしたJSONファイルを選択します。
JSONをImportすると、いくつかの項目がJSONに記載された内容で設定済みになります。チャンネル名は「[設定元チャンネル名] - clone」となるようですね。またOutput groupsもImportしたJSONの内容が引き継がれていることがわかります。対して、Inputについては設定されていません。(リージョンやアカウントが違えばJSONに記載のあるInputを使うことはできませんし、また同一リージョンでも既存Inputが使用中であれば重複してアタッチすることはできません。InputについてはJSONをImportした後で自分で設定する、としたほうがよいですね。)
その他確認できた項目として、Output groupsの各項目の出力先については設定がそのまま残っていました。例えばHLS group destinationについてはMediaStoreを設定していましたが、こちらのように。
またArchive設定についても出力先S3バケット、パスが残っていました。
まとめ
AWS Elemental MediaLiveに新しく追加されたチャンネル設定のJSONでのExport/Import機能を使い、チャンネル設定をオレゴンリージョンから東京リージョンに移してみました。MediaLiveでは出力設定なども細く設定できますが、その分同じ設定を複製する、といったことがが手動でやる場合は大変になります。(し、なるべくなら手動ではやりたくないですよね。)MediaLiveの利便性を高めるすてきなアップデートだと思います。引き続きMediaLive含めたAWS Media Servicesの機能アップデートに注目していきたいと思います!