Migrate to the v1 API

This page outlines the changes from v1beta1 to v1. You can use this information to migrate existing job templates to the new v1 format.

Codec-specific settings

VideoStream settings are now specified per codec.

v1beta1

"elementaryStreams": [
  {
    "key": "video-stream0",
    "videoStream": {
      "codec": "h264",
      "heightPixels": 360,
      "widthPixels": 640,
      "bitrateBps": 550000,
      "frameRate": 30
    }
  }
]

v1

"elementaryStreams": [
  {
    "key": "video-stream0",
    "videoStream": {
      "h264": {
        "heightPixels": 360,
        "widthPixels": 640,
        "bitrateBps": 550000,
        "frameRate": 30
      }
    }
  }
]

Specify a h264, h265, or vp9 object to select the desired codec. For each codec, configure the codec-specific settings:

Stream mappings

Audio and text stream mappings now use a flat array rather than a 3-dimensional nested array.

Audio

For more information, see the AudioMapping field in the reference documentation.

v1beta1

"elementaryStreams": [
  {
    "key": "output_audio",
    "audioStream": {
      "codec": "aac",
      "bitrateBps": 64000,
      "channelCount": 2,
      "channelLayout": [
        "fl",
        "fr"
      ],
      "sampleRateHertz": 48000,
      "mapping": [
        {
          "key": "atom0",
          "channels": [
            {
              "inputs": [
                {
                  "key": "video_and_stereo_audio",
                  "track": 1,
                  "channel": 0,
                  "gainDb": 0
                }
              ]
            },
            {
              "inputs": [
                {
                  "key": "video_and_stereo_audio",
                  "track": 1,
                  "channel": 1,
                  "gainDb": 0
                }
              ]
            }
          ]
        }
      ]
    }
  }
]

v1

"elementaryStreams": [
  {
    "key": "output_audio",
    "audioStream": {
      "codec": "aac",
      "bitrateBps": 64000,
      "channelCount": 2,
      "channelLayout": [
        "fl",
        "fr"
      ],
      "sampleRateHertz": 48000,
      "mapping": [
        {
          "atomKey": "atom0",
          "inputKey": "video_and_stereo_audio",
          "inputTrack": 1,
          "inputChannel": 0,
          "outputChannel": 0,
          "gainDb": 0
        },
        {
          "atomKey": "atom0",
          "inputKey": "video_and_stereo_audio",
          "inputTrack": 1,
          "inputChannel": 1,
          "outputChannel": 1,
          "gainDb": 0
        }
      ]
    }
  }
]

Text

For more information, see the TextMapping field in the reference documentation.

v1beta1

"elementaryStreams":[
  {
    "key": "cea-stream0",
    "textStream": {
      "codec": "cea708",
      "languageCode": "en-US",
      "mapping": [
        {
          "key": "atom0",
          "inputs": [
            {
              "key": "caption_input0"
            }
          ]
        }
      ]
    }
  }
]

v1

"elementaryStreams":[
  {
    "key": "cea-stream0",
    "textStream": {
      "codec": "cea708",
      "languageCode": "en-US",
      "mapping": [
        {
          "atomKey": "atom0",
          "inputKey": "caption_input0",
          "inputTrack": 0
        }
      ]
    }
  }
]

Error reporting

The v1 API replaces the failureReason and failureDetails fields with an error field of type google.rpc.Status.

v1beta1

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
  ...
  "status": "FAILED",
  "failureReason": "Failed to download input(s) from GCS: {\n  \"error\": 
    {\n    \"code\": 403,\n    \"message\": \"service-226101368459@gcp-sa-transcoder.iam.gserviceaccount.com
    does not have storage.objects.get access to the Google Cloud Storage object.\",\n
    \"errors\": [\n      {\n        \"message\":\"service-226101368459@gcp-sa-transcoder.iam.gserviceaccount.com
    does not have storage.objects.get access to the Google Cloud Storage object.\",\n 
    \"domain\": \"global\",\n        \"reason\": \"forbidden\"\n      }\n   ]\n}\n}\n",
  "failureDetails": []
}

v1

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
  ...
  "state": "FAILED",
  "error": {
    "code":403,
    "message":"Permission denied for Google Cloud Storage.",
    "status":"PERMISSION_DENIED",
    "details":[
      {
        "@type":"type.googleapis.com/google.rpc.ErrorInfo",
        "reason":"GCSPermissionDenied",
        "domain":"transcoder.googleapis.com",
        "metadata":{
          "details":"my_sa@my_project.iam.gserviceaccount.com does not
            have storage.objects.get access to gs://example/input/video.mp4."
        }
      }
    ]
  }
}

Delete operations

The v1 delete operations fail if you specify the wrong resource name. This applies to deleting jobs and deleting job templates. Previously in v1beta1, the operation would succeed (although nothing would be deleted). To enable the previous behavior, set the allowMissing query parameter to true when sending a request to delete a job or job template.

v1beta1

curl -X DELETE -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) https://transcoder.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/jobs/NON_EXISTENT_JOB_ID
{}

v1

curl -X DELETE -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) https://transcoder.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/jobs/NON_EXISTENT_JOB_ID
{
  "error": {
    "code": 404,
    "message": "Resource 'projects/PROJECT_ID/locations/LOCATION/jobs/NON_EXISTENT_JOB_ID' was not found",
    "status": "NOT_FOUND",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ResourceInfo",
        "resourceName": "projects/PROJECT_ID/locations/LOCATION/jobs/NON_EXISTENT_JOB_ID"
      }
    ]
  }
}

Pub/Sub notifications

The v1 API replaces the failureReason and failureDetails fields with an error field of type google.rpc.Status.

v1beta1

{
  "job": {
    "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
    ...
    "status": "FAILED",
    "failureReason": "Failed to download input(s) from GCS: {\n  \"error\": 
      {\n    \"code\": 403,\n    \"message\": \"service-226101368459@gcp-sa-transcoder.iam.gserviceaccount.com
      does not have storage.objects.get access to the Google Cloud Storage object.\",\n
      \"errors\": [\n      {\n        \"message\":\"service-226101368459@gcp-sa-transcoder.iam.gserviceaccount.com
      does not have storage.objects.get access to the Google Cloud Storage object.\",\n 
      \"domain\": \"global\",\n        \"reason\": \"forbidden\"\n      }\n   ]\n}\n}\n",
    "failureDetails": []
  }
}

v1

{
  "job": {
    "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
    ...
    "state": "FAILED",
    "error": {
      "code":403,
      "message":"Permission denied for Google Cloud Storage.",
      "status":"PERMISSION_DENIED",
      "details":[
        {
          "@type":"type.googleapis.com/google.rpc.ErrorInfo",
          "reason":"GCSPermissionDenied",
          "domain":"transcoder.googleapis.com",
          "metadata":{
            "details":"my_sa@my_project.iam.gserviceaccount.com does not
              have storage.objects.get access to gs://example/input/video.mp4."
          }
        }
      ]
    }
  }
}