目次

AWS Elemental MediaConvert v2.0 完全ガイド 2026

初心者から実務者向けの包括的解説

AWS Elemental MediaConvert は、ファイルベースのビデオトランスコーディングサービス であり、S3 に保存されたソース動画を HLS / DASH / MP4 / MXF 等の複数フォーマットに高速に変換します。H.264・H.265・AV1・VP8・VP9 などの多彩なコーデック、10-bit HDR(HDR10・HDR10+・HLG・Dolby Vision)、高度なオーディオ処理、DRM 統合、字幕・ウォーターマーク等の放送グレード機能を備え、VOD 配信・OTT ストリーミング・ライブアーカイブ・エンタープライズメディア処理に対応します。本ドキュメントは MediaConvert の概念・アーキテクチャ・実装・ベストプラクティス・最新動向を体系的に解説する包括的ガイドです。

ドキュメント対象者

  • 初心者向け:MediaConvert の基本概念・選ぶ理由・ユースケースを理解したい方
  • 開発者向け:S3 上の動画を HLS / DASH でマルチビットレート変換したい方
  • メディア技術者向け:HDR・DRM・字幕・ABR・カスタムプリセットを実装したい方
  • アーキテクト向け:Elastic Transcoder からの移行・大規模 VOD パイプライン設計の判断
  • SRE 向け:Lambda・EventBridge・CloudFormation との自動化統合

概要と課題

MediaConvert が解決する課題

複数デバイス・ネットワーク対応の動画配信

  • スマートフォン・タブレット・PC・スマート TV・4K デバイスなど異なる画面サイズと回線速度に対応する必要があり、同一コンテンツを複数品質(360p・480p・720p・1080p・4K)に自動変換する機能が必須

放送品質のビデオ処理

  • プロフェッショナルなメディア配信には HDR・ドルビー音声・多言語字幕・ウォーターマーク・DRM(Widevine・FairPlay・PlayReady)が必須だが、FFmpeg などのオープンソースでは機能制限・商用サポートなし

スケーラブルな自動化

  • 大量の動画ファイルを処理する際、EC2 + FFmpeg では運用管理が煩雑でコスト効率が悪く、MediaConvert はマネージドサービスで自動スケーリングと従量課金対応

迅速な配信パイプライン構築

  • S3 + Lambda + EventBridge + MediaConvert を組み合わせることで、サーバーレスで VOD 配信パイプラインを数日で実装可能

主な特徴

特徴 説明
マルチコーデック対応 H.264・H.265・AV1・VP8・VP9・Apple ProRes・MPEG-2
HDR 完全サポート HDR10・HDR10+・HLG・Dolby Vision 対応
QVBR エンコーディング Quality-Defined Variable Bitrate で最適品質を自動達成
DRM 統合(SPEKE) Widevine・FairPlay・PlayReady を統合管理
字幕・CC 対応 SRT・WebVTT・708 CC・708 SCTE・DVB Sub・Teletext
アダプティブビットレート 1 ジョブで複数品質の HLS / DASH プレイリスト自動生成
音声トラック多重化 複数言語音声・5.1 サラウンド・Dolby Atmos 対応
静止画生成 サムネイル・スプライトシート自動生成
カラー変換 HDR → SDR・色空間変換・10-bit 対応

アーキテクチャ概要

graph TB
    subgraph Sources["ソース"]
        S3["Amazon S3<br/>MP4/MXF/MOV"]
        HTTP["HTTP/HTTPS URL"]
        File["ローカルファイル<br/>(EventBridge)"]
    end
    
    subgraph MediaConvert["MediaConvert"]
        Job["トランスコーディング<br/>ジョブ"]
        Preset["プリセット設定<br/>(H.264/HEVC/AV1)"]
        Output["出力グループ<br/>(HLS/DASH/MP4)"]
    end
    
    subgraph Processing["処理オプション"]
        HDR["HDR処理<br/>(HDR10/Dolby Vision)"]
        DRM["DRM設定<br/>(SPEKE)"]
        Captions["字幕処理<br/>(SRT/WebVTT/708CC)"]
        Audio["オーディオ処理<br/>(多言語/Dolby Atmos)"]
    end
    
    subgraph Outputs["出力フォーマット"]
        HLS["HLS プレイリスト<br/>(iOS/Apple TV)"]
        DASH["DASH マニフェスト<br/>(Android/Web)"]
        CMAF["CMAF<br/>(統合フォーマット)"]
        MP4["MP4/MXF<br/>(ダウンロード/放送)"]
    end
    
    subgraph Storage["ストレージ・配信"]
        S3Out["Amazon S3<br/>マルチビットレート"]
        CloudFront["CloudFront<br/>CDN配信"]
        MediaPackage["MediaPackage<br/>パッケージング"]
    end
    
    Sources -->|入力指定| Job
    Preset -->|設定適用| Job
    Job -->|出力形式| Output
    HDR -->|オプション| Output
    DRM -->|オプション| Output
    Captions -->|オプション| Output
    Audio -->|オプション| Output
    Output -->|HLS生成| HLS
    Output -->|DASH生成| DASH
    Output -->|CMAF生成| CMAF
    Output -->|MP4生成| MP4
    HLS -->|格納| S3Out
    DASH -->|格納| S3Out
    CMAF -->|格納| S3Out
    MP4 -->|格納| S3Out
    S3Out -->|配信| CloudFront
    S3Out -->|入力| MediaPackage

処理フロー

sequenceDiagram
    actor User as ユーザー
    participant S3
    participant EventBridge
    participant Lambda
    participant MediaConvert
    participant CloudWatch
    
    User->>S3: 1. 動画ファイルアップロード
    S3->>EventBridge: 2. 物体作成イベント通知
    EventBridge->>Lambda: 3. Lambda トリガー
    Lambda->>MediaConvert: 4. create-job(ジョブ作成)
    MediaConvert->>MediaConvert: 5. トランスコーディング実行
    MediaConvert->>CloudWatch: 6. ジョブステータス通知
    MediaConvert->>S3: 7. HLS/DASHファイル出力
    Lambda->>Lambda: 8. 完了通知(SNS/メール)

コアコンポーネント詳説

1. Job(トランスコーディングジョブ)

ジョブは実際の変換処理を実行する単位です。以下を指定します。

  • 入力(Inputs):S3 URL、HTTP URL、MediaConnect フロー
  • 入力設定(InputSettings):フレームレート・アスペクト比・フィルター(ノイズ除去・デブロック)
  • 出力グループ(OutputGroups):HLS / DASH / CMAF / MP4 の複数同時出力
  • 各出力の設定:コーデック・ビットレート・解像度・フレームレート

ジョブの状態遷移

  • SUBMITTEDPROGRESSINGCOMPLETE / CANCELED / ERROR

2. Queue(リソースプール)

複数ジョブの並列処理を制御するリソース管理機構です。

  • On-Demand Queue:ジョブを投入すると自動スケーリング
  • Reserved Queue:事前に容量確保(20~100 GBps 単位)し、最大 75% コスト削減
  • Pricing Tier:Basic / Standard / Pro(AV1・10-bit・4K 対応)

3. Preset(エンコーディングプリセット)

事前定義されたエンコーディング設定テンプレート。

  • システムプリセット:AWS が提供する一般的なフォーマット(HLS_360p・HLS_720p・DASH_1080p 等)
  • カスタムプリセット:組織固有の設定を保存・再利用

4. JobTemplate(ジョブテンプレート)

入力ファイルパス・メタデータ以外のすべてを事前設定。S3 自動トリガーやバッチ処理で活用。


主要ユースケース 10+

1. OTT ストリーミング VOD 配信パイプライン

ユーザー投稿動画を自動的にマルチビットレート HLS に変換して CloudFront で配信。

  • ユーザー upload → S3 → EventBridge → Lambda → MediaConvert
  • → HLS (360p/480p/720p/1080p) → S3 → CloudFront

2. ライブイベントのアーカイブ

MediaLive で録画したライブストリームを即座に VOD 化(Live to VOD)。

  • MediaLive 録画 → S3 → MediaConvert → DASH 生成 → MediaPackage

3. 放送品質ファイル変換

放送局のフォーマット(MXF・DNxHD)を OTT フォーマット(HLS・DASH)に変換。

  • MXF (10-bit 4:2:2) → MediaConvert → HLS (H.265) + DRM

4. HDR コンテンツ処理

HDR10 / Dolby Vision で撮影したコンテンツを複数形式に最適化。

  • DCI-P3 (Dolby Vision) → HDR10 / SDR (H.265) / Dolby Vision 分岐出力

5. マルチ言語字幕・音声対応

複数言語の音声・字幕を1ジョブで統合管理。

  • メイン映像 + 日本語音声・英語音声・フランス語音声 + SRT字幕
  • → HLS (複数音声トラック + 字幕)

6. DRM コンテンツ保護

有料 VOD サービスでの Widevine・FairPlay DRM 統合。

  • コンテンツ + DRM キーサーバー (SPEKE) → 暗号化 HLS/DASH

7. サムネイル・スプライトシート生成

動画から自動的にプレビュー画像を抽出。

  • 入力動画 → 360p 映像 + サムネイル(毎秒)+ スプライトシート生成

8. エンタープライズ企業ビデオ配信

社内イベント・研修・製品デモを複数品質で配信。

  • 社内イベント → MP4 (複数品質) + HLS → 認証付き配信

9. e ラーニング・オンデマンド講座

講義動画を PC・スマホ・タブレット最適化版に自動変換。

  • 講義 MP4 (高品質) → 360p/480p/720p/1080p
    • モバイル最適化 (AAC 低ビットレート)

10. ウォーターマーク・オーバーレイ

ロゴ・テロップ・字幕をビデオに合成。

  • 入力動画 + PNG (ロゴ) + SRT (字幕)
  • → 合成出力 (MP4/HLS)

11. 4K / 8K 対応

超高解像度コンテンツの Professional Tier サポート。

  • 4K (DCI-P3) → AV1 4K (HDR10+) + H.265 4K (SDR) 分岐

12. ビデオ分析用データセット

ML トレーニング用に複数フォーマット・品質でデータセット生成。

  • ソース動画 → MP4 (複数フレームレート・ビットレート)
    • メタデータ抽出 (SageMaker)

設定・操作の具体例

AWS CLI を使用した基本的なジョブ作成

例1: シンプルな HLS マルチビットレート変換

#!/bin/bash

SOURCE_BUCKET="my-source-bucket"
SOURCE_KEY="videos/sample.mp4"
OUTPUT_BUCKET="my-output-bucket"
ROLE_ARN="arn:aws:iam::123456789012:role/MediaConvertRole"
ENDPOINT="https://abc123.mediaconvert.ap-northeast-1.amazonaws.com"

aws mediaconvert create-job \
  --role "$ROLE_ARN" \
  --queue-arn "arn:aws:mediaconvert:ap-northeast-1:123456789012:queues/Default" \
  --endpoint-url "$ENDPOINT" \
  --settings '{
    "Inputs": [
      {
        "FileInput": "s3://'$SOURCE_BUCKET'/'$SOURCE_KEY'",
        "AudioSelectors": {
          "Audio Selector 1": {
            "DefaultSelection": "DEFAULT"
          }
        },
        "VideoSelector": {}
      }
    ],
    "OutputGroups": [
      {
        "Name": "HLS Group",
        "OutputGroupSettings": {
          "Type": "HLS_GROUP_SETTINGS",
          "HlsGroupSettings": {
            "Destination": "s3://'$OUTPUT_BUCKET'/hls/",
            "SegmentLength": 6,
            "MinSegmentLength": 0,
            "PlaylistType": "VOD"
          }
        },
        "Outputs": [
          {
            "NameModifier": "_360p",
            "VideoDescription": {
              "CodecSettings": {
                "Codec": "H_264",
                "H264Settings": {
                  "RateControlMode": "QVBR",
                  "MaxBitrate": 800000,
                  "QvbrSettings": {
                    "QvbrQualityLevel": 7
                  }
                }
              },
              "Width": 640,
              "Height": 360
            },
            "AudioDescriptions": [
              {
                "CodecSettings": {
                  "Codec": "AAC",
                  "AacSettings": {
                    "Bitrate": 96000,
                    "SampleRate": 48000
                  }
                }
              }
            ],
            "ContainerSettings": {
              "Container": "M3U8"
            }
          },
          {
            "NameModifier": "_720p",
            "VideoDescription": {
              "CodecSettings": {
                "Codec": "H_264",
                "H264Settings": {
                  "RateControlMode": "QVBR",
                  "MaxBitrate": 3000000,
                  "QvbrSettings": {
                    "QvbrQualityLevel": 8
                  }
                }
              },
              "Width": 1280,
              "Height": 720
            },
            "AudioDescriptions": [
              {
                "CodecSettings": {
                  "Codec": "AAC",
                  "AacSettings": {
                    "Bitrate": 128000,
                    "SampleRate": 48000
                  }
                }
              }
            ],
            "ContainerSettings": {
              "Container": "M3U8"
            }
          },
          {
            "NameModifier": "_1080p",
            "VideoDescription": {
              "CodecSettings": {
                "Codec": "H_264",
                "H264Settings": {
                  "RateControlMode": "QVBR",
                  "MaxBitrate": 6000000,
                  "QvbrSettings": {
                    "QvbrQualityLevel": 9
                  }
                }
              },
              "Width": 1920,
              "Height": 1080
            },
            "AudioDescriptions": [
              {
                "CodecSettings": {
                  "Codec": "AAC",
                  "AacSettings": {
                    "Bitrate": 192000,
                    "SampleRate": 48000
                  }
                }
              }
            ],
            "ContainerSettings": {
              "Container": "M3U8"
            }
          }
        ]
      }
    ]
  }'

例2: HEVC + AV1 フォールバック(品質・ファイルサイズ最適化)

aws mediaconvert create-job \
  --role "$ROLE_ARN" \
  --endpoint-url "$ENDPOINT" \
  --settings '{
    "Inputs": [{
      "FileInput": "s3://'$SOURCE_BUCKET'/4k-content.mov"
    }],
    "OutputGroups": [
      {
        "Name": "HEVC_4K",
        "OutputGroupSettings": {
          "Type": "HLS_GROUP_SETTINGS",
          "HlsGroupSettings": {
            "Destination": "s3://'$OUTPUT_BUCKET'/hevc/"
          }
        },
        "Outputs": [{
          "NameModifier": "_4k_hevc",
          "VideoDescription": {
            "CodecSettings": {
              "Codec": "H_265",
              "H265Settings": {
                "RateControlMode": "QVBR",
                "MaxBitrate": 15000000,
                "QvbrSettings": {"QvbrQualityLevel": 9},
                "FramerateDenominator": 1,
                "FramerateNumerator": 24
              }
            },
            "Width": 3840,
            "Height": 2160
          }
        }]
      },
      {
        "Name": "AV1_4K",
        "OutputGroupSettings": {
          "Type": "HLS_GROUP_SETTINGS",
          "HlsGroupSettings": {
            "Destination": "s3://'$OUTPUT_BUCKET'/av1/"
          }
        },
        "Outputs": [{
          "NameModifier": "_4k_av1",
          "VideoDescription": {
            "CodecSettings": {
              "Codec": "AV1",
              "Av1Settings": {
                "RateControlMode": "QVBR",
                "MaxBitrate": 10000000,
                "QvbrSettings": {"QvbrQualityLevel": 9},
                "FramerateControl": "SPECIFIED_FRAMERATE",
                "FramerateDenominator": 1,
                "FramerateNumerator": 24
              }
            },
            "Width": 3840,
            "Height": 2160
          }
        }]
      }
    ]
  }'

例3: DRM + SPEKE + 複数言語字幕

aws mediaconvert create-job \
  --role "$ROLE_ARN" \
  --endpoint-url "$ENDPOINT" \
  --settings '{
    "Inputs": [{
      "FileInput": "s3://'$SOURCE_BUCKET'/premium-content.mxf",
      "AudioSelectors": {
        "Audio 1": {"DefaultSelection": "DEFAULT"},
        "Audio 2": {"Selector": "Selector 2"}
      },
      "CaptionSelectors": {
        "Captions 1": {
          "SourceSettings": {
            "SourceType": "SCC"
          }
        }
      }
    }],
    "OutputGroups": [{
      "Name": "DASH_DRM",
      "OutputGroupSettings": {
        "Type": "DASH_ISO_GROUP_SETTINGS",
        "DashIsoGroupSettings": {
          "Destination": "s3://'$OUTPUT_BUCKET'/dash-drm/",
          "SegmentLength": 6,
          "Encryption": {
            "SpekeKeyProvider": {
              "CertificateArn": "arn:aws:acm:ap-northeast-1:123456789012:certificate/...",
              "ResourceId": "resource-id-123",
              "SystemIds": [
                "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",
                "94ce86fb-07ff-4f43-adb8-93d2fa968ca2"
              ],
              "Url": "https://speke.example.com/v1/copyProtection"
            }
          }
        }
      },
      "Outputs": [{
        "NameModifier": "_dash",
        "VideoDescription": {
          "CodecSettings": {
            "Codec": "H_265",
            "H265Settings": {
              "RateControlMode": "QVBR",
              "MaxBitrate": 5000000,
              "QvbrSettings": {"QvbrQualityLevel": 8}
            }
          }
        },
        "AudioDescriptions": [
          {
            "LanguageCode": "JPN",
            "CodecSettings": {
              "Codec": "AAC",
              "AacSettings": {
                "Bitrate": 128000,
                "SampleRate": 48000
              }
            }
          },
          {
            "LanguageCode": "ENG",
            "CodecSettings": {
              "Codec": "AAC",
              "AacSettings": {
                "Bitrate": 128000,
                "SampleRate": 48000
              }
            }
          }
        ],
        "CaptionDescriptions": [
          {
            "LanguageCode": "JPN",
            "DestinationSettings": {
              "DvbSubDestinationSettings": {
                "OutlineColor": "BLACK",
                "OutlineSize": 1
              }
            }
          }
        ]
      }]
    }]
  }'

Python SDK を使用したジョブ作成

import boto3
import json
import os
from datetime import datetime

class MediaConvertJobManager:
    def __init__(self, endpoint_url, role_arn, region='ap-northeast-1'):
        self.client = boto3.client(
            'mediaconvert',
            endpoint_url=endpoint_url,
            region_name=region
        )
        self.role_arn = role_arn
    
    def create_hls_job(self, source_s3, dest_s3_prefix, quality_levels=None):
        """
        HLS マルチビットレートジョブを作成
        quality_levels: [{'res': '360p', 'bitrate': 800000}, ...]
        """
        if quality_levels is None:
            quality_levels = [
                {'res': '360p', 'bitrate': 800000, 'width': 640, 'height': 360},
                {'res': '720p', 'bitrate': 3000000, 'width': 1280, 'height': 720},
                {'res': '1080p', 'bitrate': 6000000, 'width': 1920, 'height': 1080}
            ]
        
        outputs = []
        for level in quality_levels:
            outputs.append({
                'NameModifier': f"_{level['res']}",
                'VideoDescription': {
                    'CodecSettings': {
                        'Codec': 'H_264',
                        'H264Settings': {
                            'RateControlMode': 'QVBR',
                            'MaxBitrate': level['bitrate'],
                            'QvbrSettings': {
                                'QvbrQualityLevel': 7 + (len(outputs) % 3)
                            }
                        }
                    },
                    'Width': level['width'],
                    'Height': level['height']
                },
                'AudioDescriptions': [{
                    'CodecSettings': {
                        'Codec': 'AAC',
                        'AacSettings': {
                            'Bitrate': 128000,
                            'SampleRate': 48000
                        }
                    }
                }],
                'ContainerSettings': {'Container': 'M3U8'}
            })
        
        settings = {
            'Inputs': [{
                'FileInput': source_s3,
                'AudioSelectors': {'Audio Selector 1': {'DefaultSelection': 'DEFAULT'}},
                'VideoSelector': {}
            }],
            'OutputGroups': [{
                'Name': 'HLS Group',
                'OutputGroupSettings': {
                    'Type': 'HLS_GROUP_SETTINGS',
                    'HlsGroupSettings': {
                        'Destination': dest_s3_prefix,
                        'SegmentLength': 6,
                        'MinSegmentLength': 0,
                        'PlaylistType': 'VOD'
                    }
                },
                'Outputs': outputs
            }]
        }
        
        response = self.client.create_job(
            Role=self.role_arn,
            Settings=settings
        )
        
        return response['Job']['Id']
    
    def create_av1_job(self, source_s3, dest_s3_prefix, max_bitrate=10000000, quality=9):
        """AV1 エンコーディングジョブを作成(4K 最適化)"""
        settings = {
            'Inputs': [{
                'FileInput': source_s3,
                'VideoSelector': {}
            }],
            'OutputGroups': [{
                'Name': 'AV1 Output',
                'OutputGroupSettings': {
                    'Type': 'HLS_GROUP_SETTINGS',
                    'HlsGroupSettings': {
                        'Destination': dest_s3_prefix
                    }
                },
                'Outputs': [{
                    'VideoDescription': {
                        'CodecSettings': {
                            'Codec': 'AV1',
                            'Av1Settings': {
                                'RateControlMode': 'QVBR',
                                'MaxBitrate': max_bitrate,
                                'QvbrSettings': {'QvbrQualityLevel': quality}
                            }
                        },
                        'Width': 3840,
                        'Height': 2160
                    },
                    'ContainerSettings': {'Container': 'M3U8'}
                }]
            }]
        }
        
        response = self.client.create_job(
            Role=self.role_arn,
            Settings=settings
        )
        return response['Job']['Id']
    
    def create_hdr_job(self, source_s3, dest_s3_prefix):
        """HDR(HDR10 + SDR フォールバック)ジョブを作成"""
        settings = {
            'Inputs': [{
                'FileInput': source_s3,
                'VideoSelector': {
                    'Hdr10Metadata': {
                        'RedPrimaryX': 64000,
                        'RedPrimaryY': 33000,
                        'GreenPrimaryX': 29000,
                        'GreenPrimaryY': 61000,
                        'BluePrimaryX': 15000,
                        'BluePrimaryY': 6000,
                        'WhitePointX': 31800,
                        'WhitePointY': 33000,
                        'MaxFrameAverageLightLevel': 100,
                        'MaxContentLightLevel': 400
                    }
                }
            }],
            'OutputGroups': [
                {
                    'Name': 'HDR10 Output',
                    'OutputGroupSettings': {
                        'Type': 'HLS_GROUP_SETTINGS',
                        'HlsGroupSettings': {'Destination': f"{dest_s3_prefix}hdr10/"}
                    },
                    'Outputs': [{
                        'VideoDescription': {
                            'CodecSettings': {
                                'Codec': 'H_265',
                                'H265Settings': {
                                    'RateControlMode': 'QVBR',
                                    'MaxBitrate': 12000000,
                                    'QvbrSettings': {'QvbrQualityLevel': 9}
                                }
                            }
                        }
                    }]
                },
                {
                    'Name': 'SDR Output',
                    'OutputGroupSettings': {
                        'Type': 'HLS_GROUP_SETTINGS',
                        'HlsGroupSettings': {'Destination': f"{dest_s3_prefix}sdr/"}
                    },
                    'Outputs': [{
                        'VideoDescription': {
                            'CodecSettings': {
                                'Codec': 'H_264',
                                'H264Settings': {
                                    'RateControlMode': 'QVBR',
                                    'MaxBitrate': 8000000,
                                    'QvbrSettings': {'QvbrQualityLevel': 8}
                                }
                            }
                        }
                    }]
                }
            ]
        }
        
        response = self.client.create_job(
            Role=self.role_arn,
            Settings=settings
        )
        return response['Job']['Id']
    
    def create_drm_job(self, source_s3, dest_s3_prefix, speke_url, resource_id):
        """DRM(Widevine + FairPlay)ジョブを作成"""
        settings = {
            'Inputs': [{
                'FileInput': source_s3
            }],
            'OutputGroups': [{
                'Name': 'DASH DRM',
                'OutputGroupSettings': {
                    'Type': 'DASH_ISO_GROUP_SETTINGS',
                    'DashIsoGroupSettings': {
                        'Destination': dest_s3_prefix,
                        'Encryption': {
                            'SpekeKeyProvider': {
                                'Url': speke_url,
                                'ResourceId': resource_id,
                                'SystemIds': [
                                    'edef8ba9-79d6-4ace-a3c8-27dcd51d21ed',
                                    '94ce86fb-07ff-4f43-adb8-93d2fa968ca2'
                                ]
                            }
                        }
                    }
                },
                'Outputs': [{
                    'VideoDescription': {
                        'CodecSettings': {
                            'Codec': 'H_265',
                            'H265Settings': {
                                'RateControlMode': 'QVBR',
                                'MaxBitrate': 6000000,
                                'QvbrSettings': {'QvbrQualityLevel': 8}
                            }
                        }
                    }
                }]
            }]
        }
        
        response = self.client.create_job(
            Role=self.role_arn,
            Settings=settings
        )
        return response['Job']['Id']

# 使用例
if __name__ == '__main__':
    manager = MediaConvertJobManager(
        endpoint_url='https://abc123.mediaconvert.ap-northeast-1.amazonaws.com',
        role_arn='arn:aws:iam::123456789012:role/MediaConvertRole'
    )
    
    # HLS マルチビットレートジョブ
    job_id = manager.create_hls_job(
        source_s3='s3://my-source/video.mp4',
        dest_s3_prefix='s3://my-output/hls/'
    )
    print(f"HLS Job created: {job_id}")
    
    # AV1 4K ジョブ
    job_id = manager.create_av1_job(
        source_s3='s3://my-source/4k.mov',
        dest_s3_prefix='s3://my-output/av1/'
    )
    print(f"AV1 Job created: {job_id}")

CloudFormation による IaC (Infrastructure as Code) 構成

AWSTemplateFormatVersion: '2010-09-09'
Description: 'MediaConvert VOD Pipeline with Lambda Automation'

Parameters:
  SourceBucket:
    Type: String
    Description: S3 bucket for input videos
  OutputBucket:
    Type: String
    Description: S3 bucket for transcoded videos

Resources:
  # IAM Role for MediaConvert
  MediaConvertRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: mediaconvert.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: MediaConvertPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 's3:GetObject'
                Resource: !Sub 'arn:aws:s3:::${SourceBucket}/*'
              - Effect: Allow
                Action:
                  - 's3:PutObject'
                Resource: !Sub 'arn:aws:s3:::${OutputBucket}/*'

  # Lambda Role for automation
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      Policies:
        - PolicyName: MediaConvertAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'mediaconvert:CreateJob'
                  - 'mediaconvert:DescribeEndpoints'
                Resource: '*'

  # Lambda function to trigger MediaConvert
  TranscodingLambda:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.11
      Role: !GetAtt LambdaExecutionRole.Arn
      Handler: index.handler
      Environment:
        Variables:
          MEDIACONVERT_ROLE: !GetAtt MediaConvertRole.Arn
          OUTPUT_BUCKET: !Ref OutputBucket
      Code:
        ZipFile: |
          import boto3
          import json
          import os
          from urllib.parse import unquote_plus
          
          mediaconvert = boto3.client('mediaconvert')
          
          def handler(event, context):
              # Get MediaConvert endpoint
              endpoints = mediaconvert.describe_endpoints()
              endpoint = endpoints['Endpoints'][0]['Url']
              
              # Extract S3 bucket and key from event
              bucket = event['detail']['bucket']['name']
              key = unquote_plus(event['detail']['object']['key'])
              source_s3 = f"s3://{bucket}/{key}"
              output_bucket = os.environ['OUTPUT_BUCKET']
              
              # Create transcoding job
              settings = {
                  'Inputs': [{
                      'FileInput': source_s3,
                      'AudioSelectors': {'Audio Selector 1': {'DefaultSelection': 'DEFAULT'}},
                      'VideoSelector': {}
                  }],
                  'OutputGroups': [{
                      'Name': 'HLS Group',
                      'OutputGroupSettings': {
                          'Type': 'HLS_GROUP_SETTINGS',
                          'HlsGroupSettings': {
                              'Destination': f"s3://{output_bucket}/hls/",
                              'SegmentLength': 6
                          }
                      },
                      'Outputs': [
                          {
                              'NameModifier': '_360p',
                              'VideoDescription': {
                                  'CodecSettings': {
                                      'Codec': 'H_264',
                                      'H264Settings': {
                                          'RateControlMode': 'QVBR',
                                          'MaxBitrate': 800000,
                                          'QvbrSettings': {'QvbrQualityLevel': 7}
                                      }
                                  },
                                  'Width': 640,
                                  'Height': 360
                              }
                          },
                          {
                              'NameModifier': '_720p',
                              'VideoDescription': {
                                  'CodecSettings': {
                                      'Codec': 'H_264',
                                      'H264Settings': {
                                          'RateControlMode': 'QVBR',
                                          'MaxBitrate': 3000000,
                                          'QvbrSettings': {'QvbrQualityLevel': 8}
                                      }
                                  },
                                  'Width': 1280,
                                  'Height': 720
                              }
                          }
                      ]
                  }]
              }
              
              client = boto3.client('mediaconvert', endpoint_url=endpoint)
              response = client.create_job(
                  Role=os.environ['MEDIACONVERT_ROLE'],
                  Settings=settings
              )
              
              return {
                  'statusCode': 200,
                  'body': json.dumps({'jobId': response['Job']['Id']})
              }

  # EventBridge Rule to trigger Lambda on S3 upload
  S3UploadEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventBusName: default
      EventPattern:
        source:
          - aws.s3
        detail-type:
          - Object Created
        detail:
          bucket:
            name:
              - !Ref SourceBucket
          object:
            key:
              - prefix: videos/
      State: ENABLED
      Targets:
        - Arn: !GetAtt TranscodingLambda.Arn
          RoleArn: !GetAtt EventBridgeRole.Arn

  # EventBridge Role
  EventBridgeRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: InvokeLambda
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'lambda:InvokeFunction'
                Resource: !GetAtt TranscodingLambda.Arn

  LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref TranscodingLambda
      Action: 'lambda:InvokeFunction'
      Principal: events.amazonaws.com
      SourceArn: !GetAtt S3UploadEventRule.Arn

Outputs:
  MediaConvertRoleArn:
    Value: !GetAtt MediaConvertRole.Arn
  LambdaFunctionArn:
    Value: !GetAtt TranscodingLambda.Arn

類似サービス比較表

項目 MediaConvert FFmpeg(自前) Elastic Transcoder Bitmovin Mux Video Cloudinary
提供形態 マネージドサービス OS ソフト AWS(レガシー) SaaS API SaaS SaaS
HEVC / AV1
HDR(Dolby Vision) 限定的
DRM(SPEKE) 限定的
マルチビットレート自動化 手動
DASH / CMAF 限定的 限定的
字幕・CC 限定的
運用管理 AWS 一体 複雑 AWS 内 外部 外部 外部
初期コスト 0 実装時間 0 無料枠 無料枠 無料枠
スケーラビリティ 無制限 制約あり 制約あり 無制限 無制限 無制限
AWS 統合 ネイティブ 手動 ネイティブ API API API

ベストプラクティス

✅ 推奨事項

  1. QVBR エンコーディングの活用

    • VBR ではなく QVBR を使用し、品質レベル(1-15)を指定
    • ファイルサイズ最小化と品質を自動バランス
  2. キューの適切な選択

    • 継続的・バッチ処理 → Reserved Queue(最大 75% コスト削減)
    • スパイク・臨時 → On-Demand Queue
  3. 複数品質の効率的出力

    • 1 ジョブで複数解像度・複数コーデック(H.264/H.265/AV1)を同時出力
    • OutputGroup を分岐させず、複数 Output で実行
  4. プリセット・テンプレートの再利用

    • 標準的な HLS/DASH 設定はシステムプリセット活用
    • カスタムプリセットを作成・共有で運用効率化
  5. 自動化パイプライン構築

    • S3 + EventBridge + Lambda で S3 アップロード自動トリガー
    • CloudFormation / CDK で IaC 管理
  6. HDR コンテンツの段階的対応

    • HDR10 → SDR フォールバック設定で互換性確保
    • Dolby Vision は高品質コンテンツに絞定

❌ 回避すべき事項

  1. 各品質ごとに個別ジョブ作成

    • 複数ジョブ = 複数課金・管理複雑化
    • 1 ジョブで複数 Output が推奨
  2. CBR(固定ビットレート)の使用

    • シーンの複雑さに対応できず品質ばらつき
    • VBR / QVBR 推奨
  3. On-Demand Queue で長期運用

    • 月 180 時間以上なら Reserved Queue で最大 75% 削減
    • コスト分析から Queue 選択を判定
  4. オンプレミス自前エンコーディング継続

    • 管理コスト・機材更新・スケーラビリティ制限
    • MediaConvert への移行を検討
  5. 不適切な解像度設定

    • 4K コンテンツを無理に 360p に圧縮
    • 各デバイス・ネットワーク対応を設計
  6. 字幕・音声の後処理

    • MediaConvert で一括処理 vs 別ツール処理の検討
    • 統合は効率化・エラー削減につながる

トラブルシューティング表

症状 原因 対策
ジョブが SUBMITTED のまま進まない Queue リソース不足 On-Demand Queue に変更 / Reserved Queue 容量増加
出力ファイルが破損・再生不可 コーデック設定不正 / 入力フォーマット非対応 ログ確認 / 入力ファイル検証 / プリセット修正
字幕が表示されない 字幕ファイル形式不正 / 埋め込み設定ミス CaptionSelectors / ContainerSettings 確認
HDR メタデータ失われ Hdr10Metadata 未設定 / マニフェスト生成ミス VideoSelector で HDR 設定確認
DRM 暗号化失敗 SPEKE エンドポイント接続不可 / 証明書期限切れ SPEKE URL 疎通確認 / 証明書更新
ファイルサイズ巨大 ビットレート設定高すぎ / QVBR 未使用 QVBR 導入 / ビットレート見直し
処理時間が長い AV1 高品質エンコード / 4K 処理 H.265 へ変更 / 品質レベル低下 / Reserved Queue 活用
複数言語音声が混在 AudioSelectors 指定ミス AudioDescriptions で言語別トラック明示
IAM 権限エラー Role に S3 権限なし MediaConvertRole に s3:GetObject/PutObject 追加
HLS プレイリスト形式エラー SegmentLength / PlaylistType 設定不正 HlsGroupSettings 再確認

2025-2026 最新動向

新機能・アップデート

  1. AV1 2-pass エンコーディング GA

    • 高品質 AV1 出力の品質向上(最大 30% ファイルサイズ削減)
    • 処理時間 1.5 倍だが品質向上の選択肢提供
  2. 10-bit AV1 完全対応

    • 4K HDR 用 10-bit AV1 出力(Professional Tier)
    • Rec. 2020 色空間で完全な HDR 品質保証
  3. 自動 QVBR レベル推奨

    • ML ベースで入力映像から最適 QVBR レベルを自動提案
    • 手動調整を削減・処理時間最適化
  4. Film Grain Synthesis for AV1

    • AV1 で動画圧縮時のノイズ感受性を改善
    • 低ビットレートでも高品質感維持
  5. WebVTT / IMSC アクセシビリティタグ

    • 聴覚障害対応字幕・音声解説の標準化
    • プレーヤーでの自動選択対応
  6. S3 Intelligent-Tiering 統合

    • 出力ファイルを自動的に S3 Intelligent-Tiering に格納
    • ストレージコスト自動最適化

学習リソース・参考文献

公式ドキュメント

AWS ブログ・記事

オープンソース・参考実装

ベンダー・競合サービス比較


実装チェックリスト

  • [ ] IAM Role(MediaConvert + Lambda + S3)を作成
  • [ ] S3 ソースバケット・出力バケットを準備
  • [ ] MediaConvert Endpoint URL を取得(region 別)
  • [ ] 標準プリセット or カスタムプリセットを選択
  • [ ] HLS / DASH / CMAF などフォーマット決定
  • [ ] QVBR 品質レベル(1-15)を設定
  • [ ] Queue(On-Demand or Reserved)を選択
  • [ ] EventBridge + Lambda 自動トリガー実装(オプション)
  • [ ] CloudFormation / CDK で IaC 化
  • [ ] テスト動画でジョブ実行・出力検証
  • [ ] CloudWatch ログ・メトリクス監視設定
  • [ ] コスト見積(Queue 料金・出力品質別)

まとめ

AWS Elemental MediaConvert は、ファイルベースの高機能・スケーラブルなビデオトランスコーディングサービス です。H.264・H.265・AV1、HDR10・Dolby Vision、DRM(SPEKE)、複数言語字幕、マルチビットレート HLS/DASH/CMAF 出力をサポートし、S3 + Lambda + EventBridge との統合で完全なサーバーレス VOD 配信パイプラインを実現します。Elastic Transcoder の後継として、より高度な放送グレード処理に対応する企業メディア配信の第一選択肢です。

活用シーン:動画配信プラットフォーム・OTT ストリーミング・放送社 VOD・企業ビデオ・e ラーニング・メディアアーカイブ

最大のメリット:運用管理なしに、高品質・大規模・低コストで動画トランスコーディングを自動実行

次ステップ:MediaPackage・CloudFront・MediaTailor と組み合わせて、エンドツーエンドのライブ・VOD 配信基盤を構築


最終更新:2026-04-26 バージョン:v2.0