1

I'm trying to write a Go code to create a job on MediaConvert that take as input an MP4 video, some MP3 used as different audio track and some SRT file used for captions.

My Go code generated this JSON that is sent to AWS:

{
    "clientRequestToken": "---",
    "role": "---",
    "settings": {
        "inputs": [{
            "audioSelectors": {
                "ENG": {
                    "defaultSelection": "NOT_DEFAULT",
                    "externalAudioFileInput": "s3://mybucket/test/sample1.mp3",
                    "languageCode": "ENG",
                    "offset": 0,
                    "programSelection": 1,
                    "selectorType": "TRACK"
                },
                "SPA": {
                    "defaultSelection": "NOT_DEFAULT",
                    "externalAudioFileInput": "s3://mybucket/test/sample3.mp3",
                    "languageCode": "SPA",
                    "offset": 0,
                    "programSelection": 1,
                    "selectorType": "TRACK"
                },
                "floor": {
                    "defaultSelection": "DEFAULT",
                    "offset": 0,
                    "programSelection": 1
                }
            },
            "captionSelectors": {
                "ENG": {
                    "languageCode": "ENG",
                    "sourceSettings": {
                        "fileSourceSettings": {
                            "sourceFile": "s3://mybucket/test/eng.srt"
                        },
                        "sourceType": "SRT"
                    }
                },
                "SPA": {
                    "languageCode": "SPA",
                    "sourceSettings": {
                        "fileSourceSettings": {
                            "sourceFile": "s3://mybucket/test/spa.srt"
                        },
                        "sourceType": "SRT"
                    }
                }
            },
            "deblockFilter": "DISABLED",
            "denoiseFilter": "DISABLED",
            "fileInput": "s3://mybucket/test/video.mp4",
            "filterEnable": "AUTO",
            "psiControl": "USE_PSI",
            "timecodeSource": "EMBEDDED",
            "videoSelector": {
                "alphaBehavior": "DISCARD",
                "colorSpace": "FOLLOW",
                "rotate": "DEGREE_0"
            }
        }],
        "outputGroups": [{
            "name": "Apple HLS",
            "outputGroupSettings": {
                "hlsGroupSettings": {
                    "captionLanguageSetting": "OMIT",
                    "clientCache": "ENABLED",
                    "codecSpecification": "RFC_4281",
                    "destination": "s3://mybucket/1/encoded",
                    "directoryStructure": "SINGLE_DIRECTORY",
                    "manifestCompression": "NONE",
                    "manifestDurationFormat": "INTEGER",
                    "minSegmentLength": 0,
                    "outputSelection": "MANIFESTS_AND_SEGMENTS",
                    "programDateTime": "EXCLUDE",
                    "programDateTimePeriod": 600,
                    "segmentControl": "SEGMENTED_FILES",
                    "segmentLength": 5,
                    "streamInfResolution": "INCLUDE",
                    "timedMetadataId3Period": 10
                },
                "type": "HLS_GROUP_SETTINGS"
            },
            "outputs": [{
                "audioDescriptions": [{
                        "audioSourceName": "floor",
                        "codecSettings": {
                            "aacSettings": {
                                "audioDescriptionBroadcasterMix": "NORMAL",
                                "bitrate": 96000,
                                "codecProfile": "LC",
                                "codingMode": "CODING_MODE_2_0",
                                "rateControlMode": "CBR",
                                "rawFormat": "NONE",
                                "sampleRate": 48000,
                                "specification": "MPEG4"
                            },
                            "codec": "AAC"
                        },
                        "languageCode": "FOLLOW_INPUT"
                    },
                    {
                        "audioSourceName": "ENG",
                        "codecSettings": {
                            "aacSettings": {
                                "audioDescriptionBroadcasterMix": "NORMAL",
                                "bitrate": 96000,
                                "codecProfile": "LC",
                                "codingMode": "CODING_MODE_2_0",
                                "rateControlMode": "CBR",
                                "rawFormat": "NONE",
                                "sampleRate": 48000,
                                "specification": "MPEG4"
                            },
                            "codec": "AAC"
                        },
                        "languageCode": "FOLLOW_INPUT"
                    },
                    {
                        "audioSourceName": "SPA",
                        "codecSettings": {
                            "aacSettings": {
                                "audioDescriptionBroadcasterMix": "NORMAL",
                                "bitrate": 96000,
                                "codecProfile": "LC",
                                "codingMode": "CODING_MODE_2_0",
                                "rateControlMode": "CBR",
                                "rawFormat": "NONE",
                                "sampleRate": 48000,
                                "specification": "MPEG4"
                            },
                            "codec": "AAC"
                        },
                        "languageCode": "FOLLOW_INPUT"
                    }
                ],
                "captionDescriptions": [{
                        "captionSelectorName": "ENG",
                        "destinationSettings": {
                            "destinationType": "EMBEDDED"
                        }
                    },
                    {
                        "captionSelectorName": "SPA",
                        "destinationSettings": {
                            "destinationType": "EMBEDDED"
                        }
                    }
                ],
                "containerSettings": {
                    "container": "M3U8",
                    "m3u8Settings": {}
                },
                "extension": "m3u8",
                "nameModifier": "1",
                "outputSettings": {
                    "hlsSettings": {
                        "audioGroupId": "program_audio",
                        "audioOnlyContainer": "AUTOMATIC",
                        "iFrameOnlyManifest": "EXCLUDE"
                    }
                },
                "videoDescription": {
                    "afdSignaling": "NONE",
                    "antiAlias": "ENABLED",
                    "codecSettings": {
                        "codec": "H_264",
                        "h264Settings": {
                            "adaptiveQuantization": "HIGH",
                            "codecLevel": "AUTO",
                            "codecProfile": "MAIN",
                            "dynamicSubGop": "STATIC",
                            "entropyEncoding": "CABAC",
                            "fieldEncoding": "PAFF",
                            "flickerAdaptiveQuantization": "DISABLED",
                            "framerateControl": "INITIALIZE_FROM_SOURCE",
                            "framerateConversionAlgorithm": "DUPLICATE_DROP",
                            "gopBReference": "DISABLED",
                            "gopClosedCadence": 0,
                            "gopSize": 90,
                            "gopSizeUnits": "FRAMES",
                            "interlaceMode": "PROGRESSIVE",
                            "maxBitrate": 5000000,
                            "minIInterval": 0,
                            "numberBFramesBetweenReferenceFrames": 2,
                            "numberReferenceFrames": 3,
                            "parControl": "INITIALIZE_FROM_SOURCE",
                            "qualityTuningLevel": "SINGLE_PASS",
                            "rateControlMode": "QVBR",
                            "repeatPps": "DISABLED",
                            "sceneChangeDetect": "ENABLED",
                            "slices": 1,
                            "slowPal": "DISABLED",
                            "softness": 0,
                            "spatialAdaptiveQuantization": "ENABLED",
                            "syntax": "DEFAULT",
                            "telecine": "NONE",
                            "temporalAdaptiveQuantization": "ENABLED",
                            "unregisteredSeiTimecode": "DISABLED"
                        }
                    },
                    "colorMetadata": "INSERT",
                    "dropFrameTimecode": "ENABLED",
                    "respondToAfd": "NONE",
                    "scalingBehavior": "DEFAULT",
                    "sharpness": 50,
                    "timecodeInsertion": "DISABLED"
                }
            }]
        }],
        "timecodeConfig": {
            "source": "ZEROBASED"
        }
    },
    "tags": {
        "Env": "dev"
    }
}

My problem is that rest api return error 400 bad request with message:

"message" : "The request could not be interpreted.","settingsValidationErrorsJsonBlob" : ""

Can someone gives me some advice to understand which could be the problem?

Thank you!

Jayyrus
  • 12,961
  • 41
  • 132
  • 214

1 Answers1

1

First, let me preface this by saying I am not familiar with Go, so I converted your JSON to pascal case and tested via the AWS CLI. I've converted my result back to camel case for you below.

On to my findings - it looks like you have some extraneous text at the beginning and end of the JSON. After removing the following bits from the top:

{
  "clientRequestToken": "---",
  "role": "---",
  "settings": 

and the following from the bottom

,
  "tags": {
    "Env": "dev"
  }
}

I received a different error response:

An error occurred (BadRequestException) when calling the CreateJob operation: The request could not be interpreted.

Looking deeper, I noticed you've also got some contradictory parameters in your input audio selectors. If I had to guess, and please correct me if I'm wrong, you're trying to set the language codes within the audio selector declarations. Here's one of the audio selectors, to highlight what I'm talking about:

                "ENG": {
                    "defaultSelection": "NOT_DEFAULT",
                    "externalAudioFileInput": "s3://mybucket/test/sample1.mp3",
                    "languageCode": "ENG",
                    "offset": 0,
                    "programSelection": 1,
                    "selectorType": "TRACK"
                }

"languageCode": "ENG" is telling MediaConvert that you want to extract the ENG track from the audio source file, however you've also declared "selectorType": "TRACK" which is telling MediaConvert that you want to extract audio by track number. Since you specified a track selector type, I assume you actually just want to pull off track 1 from the audio file and modified the audio selectors to look like this:

        "ENG": {
          "tracks": [
            1
          ],
          "defaultSelection": "NOT_DEFAULT",
          "selectorType": "TRACK",
          "externalAudioFileInput": "s3://mybucket/test/sample1.mp3"
        },

If I'm assuming wrong and you actually did intend to use the ENG track, then that stanza should look like this:

          "ENG": {
            "DefaultSelection": "NOT_DEFAULT",
            "SelectorType": "LANGUAGE_CODE",
            "ExternalAudioFileInput": "s3://mybucket/test/sample1.mp3",
            "LanguageCode": "ENG"
          },

Lastly, I moved the language codes to the outputs for the ENG and SPA audio tracks, which is where you would need to call them out. Also note that FOLLOW_INPUT is not valid for LanguageCode, so I've changed those keys to LanguageCodeControl. Here's the working JSON:

{
  "inputs": [
    {
      "audioSelectors": {
        "ENG": {
          "tracks": [
            1
          ],
          "defaultSelection": "NOT_DEFAULT",
          "selectorType": "TRACK",
          "externalAudioFileInput": "s3://mybucket/test/sample1.mp3"
        },
        "SPA": {
          "tracks": [
            1
          ],
          "defaultSelection": "NOT_DEFAULT",
          "selectorType": "TRACK",
          "externalAudioFileInput": "s3://mybucket/test/sample3.mp3"
        },
        "floor": {
          "defaultSelection": "DEFAULT"
        }
      },
      "captionSelectors": {
        "ENG": {
          "languageCode": "ENG",
          "sourceSettings": {
            "fileSourceSettings": {
              "sourceFile": "s3://mybucket/test/eng.srt"
            },
            "sourceType": "SRT"
          }
        },
        "SPA": {
          "languageCode": "SPA",
          "sourceSettings": {
            "fileSourceSettings": {
              "sourceFile": "s3://mybucket/test/spa.srt"
            },
            "sourceType": "SRT"
          }
        }
      },
      "deblockFilter": "DISABLED",
      "denoiseFilter": "DISABLED",
      "fileInput": "s3://mybucket/test/video.mp4",
      "filterEnable": "AUTO",
      "psiControl": "USE_PSI",
      "timecodeSource": "EMBEDDED",
      "videoSelector": {
        "alphaBehavior": "DISCARD",
        "colorSpace": "FOLLOW",
        "rotate": "DEGREE_0"
      }
    }
  ],
  "outputGroups": [
    {
      "name": "Apple HLS",
      "outputGroupSettings": {
        "hlsGroupSettings": {
          "captionLanguageSetting": "OMIT",
          "clientCache": "ENABLED",
          "codecSpecification": "RFC_4281",
          "destination": "s3://mybucket/1/encoded",
          "directoryStructure": "SINGLE_DIRECTORY",
          "manifestCompression": "NONE",
          "manifestDurationFormat": "INTEGER",
          "minSegmentLength": 0,
          "outputSelection": "MANIFESTS_AND_SEGMENTS",
          "programDateTime": "EXCLUDE",
          "programDateTimePeriod": 600,
          "segmentControl": "SEGMENTED_FILES",
          "segmentLength": 5,
          "streamInfResolution": "INCLUDE",
          "timedMetadataId3Period": 10
        },
        "type": "HLS_GROUP_SETTINGS"
      },
      "outputs": [
        {
          "audioDescriptions": [
            {
              "audioSourceName": "floor",
              "codecSettings": {
                "aacSettings": {
                  "audioDescriptionBroadcasterMix": "NORMAL",
                  "bitrate": 96000,
                  "codecProfile": "LC",
                  "codingMode": "CODING_MODE_2_0",
                  "rateControlMode": "CBR",
                  "rawFormat": "NONE",
                  "sampleRate": 48000,
                  "specification": "MPEG4"
                },
                "codec": "AAC"
              },
              "languageCodeControl": "FOLLOW_INPUT"
            },
            {
              "audioSourceName": "ENG",
              "codecSettings": {
                "aacSettings": {
                  "audioDescriptionBroadcasterMix": "NORMAL",
                  "bitrate": 96000,
                  "codecProfile": "LC",
                  "codingMode": "CODING_MODE_2_0",
                  "rateControlMode": "CBR",
                  "rawFormat": "NONE",
                  "sampleRate": 48000,
                  "specification": "MPEG4"
                },
                "codec": "AAC"
              },
              "languageCode": "ENG"
            },
            {
              "audioSourceName": "SPA",
              "codecSettings": {
                "aacSettings": {
                  "audioDescriptionBroadcasterMix": "NORMAL",
                  "bitrate": 96000,
                  "codecProfile": "LC",
                  "codingMode": "CODING_MODE_2_0",
                  "rateControlMode": "CBR",
                  "rawFormat": "NONE",
                  "sampleRate": 48000,
                  "specification": "MPEG4"
                },
                "codec": "AAC"
              },
              "languageCode": "SPA"
            }
          ],
          "captionDescriptions": [
            {
              "captionSelectorName": "ENG",
              "destinationSettings": {
                "destinationType": "EMBEDDED"
              }
            },
            {
              "captionSelectorName": "SPA",
              "destinationSettings": {
                "destinationType": "EMBEDDED"
              }
            }
          ],
          "containerSettings": {
            "container": "M3U8",
            "m3u8Settings": {}
          },
          "extension": "m3u8",
          "nameModifier": "1",
          "outputSettings": {
            "hlsSettings": {
              "audioGroupId": "program_audio",
              "audioOnlyContainer": "AUTOMATIC",
              "iFrameOnlyManifest": "EXCLUDE"
            }
          },
          "videoDescription": {
            "afdSignaling": "NONE",
            "antiAlias": "ENABLED",
            "codecSettings": {
              "codec": "H_264",
              "h264Settings": {
                "adaptiveQuantization": "HIGH",
                "codecLevel": "AUTO",
                "codecProfile": "MAIN",
                "dynamicSubGop": "STATIC",
                "entropyEncoding": "CABAC",
                "fieldEncoding": "PAFF",
                "flickerAdaptiveQuantization": "DISABLED",
                "framerateControl": "INITIALIZE_FROM_SOURCE",
                "framerateConversionAlgorithm": "DUPLICATE_DROP",
                "gopBReference": "DISABLED",
                "gopClosedCadence": 0,
                "gopSize": 90,
                "gopSizeUnits": "FRAMES",
                "interlaceMode": "PROGRESSIVE",
                "maxBitrate": 5000000,
                "minIInterval": 0,
                "numberBFramesBetweenReferenceFrames": 2,
                "numberReferenceFrames": 3,
                "parControl": "INITIALIZE_FROM_SOURCE",
                "qualityTuningLevel": "SINGLE_PASS",
                "rateControlMode": "QVBR",
                "repeatPps": "DISABLED",
                "sceneChangeDetect": "ENABLED",
                "slices": 1,
                "slowPal": "DISABLED",
                "softness": 0,
                "spatialAdaptiveQuantization": "ENABLED",
                "syntax": "DEFAULT",
                "telecine": "NONE",
                "temporalAdaptiveQuantization": "ENABLED",
                "unregisteredSeiTimecode": "DISABLED"
              }
            },
            "colorMetadata": "INSERT",
            "dropFrameTimecode": "ENABLED",
            "respondToAfd": "NONE",
            "scalingBehavior": "DEFAULT",
            "sharpness": 50,
            "timecodeInsertion": "DISABLED"
          }
        }
      ]
    }
  ],
  "timecodeConfig": {
    "source": "ZEROBASED"
  }
}
JeffH-AWS
  • 146
  • 4
  • 1
    Hello JeffH! Thank you very much! I converted your json in GO and seems to work really good! I will do some tests right now to understand If everything goes good. Thank you again! – Jayyrus Nov 23 '21 at 12:22
  • 1
    Using your code and SRT captions I receive that error: Media target [1] cannot convert non-EIA-608 to EIA-608 (invalid conversion from SRT to Embedded attempted. Could you please give me a suggestion? – Jayyrus Nov 23 '21 at 13:02
  • Hey Jayyrus I'm so glad that worked! And thanks for mentioning that validation error you got. I should have noticed that previously. In the user guide there's a section that outlines supported caption workflows, and it looks like SRT -> Embedded is not supported for HLS. You'll need to use WebVTT (or burn-in): https://docs.aws.amazon.com/mediaconvert/latest/ug/sidecar-captions-support-tables-by-container-type.html WebVTT is typical for HLS captions in my experience. – JeffH-AWS Nov 23 '21 at 17:24
  • Using WebVTT in output, I receive message that is not valid. Should I move captions to other output? So one output with video + audio and another with only captions? – Jayyrus Nov 24 '21 at 10:55
  • 1
    That's correct, WebVTT will need to be separate from the muxed audio/video rendition. You'll see ".vtt" files at the output, which the client player will request if the viewer selects the subtitle track. – JeffH-AWS Nov 24 '21 at 17:19