aws mediaconvert

aws上で

- 動画の合成
- 動画の作成
- 音声の作成

ができるサービス

特にジョブの設定jsonではまったので残しておきます

おすすめはgptなどで生成するより、awsのコンソール画面でポチポチしながらジョブのjsonを作成してそれをプログラムに落とし込む方が全然早いことに気が付きました

# 必要なrole

```terraform
# IAMロールの作成
resource "aws_iam_role" "mediaconvert_role" {
  name = "MediaConvertRole"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "mediaconvert.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

# IAMポリシーのアタッチ
resource "aws_iam_role_policy" "mediaconvert_policy" {
  role = aws_iam_role.mediaconvert_role.name

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::vision-maker-dev/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "mediaconvert:CreateJob",
        "mediaconvert:GetJob",
        "mediaconvert:ListJobs"
      ],
      "Resource": "*"
    }
  ]
}
EOF
}

# MediaConvertのキュー
resource "aws_mediaconvert_queue" "default_queue" {
  name = "default"
}

output "mediaconvert_role_arn" {
  value = aws_iam_role.mediaconvert_role.arn
}
```

## mp3と画像の合成 ジョブキー

```json
{
  "Queue": "<キューのarn>",
  "UserMetadata": {},
  "Role": "<roleのarn>",
  "Settings": {
    "TimecodeConfig": {
      "Source": "ZEROBASED"
    },
    "OutputGroups": [
      {
        "Name": "File Group",
        "Outputs": [
          {
            "ContainerSettings": {
              "Container": "MP4",
              "Mp4Settings": {}
            },
            "VideoDescription": {
              "Width": 1920,
              "Height": 1080,
              "CodecSettings": {
                "Codec": "H_264",
                "H264Settings": {
                  "FramerateDenominator": 1,
                  "MaxBitrate": 5000000,
                  "FramerateControl": "SPECIFIED",
                  "RateControlMode": "QVBR",
                  "FramerateNumerator": 30,
                  "SceneChangeDetect": "TRANSITION_DETECTION"
                }
              }
            },
            "AudioDescriptions": [
              {
                "AudioSourceName": "Audio Selector 1",
                "CodecSettings": {
                  "Codec": "AAC",
                  "AacSettings": {
                    "Bitrate": 96000,
                    "CodingMode": "CODING_MODE_2_0",
                    "SampleRate": 48000
                  }
                }
              }
            ],
            "NameModifier": "test"
          }
        ],
        "OutputGroupSettings": {
          "Type": "FILE_GROUP_SETTINGS",
          "FileGroupSettings": {
            "Destination": "<出力s3フォルダ>",
            "DestinationSettings": {
              "S3Settings": {
                "StorageClass": "STANDARD"
              }
            }
          }
        }
      }
    ],
    "FollowSource": 1,
    "Inputs": [
      {
        "AudioSelectors": {
          "Audio Selector 1": {
            "DefaultSelection": "DEFAULT"
          }
        },
        "TimecodeSource": "ZEROBASED",
        "ImageInserter": {
          "InsertableImages": [
            {
              "ImageX": 0,
              "ImageY": 0,
              "Layer": 0,
              "ImageInserterInput": "<画像のキs3ー>",
              "Opacity": 50
            }
          ]
        },
        "FileInput": "<音声のs3キー>"
      }
    ]
  },
  "BillingTagsSource": "QUEUE",
  "AccelerationSettings": {
    "Mode": "DISABLED"
  },
  "StatusUpdateInterval": "SECONDS_10",
  "Priority": 0
}

```

## 動画の合成

```json
{
  "Queue": "<キューのarn>",
  "UserMetadata": {},
  "Role": "<roleのarn>",
  "Settings": {
    "TimecodeConfig": {
      "Source": "ZEROBASED"
    },
    "OutputGroups": [
      {
        "Name": "File Group",
        "Outputs": [
          {
            "ContainerSettings": {
              "Container": "MP4",
              "Mp4Settings": {}
            },
            "VideoDescription": {
              "CodecSettings": {
                "Codec": "H_264",
                "H264Settings": {
                  "MaxBitrate": 5000000,
                  "RateControlMode": "QVBR",
                  "SceneChangeDetect": "TRANSITION_DETECTION"
                }
              }
            },
            "AudioDescriptions": [
              {
                "CodecSettings": {
                  "Codec": "AAC",
                  "AacSettings": {
                    "Bitrate": 96000,
                    "CodingMode": "CODING_MODE_2_0",
                    "SampleRate": 48000
                  }
                }
              }
            ]
          }
        ],
        "OutputGroupSettings": {
          "Type": "FILE_GROUP_SETTINGS",
          "FileGroupSettings": {
            "Destination": "<出力s3フォルダ>",
            "DestinationSettings": {
              "S3Settings": {
                "StorageClass": "STANDARD"
              }
            }
          }
        }
      }
    ],
    "FollowSource": 1,
    "Inputs": [
      {
        "AudioSelectors": {
          "Audio Selector 1": {
            "DefaultSelection": "DEFAULT"
          }
        },
        "VideoSelector": {},
        "TimecodeSource": "ZEROBASED",
        "FileInput": "<動画のs3キー1>"
      },
      {
        "AudioSelectors": {
          "Audio Selector 1": {
            "DefaultSelection": "DEFAULT"
          }
        },
        "VideoSelector": {},
        "TimecodeSource": "ZEROBASED",
        "FileInput": "<動画のs3キー2>"
      }
    ]
  },
  "BillingTagsSource": "JOB",
  "AccelerationSettings": {
    "Mode": "DISABLED"
  },
  "StatusUpdateInterval": "SECONDS_60",
  "Priority": 0
}
```