Create GCP Transcoder Jobs

The gcp:transcoder/job:Job resource, part of the Pulumi GCP provider, defines a Transcoder API job that converts video files into multiple formats, resolutions, and streaming protocols. This guide focuses on three capabilities: template-based job configuration, DRM encryption with multiple schemes, and adaptive streaming manifest generation.

Transcoder jobs read source video from GCS buckets and write outputs back to GCS. They may reference Secret Manager for encryption keys or Pub/Sub topics for status notifications. The examples are intentionally small. Combine them with your own storage buckets, encryption infrastructure, and delivery pipelines.

Transcode video to multiple resolutions using a template

Video platforms deliver content at multiple quality levels to accommodate different network conditions and device capabilities.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.storage.Bucket("default", {
    name: "transcoder-job",
    location: "US",
    forceDestroy: true,
    uniformBucketLevelAccess: true,
    publicAccessPrevention: "enforced",
});
const exampleMp4 = new gcp.storage.BucketObject("example_mp4", {
    name: "example.mp4",
    source: new pulumi.asset.FileAsset("./test-fixtures/example.mp4"),
    bucket: _default.name,
});
const defaultJobTemplate = new gcp.transcoder.JobTemplate("default", {
    jobTemplateId: "example-job-template",
    location: "us-central1",
    config: {
        inputs: [{
            key: "input0",
            uri: pulumi.interpolate`gs://${_default.name}/${exampleMp4.name}`,
        }],
        output: {
            uri: pulumi.interpolate`gs://${_default.name}/outputs/`,
        },
        editLists: [{
            key: "atom0",
            inputs: ["input0"],
            startTimeOffset: "0s",
        }],
        elementaryStreams: [
            {
                key: "video-stream0",
                videoStream: {
                    h264: {
                        widthPixels: 640,
                        heightPixels: 360,
                        bitrateBps: 550000,
                        frameRate: 60,
                        pixelFormat: "yuv420p",
                        rateControlMode: "vbr",
                        crfLevel: 21,
                        gopDuration: "3s",
                        vbvSizeBits: 550000,
                        vbvFullnessBits: 495000,
                        entropyCoder: "cabac",
                        profile: "high",
                        preset: "veryfast",
                    },
                },
            },
            {
                key: "video-stream1",
                videoStream: {
                    h264: {
                        widthPixels: 1280,
                        heightPixels: 720,
                        bitrateBps: 550000,
                        frameRate: 60,
                        pixelFormat: "yuv420p",
                        rateControlMode: "vbr",
                        crfLevel: 21,
                        gopDuration: "3s",
                        vbvSizeBits: 2500000,
                        vbvFullnessBits: 2250000,
                        entropyCoder: "cabac",
                        profile: "high",
                        preset: "veryfast",
                    },
                },
            },
            {
                key: "audio-stream0",
                audioStream: {
                    codec: "aac",
                    bitrateBps: 64000,
                    channelCount: 2,
                    channelLayouts: [
                        "fl",
                        "fr",
                    ],
                    sampleRateHertz: 48000,
                },
            },
        ],
        muxStreams: [
            {
                key: "sd",
                fileName: "sd.mp4",
                container: "mp4",
                elementaryStreams: [
                    "video-stream0",
                    "audio-stream0",
                ],
            },
            {
                key: "hd",
                fileName: "hd.mp4",
                container: "mp4",
                elementaryStreams: [
                    "video-stream1",
                    "audio-stream0",
                ],
            },
        ],
    },
    labels: {
        label: "key",
    },
});
const defaultJob = new gcp.transcoder.Job("default", {
    templateId: defaultJobTemplate.name,
    location: "us-central1",
    labels: {
        label: "key",
    },
});
import pulumi
import pulumi_gcp as gcp

default = gcp.storage.Bucket("default",
    name="transcoder-job",
    location="US",
    force_destroy=True,
    uniform_bucket_level_access=True,
    public_access_prevention="enforced")
example_mp4 = gcp.storage.BucketObject("example_mp4",
    name="example.mp4",
    source=pulumi.FileAsset("./test-fixtures/example.mp4"),
    bucket=default.name)
default_job_template = gcp.transcoder.JobTemplate("default",
    job_template_id="example-job-template",
    location="us-central1",
    config={
        "inputs": [{
            "key": "input0",
            "uri": pulumi.Output.all(
                defaultName=default.name,
                exampleMp4Name=example_mp4.name
).apply(lambda resolved_outputs: f"gs://{resolved_outputs['defaultName']}/{resolved_outputs['exampleMp4Name']}")
,
        }],
        "output": {
            "uri": default.name.apply(lambda name: f"gs://{name}/outputs/"),
        },
        "edit_lists": [{
            "key": "atom0",
            "inputs": ["input0"],
            "start_time_offset": "0s",
        }],
        "elementary_streams": [
            {
                "key": "video-stream0",
                "video_stream": {
                    "h264": {
                        "width_pixels": 640,
                        "height_pixels": 360,
                        "bitrate_bps": 550000,
                        "frame_rate": 60,
                        "pixel_format": "yuv420p",
                        "rate_control_mode": "vbr",
                        "crf_level": 21,
                        "gop_duration": "3s",
                        "vbv_size_bits": 550000,
                        "vbv_fullness_bits": 495000,
                        "entropy_coder": "cabac",
                        "profile": "high",
                        "preset": "veryfast",
                    },
                },
            },
            {
                "key": "video-stream1",
                "video_stream": {
                    "h264": {
                        "width_pixels": 1280,
                        "height_pixels": 720,
                        "bitrate_bps": 550000,
                        "frame_rate": 60,
                        "pixel_format": "yuv420p",
                        "rate_control_mode": "vbr",
                        "crf_level": 21,
                        "gop_duration": "3s",
                        "vbv_size_bits": 2500000,
                        "vbv_fullness_bits": 2250000,
                        "entropy_coder": "cabac",
                        "profile": "high",
                        "preset": "veryfast",
                    },
                },
            },
            {
                "key": "audio-stream0",
                "audio_stream": {
                    "codec": "aac",
                    "bitrate_bps": 64000,
                    "channel_count": 2,
                    "channel_layouts": [
                        "fl",
                        "fr",
                    ],
                    "sample_rate_hertz": 48000,
                },
            },
        ],
        "mux_streams": [
            {
                "key": "sd",
                "file_name": "sd.mp4",
                "container": "mp4",
                "elementary_streams": [
                    "video-stream0",
                    "audio-stream0",
                ],
            },
            {
                "key": "hd",
                "file_name": "hd.mp4",
                "container": "mp4",
                "elementary_streams": [
                    "video-stream1",
                    "audio-stream0",
                ],
            },
        ],
    },
    labels={
        "label": "key",
    })
default_job = gcp.transcoder.Job("default",
    template_id=default_job_template.name,
    location="us-central1",
    labels={
        "label": "key",
    })
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/storage"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/transcoder"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := storage.NewBucket(ctx, "default", &storage.BucketArgs{
			Name:                     pulumi.String("transcoder-job"),
			Location:                 pulumi.String("US"),
			ForceDestroy:             pulumi.Bool(true),
			UniformBucketLevelAccess: pulumi.Bool(true),
			PublicAccessPrevention:   pulumi.String("enforced"),
		})
		if err != nil {
			return err
		}
		exampleMp4, err := storage.NewBucketObject(ctx, "example_mp4", &storage.BucketObjectArgs{
			Name:   pulumi.String("example.mp4"),
			Source: pulumi.NewFileAsset("./test-fixtures/example.mp4"),
			Bucket: _default.Name,
		})
		if err != nil {
			return err
		}
		defaultJobTemplate, err := transcoder.NewJobTemplate(ctx, "default", &transcoder.JobTemplateArgs{
			JobTemplateId: pulumi.String("example-job-template"),
			Location:      pulumi.String("us-central1"),
			Config: &transcoder.JobTemplateConfigArgs{
				Inputs: transcoder.JobTemplateConfigInputTypeArray{
					&transcoder.JobTemplateConfigInputTypeArgs{
						Key: pulumi.String("input0"),
						Uri: pulumi.All(_default.Name, exampleMp4.Name).ApplyT(func(_args []interface{}) (string, error) {
							defaultName := _args[0].(string)
							exampleMp4Name := _args[1].(string)
							return fmt.Sprintf("gs://%v/%v", defaultName, exampleMp4Name), nil
						}).(pulumi.StringOutput),
					},
				},
				Output: &transcoder.JobTemplateConfigOutputTypeArgs{
					Uri: _default.Name.ApplyT(func(name string) (string, error) {
						return fmt.Sprintf("gs://%v/outputs/", name), nil
					}).(pulumi.StringOutput),
				},
				EditLists: transcoder.JobTemplateConfigEditListArray{
					&transcoder.JobTemplateConfigEditListArgs{
						Key: pulumi.String("atom0"),
						Inputs: pulumi.StringArray{
							pulumi.String("input0"),
						},
						StartTimeOffset: pulumi.String("0s"),
					},
				},
				ElementaryStreams: transcoder.JobTemplateConfigElementaryStreamArray{
					&transcoder.JobTemplateConfigElementaryStreamArgs{
						Key: pulumi.String("video-stream0"),
						VideoStream: &transcoder.JobTemplateConfigElementaryStreamVideoStreamArgs{
							H264: &transcoder.JobTemplateConfigElementaryStreamVideoStreamH264Args{
								WidthPixels:     pulumi.Int(640),
								HeightPixels:    pulumi.Int(360),
								BitrateBps:      pulumi.Int(550000),
								FrameRate:       pulumi.Int(60),
								PixelFormat:     pulumi.String("yuv420p"),
								RateControlMode: pulumi.String("vbr"),
								CrfLevel:        pulumi.Int(21),
								GopDuration:     pulumi.String("3s"),
								VbvSizeBits:     pulumi.Int(550000),
								VbvFullnessBits: pulumi.Int(495000),
								EntropyCoder:    pulumi.String("cabac"),
								Profile:         pulumi.String("high"),
								Preset:          pulumi.String("veryfast"),
							},
						},
					},
					&transcoder.JobTemplateConfigElementaryStreamArgs{
						Key: pulumi.String("video-stream1"),
						VideoStream: &transcoder.JobTemplateConfigElementaryStreamVideoStreamArgs{
							H264: &transcoder.JobTemplateConfigElementaryStreamVideoStreamH264Args{
								WidthPixels:     pulumi.Int(1280),
								HeightPixels:    pulumi.Int(720),
								BitrateBps:      pulumi.Int(550000),
								FrameRate:       pulumi.Int(60),
								PixelFormat:     pulumi.String("yuv420p"),
								RateControlMode: pulumi.String("vbr"),
								CrfLevel:        pulumi.Int(21),
								GopDuration:     pulumi.String("3s"),
								VbvSizeBits:     pulumi.Int(2500000),
								VbvFullnessBits: pulumi.Int(2250000),
								EntropyCoder:    pulumi.String("cabac"),
								Profile:         pulumi.String("high"),
								Preset:          pulumi.String("veryfast"),
							},
						},
					},
					&transcoder.JobTemplateConfigElementaryStreamArgs{
						Key: pulumi.String("audio-stream0"),
						AudioStream: &transcoder.JobTemplateConfigElementaryStreamAudioStreamArgs{
							Codec:        pulumi.String("aac"),
							BitrateBps:   pulumi.Int(64000),
							ChannelCount: pulumi.Int(2),
							ChannelLayouts: pulumi.StringArray{
								pulumi.String("fl"),
								pulumi.String("fr"),
							},
							SampleRateHertz: pulumi.Int(48000),
						},
					},
				},
				MuxStreams: transcoder.JobTemplateConfigMuxStreamArray{
					&transcoder.JobTemplateConfigMuxStreamArgs{
						Key:       pulumi.String("sd"),
						FileName:  pulumi.String("sd.mp4"),
						Container: pulumi.String("mp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream0"),
							pulumi.String("audio-stream0"),
						},
					},
					&transcoder.JobTemplateConfigMuxStreamArgs{
						Key:       pulumi.String("hd"),
						FileName:  pulumi.String("hd.mp4"),
						Container: pulumi.String("mp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream1"),
							pulumi.String("audio-stream0"),
						},
					},
				},
			},
			Labels: pulumi.StringMap{
				"label": pulumi.String("key"),
			},
		})
		if err != nil {
			return err
		}
		_, err = transcoder.NewJob(ctx, "default", &transcoder.JobArgs{
			TemplateId: defaultJobTemplate.Name,
			Location:   pulumi.String("us-central1"),
			Labels: pulumi.StringMap{
				"label": pulumi.String("key"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Storage.Bucket("default", new()
    {
        Name = "transcoder-job",
        Location = "US",
        ForceDestroy = true,
        UniformBucketLevelAccess = true,
        PublicAccessPrevention = "enforced",
    });

    var exampleMp4 = new Gcp.Storage.BucketObject("example_mp4", new()
    {
        Name = "example.mp4",
        Source = new FileAsset("./test-fixtures/example.mp4"),
        Bucket = @default.Name,
    });

    var defaultJobTemplate = new Gcp.Transcoder.JobTemplate("default", new()
    {
        JobTemplateId = "example-job-template",
        Location = "us-central1",
        Config = new Gcp.Transcoder.Inputs.JobTemplateConfigArgs
        {
            Inputs = new[]
            {
                new Gcp.Transcoder.Inputs.JobTemplateConfigInputArgs
                {
                    Key = "input0",
                    Uri = Output.Tuple(@default.Name, exampleMp4.Name).Apply(values =>
                    {
                        var defaultName = values.Item1;
                        var exampleMp4Name = values.Item2;
                        return $"gs://{defaultName}/{exampleMp4Name}";
                    }),
                },
            },
            Output = new Gcp.Transcoder.Inputs.JobTemplateConfigOutputArgs
            {
                Uri = @default.Name.Apply(name => $"gs://{name}/outputs/"),
            },
            EditLists = new[]
            {
                new Gcp.Transcoder.Inputs.JobTemplateConfigEditListArgs
                {
                    Key = "atom0",
                    Inputs = new[]
                    {
                        "input0",
                    },
                    StartTimeOffset = "0s",
                },
            },
            ElementaryStreams = new[]
            {
                new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamArgs
                {
                    Key = "video-stream0",
                    VideoStream = new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamVideoStreamArgs
                    {
                        H264 = new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamVideoStreamH264Args
                        {
                            WidthPixels = 640,
                            HeightPixels = 360,
                            BitrateBps = 550000,
                            FrameRate = 60,
                            PixelFormat = "yuv420p",
                            RateControlMode = "vbr",
                            CrfLevel = 21,
                            GopDuration = "3s",
                            VbvSizeBits = 550000,
                            VbvFullnessBits = 495000,
                            EntropyCoder = "cabac",
                            Profile = "high",
                            Preset = "veryfast",
                        },
                    },
                },
                new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamArgs
                {
                    Key = "video-stream1",
                    VideoStream = new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamVideoStreamArgs
                    {
                        H264 = new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamVideoStreamH264Args
                        {
                            WidthPixels = 1280,
                            HeightPixels = 720,
                            BitrateBps = 550000,
                            FrameRate = 60,
                            PixelFormat = "yuv420p",
                            RateControlMode = "vbr",
                            CrfLevel = 21,
                            GopDuration = "3s",
                            VbvSizeBits = 2500000,
                            VbvFullnessBits = 2250000,
                            EntropyCoder = "cabac",
                            Profile = "high",
                            Preset = "veryfast",
                        },
                    },
                },
                new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamArgs
                {
                    Key = "audio-stream0",
                    AudioStream = new Gcp.Transcoder.Inputs.JobTemplateConfigElementaryStreamAudioStreamArgs
                    {
                        Codec = "aac",
                        BitrateBps = 64000,
                        ChannelCount = 2,
                        ChannelLayouts = new[]
                        {
                            "fl",
                            "fr",
                        },
                        SampleRateHertz = 48000,
                    },
                },
            },
            MuxStreams = new[]
            {
                new Gcp.Transcoder.Inputs.JobTemplateConfigMuxStreamArgs
                {
                    Key = "sd",
                    FileName = "sd.mp4",
                    Container = "mp4",
                    ElementaryStreams = new[]
                    {
                        "video-stream0",
                        "audio-stream0",
                    },
                },
                new Gcp.Transcoder.Inputs.JobTemplateConfigMuxStreamArgs
                {
                    Key = "hd",
                    FileName = "hd.mp4",
                    Container = "mp4",
                    ElementaryStreams = new[]
                    {
                        "video-stream1",
                        "audio-stream0",
                    },
                },
            },
        },
        Labels = 
        {
            { "label", "key" },
        },
    });

    var defaultJob = new Gcp.Transcoder.Job("default", new()
    {
        TemplateId = defaultJobTemplate.Name,
        Location = "us-central1",
        Labels = 
        {
            { "label", "key" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.storage.BucketObject;
import com.pulumi.gcp.storage.BucketObjectArgs;
import com.pulumi.gcp.transcoder.JobTemplate;
import com.pulumi.gcp.transcoder.JobTemplateArgs;
import com.pulumi.gcp.transcoder.inputs.JobTemplateConfigArgs;
import com.pulumi.gcp.transcoder.inputs.JobTemplateConfigOutputArgs;
import com.pulumi.gcp.transcoder.Job;
import com.pulumi.gcp.transcoder.JobArgs;
import com.pulumi.asset.FileAsset;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new Bucket("default", BucketArgs.builder()
            .name("transcoder-job")
            .location("US")
            .forceDestroy(true)
            .uniformBucketLevelAccess(true)
            .publicAccessPrevention("enforced")
            .build());

        var exampleMp4 = new BucketObject("exampleMp4", BucketObjectArgs.builder()
            .name("example.mp4")
            .source(new FileAsset("./test-fixtures/example.mp4"))
            .bucket(default_.name())
            .build());

        var defaultJobTemplate = new JobTemplate("defaultJobTemplate", JobTemplateArgs.builder()
            .jobTemplateId("example-job-template")
            .location("us-central1")
            .config(JobTemplateConfigArgs.builder()
                .inputs(JobTemplateConfigInputArgs.builder()
                    .key("input0")
                    .uri(Output.tuple(default_.name(), exampleMp4.name()).applyValue(values -> {
                        var defaultName = values.t1;
                        var exampleMp4Name = values.t2;
                        return String.format("gs://%s/%s", defaultName,exampleMp4Name);
                    }))
                    .build())
                .output(JobTemplateConfigOutputArgs.builder()
                    .uri(default_.name().applyValue(_name -> String.format("gs://%s/outputs/", _name)))
                    .build())
                .editLists(JobTemplateConfigEditListArgs.builder()
                    .key("atom0")
                    .inputs("input0")
                    .startTimeOffset("0s")
                    .build())
                .elementaryStreams(                
                    JobTemplateConfigElementaryStreamArgs.builder()
                        .key("video-stream0")
                        .videoStream(JobTemplateConfigElementaryStreamVideoStreamArgs.builder()
                            .h264(JobTemplateConfigElementaryStreamVideoStreamH264Args.builder()
                                .widthPixels(640)
                                .heightPixels(360)
                                .bitrateBps(550000)
                                .frameRate(60)
                                .pixelFormat("yuv420p")
                                .rateControlMode("vbr")
                                .crfLevel(21)
                                .gopDuration("3s")
                                .vbvSizeBits(550000)
                                .vbvFullnessBits(495000)
                                .entropyCoder("cabac")
                                .profile("high")
                                .preset("veryfast")
                                .build())
                            .build())
                        .build(),
                    JobTemplateConfigElementaryStreamArgs.builder()
                        .key("video-stream1")
                        .videoStream(JobTemplateConfigElementaryStreamVideoStreamArgs.builder()
                            .h264(JobTemplateConfigElementaryStreamVideoStreamH264Args.builder()
                                .widthPixels(1280)
                                .heightPixels(720)
                                .bitrateBps(550000)
                                .frameRate(60)
                                .pixelFormat("yuv420p")
                                .rateControlMode("vbr")
                                .crfLevel(21)
                                .gopDuration("3s")
                                .vbvSizeBits(2500000)
                                .vbvFullnessBits(2250000)
                                .entropyCoder("cabac")
                                .profile("high")
                                .preset("veryfast")
                                .build())
                            .build())
                        .build(),
                    JobTemplateConfigElementaryStreamArgs.builder()
                        .key("audio-stream0")
                        .audioStream(JobTemplateConfigElementaryStreamAudioStreamArgs.builder()
                            .codec("aac")
                            .bitrateBps(64000)
                            .channelCount(2)
                            .channelLayouts(                            
                                "fl",
                                "fr")
                            .sampleRateHertz(48000)
                            .build())
                        .build())
                .muxStreams(                
                    JobTemplateConfigMuxStreamArgs.builder()
                        .key("sd")
                        .fileName("sd.mp4")
                        .container("mp4")
                        .elementaryStreams(                        
                            "video-stream0",
                            "audio-stream0")
                        .build(),
                    JobTemplateConfigMuxStreamArgs.builder()
                        .key("hd")
                        .fileName("hd.mp4")
                        .container("mp4")
                        .elementaryStreams(                        
                            "video-stream1",
                            "audio-stream0")
                        .build())
                .build())
            .labels(Map.of("label", "key"))
            .build());

        var defaultJob = new Job("defaultJob", JobArgs.builder()
            .templateId(defaultJobTemplate.name())
            .location("us-central1")
            .labels(Map.of("label", "key"))
            .build());

    }
}
resources:
  default:
    type: gcp:storage:Bucket
    properties:
      name: transcoder-job
      location: US
      forceDestroy: true
      uniformBucketLevelAccess: true
      publicAccessPrevention: enforced
  exampleMp4:
    type: gcp:storage:BucketObject
    name: example_mp4
    properties:
      name: example.mp4
      source:
        fn::FileAsset: ./test-fixtures/example.mp4
      bucket: ${default.name}
  defaultJob:
    type: gcp:transcoder:Job
    name: default
    properties:
      templateId: ${defaultJobTemplate.name}
      location: us-central1
      labels:
        label: key
  defaultJobTemplate:
    type: gcp:transcoder:JobTemplate
    name: default
    properties:
      jobTemplateId: example-job-template
      location: us-central1
      config:
        inputs:
          - key: input0
            uri: gs://${default.name}/${exampleMp4.name}
        output:
          uri: gs://${default.name}/outputs/
        editLists:
          - key: atom0
            inputs:
              - input0
            startTimeOffset: 0s
        elementaryStreams:
          - key: video-stream0
            videoStream:
              h264:
                widthPixels: 640
                heightPixels: 360
                bitrateBps: 550000
                frameRate: 60
                pixelFormat: yuv420p
                rateControlMode: vbr
                crfLevel: 21
                gopDuration: 3s
                vbvSizeBits: 550000
                vbvFullnessBits: 495000
                entropyCoder: cabac
                profile: high
                preset: veryfast
          - key: video-stream1
            videoStream:
              h264:
                widthPixels: 1280
                heightPixels: 720
                bitrateBps: 550000
                frameRate: 60
                pixelFormat: yuv420p
                rateControlMode: vbr
                crfLevel: 21
                gopDuration: 3s
                vbvSizeBits: 2.5e+06
                vbvFullnessBits: 2.25e+06
                entropyCoder: cabac
                profile: high
                preset: veryfast
          - key: audio-stream0
            audioStream:
              codec: aac
              bitrateBps: 64000
              channelCount: 2
              channelLayouts:
                - fl
                - fr
              sampleRateHertz: 48000
        muxStreams:
          - key: sd
            fileName: sd.mp4
            container: mp4
            elementaryStreams:
              - video-stream0
              - audio-stream0
          - key: hd
            fileName: hd.mp4
            container: mp4
            elementaryStreams:
              - video-stream1
              - audio-stream0
      labels:
        label: key

The templateId property references a JobTemplate that defines the encoding configuration. The template specifies elementaryStreams (individual video and audio encodings at different bitrates) and muxStreams (how those streams are packaged into output files). Here, the job produces SD (640x360) and HD (1280x720) MP4 files from a single source video. The location property determines which regional endpoint processes the job.

Encrypt outputs with DRM for content protection

Content distributors protecting premium video apply encryption to prevent unauthorized playback. The Transcoder API supports Widevine for DASH and AES-128 for HLS.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.storage.Bucket("default", {
    name: "transcoder-job",
    location: "US",
    forceDestroy: true,
    uniformBucketLevelAccess: true,
    publicAccessPrevention: "enforced",
});
const exampleMp4 = new gcp.storage.BucketObject("example_mp4", {
    name: "example.mp4",
    source: new pulumi.asset.FileAsset("./test-fixtures/example.mp4"),
    bucket: _default.name,
});
const encryptionKey = new gcp.secretmanager.Secret("encryption_key", {
    secretId: "transcoder-encryption-key",
    replication: {
        auto: {},
    },
});
const encryptionKeySecretVersion = new gcp.secretmanager.SecretVersion("encryption_key", {
    secret: encryptionKey.name,
    secretData: "4A67F2C1B8E93A4F6D3E7890A1BC23DF",
});
const project = gcp.organizations.getProject({});
// this is required to allow the transcoder service identity to access the secret
const transcoder = new gcp.projects.ServiceIdentity("transcoder", {
    project: project.then(project => project.projectId),
    service: "transcoder.googleapis.com",
});
const transcoderEncryptionKeyAccessor = new gcp.secretmanager.SecretIamMember("transcoder_encryption_key_accessor", {
    secretId: encryptionKey.secretId,
    project: encryptionKey.project,
    role: "roles/secretmanager.secretAccessor",
    member: pulumi.interpolate`serviceAccount:${transcoder.email}`,
});
const defaultJob = new gcp.transcoder.Job("default", {
    location: "us-central1",
    config: {
        inputs: [{
            key: "input0",
            uri: pulumi.interpolate`gs://${_default.name}/${exampleMp4.name}`,
        }],
        elementaryStreams: [
            {
                key: "es_video",
                videoStream: {
                    h264: {
                        profile: "main",
                        heightPixels: 600,
                        widthPixels: 800,
                        bitrateBps: 1000000,
                        frameRate: 60,
                    },
                },
            },
            {
                key: "es_audio",
                audioStream: {
                    codec: "aac",
                    channelCount: 2,
                    bitrateBps: 160000,
                },
            },
        ],
        encryptions: [
            {
                id: "aes-128",
                secretManagerKeySource: {
                    secretVersion: encryptionKeySecretVersion.name,
                },
                drmSystems: {
                    clearkey: {},
                },
                aes128: {},
            },
            {
                id: "cenc",
                secretManagerKeySource: {
                    secretVersion: encryptionKeySecretVersion.name,
                },
                drmSystems: {
                    widevine: {},
                },
                mpegCenc: {
                    scheme: "cenc",
                },
            },
            {
                id: "cbcs",
                secretManagerKeySource: {
                    secretVersion: encryptionKeySecretVersion.name,
                },
                drmSystems: {
                    widevine: {},
                },
                mpegCenc: {
                    scheme: "cbcs",
                },
            },
        ],
        muxStreams: [
            {
                key: "ts_aes128",
                container: "ts",
                elementaryStreams: [
                    "es_video",
                    "es_audio",
                ],
                segmentSettings: {
                    segmentDuration: "6s",
                },
                encryptionId: "aes-128",
            },
            {
                key: "fmp4_cenc_video",
                container: "fmp4",
                elementaryStreams: ["es_video"],
                segmentSettings: {
                    segmentDuration: "6s",
                },
                encryptionId: "cenc",
            },
            {
                key: "fmp4_cenc_audio",
                container: "fmp4",
                elementaryStreams: ["es_audio"],
                segmentSettings: {
                    segmentDuration: "6s",
                },
                encryptionId: "cenc",
            },
            {
                key: "fmp4_cbcs_video",
                container: "fmp4",
                elementaryStreams: ["es_video"],
                segmentSettings: {
                    segmentDuration: "6s",
                },
                encryptionId: "cbcs",
            },
            {
                key: "fmp4_cbcs_audio",
                container: "fmp4",
                elementaryStreams: ["es_audio"],
                segmentSettings: {
                    segmentDuration: "6s",
                },
                encryptionId: "cbcs",
            },
        ],
        manifests: [
            {
                fileName: "manifest_aes128.m3u8",
                type: "HLS",
                muxStreams: ["ts_aes128"],
            },
            {
                fileName: "manifest_cenc.mpd",
                type: "DASH",
                muxStreams: [
                    "fmp4_cenc_video",
                    "fmp4_cenc_audio",
                ],
            },
            {
                fileName: "manifest_cbcs.mpd",
                type: "DASH",
                muxStreams: [
                    "fmp4_cbcs_video",
                    "fmp4_cbcs_audio",
                ],
            },
        ],
        output: {
            uri: pulumi.interpolate`gs://${_default.name}/outputs/`,
        },
    },
    labels: {
        label: "key",
    },
});
import pulumi
import pulumi_gcp as gcp

default = gcp.storage.Bucket("default",
    name="transcoder-job",
    location="US",
    force_destroy=True,
    uniform_bucket_level_access=True,
    public_access_prevention="enforced")
example_mp4 = gcp.storage.BucketObject("example_mp4",
    name="example.mp4",
    source=pulumi.FileAsset("./test-fixtures/example.mp4"),
    bucket=default.name)
encryption_key = gcp.secretmanager.Secret("encryption_key",
    secret_id="transcoder-encryption-key",
    replication={
        "auto": {},
    })
encryption_key_secret_version = gcp.secretmanager.SecretVersion("encryption_key",
    secret=encryption_key.name,
    secret_data="4A67F2C1B8E93A4F6D3E7890A1BC23DF")
project = gcp.organizations.get_project()
# this is required to allow the transcoder service identity to access the secret
transcoder = gcp.projects.ServiceIdentity("transcoder",
    project=project.project_id,
    service="transcoder.googleapis.com")
transcoder_encryption_key_accessor = gcp.secretmanager.SecretIamMember("transcoder_encryption_key_accessor",
    secret_id=encryption_key.secret_id,
    project=encryption_key.project,
    role="roles/secretmanager.secretAccessor",
    member=transcoder.email.apply(lambda email: f"serviceAccount:{email}"))
default_job = gcp.transcoder.Job("default",
    location="us-central1",
    config={
        "inputs": [{
            "key": "input0",
            "uri": pulumi.Output.all(
                defaultName=default.name,
                exampleMp4Name=example_mp4.name
).apply(lambda resolved_outputs: f"gs://{resolved_outputs['defaultName']}/{resolved_outputs['exampleMp4Name']}")
,
        }],
        "elementary_streams": [
            {
                "key": "es_video",
                "video_stream": {
                    "h264": {
                        "profile": "main",
                        "height_pixels": 600,
                        "width_pixels": 800,
                        "bitrate_bps": 1000000,
                        "frame_rate": 60,
                    },
                },
            },
            {
                "key": "es_audio",
                "audio_stream": {
                    "codec": "aac",
                    "channel_count": 2,
                    "bitrate_bps": 160000,
                },
            },
        ],
        "encryptions": [
            {
                "id": "aes-128",
                "secret_manager_key_source": {
                    "secret_version": encryption_key_secret_version.name,
                },
                "drm_systems": {
                    "clearkey": {},
                },
                "aes128": {},
            },
            {
                "id": "cenc",
                "secret_manager_key_source": {
                    "secret_version": encryption_key_secret_version.name,
                },
                "drm_systems": {
                    "widevine": {},
                },
                "mpeg_cenc": {
                    "scheme": "cenc",
                },
            },
            {
                "id": "cbcs",
                "secret_manager_key_source": {
                    "secret_version": encryption_key_secret_version.name,
                },
                "drm_systems": {
                    "widevine": {},
                },
                "mpeg_cenc": {
                    "scheme": "cbcs",
                },
            },
        ],
        "mux_streams": [
            {
                "key": "ts_aes128",
                "container": "ts",
                "elementary_streams": [
                    "es_video",
                    "es_audio",
                ],
                "segment_settings": {
                    "segment_duration": "6s",
                },
                "encryption_id": "aes-128",
            },
            {
                "key": "fmp4_cenc_video",
                "container": "fmp4",
                "elementary_streams": ["es_video"],
                "segment_settings": {
                    "segment_duration": "6s",
                },
                "encryption_id": "cenc",
            },
            {
                "key": "fmp4_cenc_audio",
                "container": "fmp4",
                "elementary_streams": ["es_audio"],
                "segment_settings": {
                    "segment_duration": "6s",
                },
                "encryption_id": "cenc",
            },
            {
                "key": "fmp4_cbcs_video",
                "container": "fmp4",
                "elementary_streams": ["es_video"],
                "segment_settings": {
                    "segment_duration": "6s",
                },
                "encryption_id": "cbcs",
            },
            {
                "key": "fmp4_cbcs_audio",
                "container": "fmp4",
                "elementary_streams": ["es_audio"],
                "segment_settings": {
                    "segment_duration": "6s",
                },
                "encryption_id": "cbcs",
            },
        ],
        "manifests": [
            {
                "file_name": "manifest_aes128.m3u8",
                "type": "HLS",
                "mux_streams": ["ts_aes128"],
            },
            {
                "file_name": "manifest_cenc.mpd",
                "type": "DASH",
                "mux_streams": [
                    "fmp4_cenc_video",
                    "fmp4_cenc_audio",
                ],
            },
            {
                "file_name": "manifest_cbcs.mpd",
                "type": "DASH",
                "mux_streams": [
                    "fmp4_cbcs_video",
                    "fmp4_cbcs_audio",
                ],
            },
        ],
        "output": {
            "uri": default.name.apply(lambda name: f"gs://{name}/outputs/"),
        },
    },
    labels={
        "label": "key",
    })
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/projects"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/storage"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/transcoder"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := storage.NewBucket(ctx, "default", &storage.BucketArgs{
			Name:                     pulumi.String("transcoder-job"),
			Location:                 pulumi.String("US"),
			ForceDestroy:             pulumi.Bool(true),
			UniformBucketLevelAccess: pulumi.Bool(true),
			PublicAccessPrevention:   pulumi.String("enforced"),
		})
		if err != nil {
			return err
		}
		exampleMp4, err := storage.NewBucketObject(ctx, "example_mp4", &storage.BucketObjectArgs{
			Name:   pulumi.String("example.mp4"),
			Source: pulumi.NewFileAsset("./test-fixtures/example.mp4"),
			Bucket: _default.Name,
		})
		if err != nil {
			return err
		}
		encryptionKey, err := secretmanager.NewSecret(ctx, "encryption_key", &secretmanager.SecretArgs{
			SecretId: pulumi.String("transcoder-encryption-key"),
			Replication: &secretmanager.SecretReplicationArgs{
				Auto: &secretmanager.SecretReplicationAutoArgs{},
			},
		})
		if err != nil {
			return err
		}
		encryptionKeySecretVersion, err := secretmanager.NewSecretVersion(ctx, "encryption_key", &secretmanager.SecretVersionArgs{
			Secret:     encryptionKey.Name,
			SecretData: pulumi.String("4A67F2C1B8E93A4F6D3E7890A1BC23DF"),
		})
		if err != nil {
			return err
		}
		project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{}, nil)
		if err != nil {
			return err
		}
		// this is required to allow the transcoder service identity to access the secret
		transcoder, err := projects.NewServiceIdentity(ctx, "transcoder", &projects.ServiceIdentityArgs{
			Project: pulumi.String(project.ProjectId),
			Service: pulumi.String("transcoder.googleapis.com"),
		})
		if err != nil {
			return err
		}
		_, err = secretmanager.NewSecretIamMember(ctx, "transcoder_encryption_key_accessor", &secretmanager.SecretIamMemberArgs{
			SecretId: encryptionKey.SecretId,
			Project:  encryptionKey.Project,
			Role:     pulumi.String("roles/secretmanager.secretAccessor"),
			Member: transcoder.Email.ApplyT(func(email string) (string, error) {
				return fmt.Sprintf("serviceAccount:%v", email), nil
			}).(pulumi.StringOutput),
		})
		if err != nil {
			return err
		}
		_, err = transcoder.NewJob(ctx, "default", &transcoder.JobArgs{
			Location: pulumi.String("us-central1"),
			Config: &transcoder.JobConfigArgs{
				Inputs: transcoder.JobConfigInputTypeArray{
					&transcoder.JobConfigInputTypeArgs{
						Key: pulumi.String("input0"),
						Uri: pulumi.All(_default.Name, exampleMp4.Name).ApplyT(func(_args []interface{}) (string, error) {
							defaultName := _args[0].(string)
							exampleMp4Name := _args[1].(string)
							return fmt.Sprintf("gs://%v/%v", defaultName, exampleMp4Name), nil
						}).(pulumi.StringOutput),
					},
				},
				ElementaryStreams: transcoder.JobConfigElementaryStreamArray{
					&transcoder.JobConfigElementaryStreamArgs{
						Key: pulumi.String("es_video"),
						VideoStream: &transcoder.JobConfigElementaryStreamVideoStreamArgs{
							H264: &transcoder.JobConfigElementaryStreamVideoStreamH264Args{
								Profile:      pulumi.String("main"),
								HeightPixels: pulumi.Int(600),
								WidthPixels:  pulumi.Int(800),
								BitrateBps:   pulumi.Int(1000000),
								FrameRate:    pulumi.Int(60),
							},
						},
					},
					&transcoder.JobConfigElementaryStreamArgs{
						Key: pulumi.String("es_audio"),
						AudioStream: &transcoder.JobConfigElementaryStreamAudioStreamArgs{
							Codec:        pulumi.String("aac"),
							ChannelCount: pulumi.Int(2),
							BitrateBps:   pulumi.Int(160000),
						},
					},
				},
				Encryptions: transcoder.JobConfigEncryptionArray{
					&transcoder.JobConfigEncryptionArgs{
						Id: pulumi.String("aes-128"),
						SecretManagerKeySource: &transcoder.JobConfigEncryptionSecretManagerKeySourceArgs{
							SecretVersion: encryptionKeySecretVersion.Name,
						},
						DrmSystems: &transcoder.JobConfigEncryptionDrmSystemsArgs{
							Clearkey: &transcoder.JobConfigEncryptionDrmSystemsClearkeyArgs{},
						},
						Aes128: &transcoder.JobConfigEncryptionAes128Args{},
					},
					&transcoder.JobConfigEncryptionArgs{
						Id: pulumi.String("cenc"),
						SecretManagerKeySource: &transcoder.JobConfigEncryptionSecretManagerKeySourceArgs{
							SecretVersion: encryptionKeySecretVersion.Name,
						},
						DrmSystems: &transcoder.JobConfigEncryptionDrmSystemsArgs{
							Widevine: &transcoder.JobConfigEncryptionDrmSystemsWidevineArgs{},
						},
						MpegCenc: &transcoder.JobConfigEncryptionMpegCencArgs{
							Scheme: pulumi.String("cenc"),
						},
					},
					&transcoder.JobConfigEncryptionArgs{
						Id: pulumi.String("cbcs"),
						SecretManagerKeySource: &transcoder.JobConfigEncryptionSecretManagerKeySourceArgs{
							SecretVersion: encryptionKeySecretVersion.Name,
						},
						DrmSystems: &transcoder.JobConfigEncryptionDrmSystemsArgs{
							Widevine: &transcoder.JobConfigEncryptionDrmSystemsWidevineArgs{},
						},
						MpegCenc: &transcoder.JobConfigEncryptionMpegCencArgs{
							Scheme: pulumi.String("cbcs"),
						},
					},
				},
				MuxStreams: transcoder.JobConfigMuxStreamArray{
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("ts_aes128"),
						Container: pulumi.String("ts"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("es_video"),
							pulumi.String("es_audio"),
						},
						SegmentSettings: &transcoder.JobConfigMuxStreamSegmentSettingsArgs{
							SegmentDuration: pulumi.String("6s"),
						},
						EncryptionId: pulumi.String("aes-128"),
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("fmp4_cenc_video"),
						Container: pulumi.String("fmp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("es_video"),
						},
						SegmentSettings: &transcoder.JobConfigMuxStreamSegmentSettingsArgs{
							SegmentDuration: pulumi.String("6s"),
						},
						EncryptionId: pulumi.String("cenc"),
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("fmp4_cenc_audio"),
						Container: pulumi.String("fmp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("es_audio"),
						},
						SegmentSettings: &transcoder.JobConfigMuxStreamSegmentSettingsArgs{
							SegmentDuration: pulumi.String("6s"),
						},
						EncryptionId: pulumi.String("cenc"),
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("fmp4_cbcs_video"),
						Container: pulumi.String("fmp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("es_video"),
						},
						SegmentSettings: &transcoder.JobConfigMuxStreamSegmentSettingsArgs{
							SegmentDuration: pulumi.String("6s"),
						},
						EncryptionId: pulumi.String("cbcs"),
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("fmp4_cbcs_audio"),
						Container: pulumi.String("fmp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("es_audio"),
						},
						SegmentSettings: &transcoder.JobConfigMuxStreamSegmentSettingsArgs{
							SegmentDuration: pulumi.String("6s"),
						},
						EncryptionId: pulumi.String("cbcs"),
					},
				},
				Manifests: transcoder.JobConfigManifestArray{
					&transcoder.JobConfigManifestArgs{
						FileName: pulumi.String("manifest_aes128.m3u8"),
						Type:     pulumi.String("HLS"),
						MuxStreams: pulumi.StringArray{
							pulumi.String("ts_aes128"),
						},
					},
					&transcoder.JobConfigManifestArgs{
						FileName: pulumi.String("manifest_cenc.mpd"),
						Type:     pulumi.String("DASH"),
						MuxStreams: pulumi.StringArray{
							pulumi.String("fmp4_cenc_video"),
							pulumi.String("fmp4_cenc_audio"),
						},
					},
					&transcoder.JobConfigManifestArgs{
						FileName: pulumi.String("manifest_cbcs.mpd"),
						Type:     pulumi.String("DASH"),
						MuxStreams: pulumi.StringArray{
							pulumi.String("fmp4_cbcs_video"),
							pulumi.String("fmp4_cbcs_audio"),
						},
					},
				},
				Output: &transcoder.JobConfigOutputTypeArgs{
					Uri: _default.Name.ApplyT(func(name string) (string, error) {
						return fmt.Sprintf("gs://%v/outputs/", name), nil
					}).(pulumi.StringOutput),
				},
			},
			Labels: pulumi.StringMap{
				"label": pulumi.String("key"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Storage.Bucket("default", new()
    {
        Name = "transcoder-job",
        Location = "US",
        ForceDestroy = true,
        UniformBucketLevelAccess = true,
        PublicAccessPrevention = "enforced",
    });

    var exampleMp4 = new Gcp.Storage.BucketObject("example_mp4", new()
    {
        Name = "example.mp4",
        Source = new FileAsset("./test-fixtures/example.mp4"),
        Bucket = @default.Name,
    });

    var encryptionKey = new Gcp.SecretManager.Secret("encryption_key", new()
    {
        SecretId = "transcoder-encryption-key",
        Replication = new Gcp.SecretManager.Inputs.SecretReplicationArgs
        {
            Auto = null,
        },
    });

    var encryptionKeySecretVersion = new Gcp.SecretManager.SecretVersion("encryption_key", new()
    {
        Secret = encryptionKey.Name,
        SecretData = "4A67F2C1B8E93A4F6D3E7890A1BC23DF",
    });

    var project = Gcp.Organizations.GetProject.Invoke();

    // this is required to allow the transcoder service identity to access the secret
    var transcoder = new Gcp.Projects.ServiceIdentity("transcoder", new()
    {
        Project = project.Apply(getProjectResult => getProjectResult.ProjectId),
        Service = "transcoder.googleapis.com",
    });

    var transcoderEncryptionKeyAccessor = new Gcp.SecretManager.SecretIamMember("transcoder_encryption_key_accessor", new()
    {
        SecretId = encryptionKey.SecretId,
        Project = encryptionKey.Project,
        Role = "roles/secretmanager.secretAccessor",
        Member = transcoder.Email.Apply(email => $"serviceAccount:{email}"),
    });

    var defaultJob = new Gcp.Transcoder.Job("default", new()
    {
        Location = "us-central1",
        Config = new Gcp.Transcoder.Inputs.JobConfigArgs
        {
            Inputs = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigInputArgs
                {
                    Key = "input0",
                    Uri = Output.Tuple(@default.Name, exampleMp4.Name).Apply(values =>
                    {
                        var defaultName = values.Item1;
                        var exampleMp4Name = values.Item2;
                        return $"gs://{defaultName}/{exampleMp4Name}";
                    }),
                },
            },
            ElementaryStreams = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigElementaryStreamArgs
                {
                    Key = "es_video",
                    VideoStream = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamVideoStreamArgs
                    {
                        H264 = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamVideoStreamH264Args
                        {
                            Profile = "main",
                            HeightPixels = 600,
                            WidthPixels = 800,
                            BitrateBps = 1000000,
                            FrameRate = 60,
                        },
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigElementaryStreamArgs
                {
                    Key = "es_audio",
                    AudioStream = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamAudioStreamArgs
                    {
                        Codec = "aac",
                        ChannelCount = 2,
                        BitrateBps = 160000,
                    },
                },
            },
            Encryptions = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigEncryptionArgs
                {
                    Id = "aes-128",
                    SecretManagerKeySource = new Gcp.Transcoder.Inputs.JobConfigEncryptionSecretManagerKeySourceArgs
                    {
                        SecretVersion = encryptionKeySecretVersion.Name,
                    },
                    DrmSystems = new Gcp.Transcoder.Inputs.JobConfigEncryptionDrmSystemsArgs
                    {
                        Clearkey = null,
                    },
                    Aes128 = null,
                },
                new Gcp.Transcoder.Inputs.JobConfigEncryptionArgs
                {
                    Id = "cenc",
                    SecretManagerKeySource = new Gcp.Transcoder.Inputs.JobConfigEncryptionSecretManagerKeySourceArgs
                    {
                        SecretVersion = encryptionKeySecretVersion.Name,
                    },
                    DrmSystems = new Gcp.Transcoder.Inputs.JobConfigEncryptionDrmSystemsArgs
                    {
                        Widevine = null,
                    },
                    MpegCenc = new Gcp.Transcoder.Inputs.JobConfigEncryptionMpegCencArgs
                    {
                        Scheme = "cenc",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigEncryptionArgs
                {
                    Id = "cbcs",
                    SecretManagerKeySource = new Gcp.Transcoder.Inputs.JobConfigEncryptionSecretManagerKeySourceArgs
                    {
                        SecretVersion = encryptionKeySecretVersion.Name,
                    },
                    DrmSystems = new Gcp.Transcoder.Inputs.JobConfigEncryptionDrmSystemsArgs
                    {
                        Widevine = null,
                    },
                    MpegCenc = new Gcp.Transcoder.Inputs.JobConfigEncryptionMpegCencArgs
                    {
                        Scheme = "cbcs",
                    },
                },
            },
            MuxStreams = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "ts_aes128",
                    Container = "ts",
                    ElementaryStreams = new[]
                    {
                        "es_video",
                        "es_audio",
                    },
                    SegmentSettings = new Gcp.Transcoder.Inputs.JobConfigMuxStreamSegmentSettingsArgs
                    {
                        SegmentDuration = "6s",
                    },
                    EncryptionId = "aes-128",
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "fmp4_cenc_video",
                    Container = "fmp4",
                    ElementaryStreams = new[]
                    {
                        "es_video",
                    },
                    SegmentSettings = new Gcp.Transcoder.Inputs.JobConfigMuxStreamSegmentSettingsArgs
                    {
                        SegmentDuration = "6s",
                    },
                    EncryptionId = "cenc",
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "fmp4_cenc_audio",
                    Container = "fmp4",
                    ElementaryStreams = new[]
                    {
                        "es_audio",
                    },
                    SegmentSettings = new Gcp.Transcoder.Inputs.JobConfigMuxStreamSegmentSettingsArgs
                    {
                        SegmentDuration = "6s",
                    },
                    EncryptionId = "cenc",
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "fmp4_cbcs_video",
                    Container = "fmp4",
                    ElementaryStreams = new[]
                    {
                        "es_video",
                    },
                    SegmentSettings = new Gcp.Transcoder.Inputs.JobConfigMuxStreamSegmentSettingsArgs
                    {
                        SegmentDuration = "6s",
                    },
                    EncryptionId = "cbcs",
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "fmp4_cbcs_audio",
                    Container = "fmp4",
                    ElementaryStreams = new[]
                    {
                        "es_audio",
                    },
                    SegmentSettings = new Gcp.Transcoder.Inputs.JobConfigMuxStreamSegmentSettingsArgs
                    {
                        SegmentDuration = "6s",
                    },
                    EncryptionId = "cbcs",
                },
            },
            Manifests = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigManifestArgs
                {
                    FileName = "manifest_aes128.m3u8",
                    Type = "HLS",
                    MuxStreams = new[]
                    {
                        "ts_aes128",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigManifestArgs
                {
                    FileName = "manifest_cenc.mpd",
                    Type = "DASH",
                    MuxStreams = new[]
                    {
                        "fmp4_cenc_video",
                        "fmp4_cenc_audio",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigManifestArgs
                {
                    FileName = "manifest_cbcs.mpd",
                    Type = "DASH",
                    MuxStreams = new[]
                    {
                        "fmp4_cbcs_video",
                        "fmp4_cbcs_audio",
                    },
                },
            },
            Output = new Gcp.Transcoder.Inputs.JobConfigOutputArgs
            {
                Uri = @default.Name.Apply(name => $"gs://{name}/outputs/"),
            },
        },
        Labels = 
        {
            { "label", "key" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.storage.BucketObject;
import com.pulumi.gcp.storage.BucketObjectArgs;
import com.pulumi.gcp.secretmanager.Secret;
import com.pulumi.gcp.secretmanager.SecretArgs;
import com.pulumi.gcp.secretmanager.inputs.SecretReplicationArgs;
import com.pulumi.gcp.secretmanager.inputs.SecretReplicationAutoArgs;
import com.pulumi.gcp.secretmanager.SecretVersion;
import com.pulumi.gcp.secretmanager.SecretVersionArgs;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetProjectArgs;
import com.pulumi.gcp.projects.ServiceIdentity;
import com.pulumi.gcp.projects.ServiceIdentityArgs;
import com.pulumi.gcp.secretmanager.SecretIamMember;
import com.pulumi.gcp.secretmanager.SecretIamMemberArgs;
import com.pulumi.gcp.transcoder.Job;
import com.pulumi.gcp.transcoder.JobArgs;
import com.pulumi.gcp.transcoder.inputs.JobConfigArgs;
import com.pulumi.gcp.transcoder.inputs.JobConfigOutputArgs;
import com.pulumi.asset.FileAsset;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new Bucket("default", BucketArgs.builder()
            .name("transcoder-job")
            .location("US")
            .forceDestroy(true)
            .uniformBucketLevelAccess(true)
            .publicAccessPrevention("enforced")
            .build());

        var exampleMp4 = new BucketObject("exampleMp4", BucketObjectArgs.builder()
            .name("example.mp4")
            .source(new FileAsset("./test-fixtures/example.mp4"))
            .bucket(default_.name())
            .build());

        var encryptionKey = new Secret("encryptionKey", SecretArgs.builder()
            .secretId("transcoder-encryption-key")
            .replication(SecretReplicationArgs.builder()
                .auto(SecretReplicationAutoArgs.builder()
                    .build())
                .build())
            .build());

        var encryptionKeySecretVersion = new SecretVersion("encryptionKeySecretVersion", SecretVersionArgs.builder()
            .secret(encryptionKey.name())
            .secretData("4A67F2C1B8E93A4F6D3E7890A1BC23DF")
            .build());

        final var project = OrganizationsFunctions.getProject(GetProjectArgs.builder()
            .build());

        // this is required to allow the transcoder service identity to access the secret
        var transcoder = new ServiceIdentity("transcoder", ServiceIdentityArgs.builder()
            .project(project.projectId())
            .service("transcoder.googleapis.com")
            .build());

        var transcoderEncryptionKeyAccessor = new SecretIamMember("transcoderEncryptionKeyAccessor", SecretIamMemberArgs.builder()
            .secretId(encryptionKey.secretId())
            .project(encryptionKey.project())
            .role("roles/secretmanager.secretAccessor")
            .member(transcoder.email().applyValue(_email -> String.format("serviceAccount:%s", _email)))
            .build());

        var defaultJob = new Job("defaultJob", JobArgs.builder()
            .location("us-central1")
            .config(JobConfigArgs.builder()
                .inputs(JobConfigInputArgs.builder()
                    .key("input0")
                    .uri(Output.tuple(default_.name(), exampleMp4.name()).applyValue(values -> {
                        var defaultName = values.t1;
                        var exampleMp4Name = values.t2;
                        return String.format("gs://%s/%s", defaultName,exampleMp4Name);
                    }))
                    .build())
                .elementaryStreams(                
                    JobConfigElementaryStreamArgs.builder()
                        .key("es_video")
                        .videoStream(JobConfigElementaryStreamVideoStreamArgs.builder()
                            .h264(JobConfigElementaryStreamVideoStreamH264Args.builder()
                                .profile("main")
                                .heightPixels(600)
                                .widthPixels(800)
                                .bitrateBps(1000000)
                                .frameRate(60)
                                .build())
                            .build())
                        .build(),
                    JobConfigElementaryStreamArgs.builder()
                        .key("es_audio")
                        .audioStream(JobConfigElementaryStreamAudioStreamArgs.builder()
                            .codec("aac")
                            .channelCount(2)
                            .bitrateBps(160000)
                            .build())
                        .build())
                .encryptions(                
                    JobConfigEncryptionArgs.builder()
                        .id("aes-128")
                        .secretManagerKeySource(JobConfigEncryptionSecretManagerKeySourceArgs.builder()
                            .secretVersion(encryptionKeySecretVersion.name())
                            .build())
                        .drmSystems(JobConfigEncryptionDrmSystemsArgs.builder()
                            .clearkey(JobConfigEncryptionDrmSystemsClearkeyArgs.builder()
                                .build())
                            .build())
                        .aes128(JobConfigEncryptionAes128Args.builder()
                            .build())
                        .build(),
                    JobConfigEncryptionArgs.builder()
                        .id("cenc")
                        .secretManagerKeySource(JobConfigEncryptionSecretManagerKeySourceArgs.builder()
                            .secretVersion(encryptionKeySecretVersion.name())
                            .build())
                        .drmSystems(JobConfigEncryptionDrmSystemsArgs.builder()
                            .widevine(JobConfigEncryptionDrmSystemsWidevineArgs.builder()
                                .build())
                            .build())
                        .mpegCenc(JobConfigEncryptionMpegCencArgs.builder()
                            .scheme("cenc")
                            .build())
                        .build(),
                    JobConfigEncryptionArgs.builder()
                        .id("cbcs")
                        .secretManagerKeySource(JobConfigEncryptionSecretManagerKeySourceArgs.builder()
                            .secretVersion(encryptionKeySecretVersion.name())
                            .build())
                        .drmSystems(JobConfigEncryptionDrmSystemsArgs.builder()
                            .widevine(JobConfigEncryptionDrmSystemsWidevineArgs.builder()
                                .build())
                            .build())
                        .mpegCenc(JobConfigEncryptionMpegCencArgs.builder()
                            .scheme("cbcs")
                            .build())
                        .build())
                .muxStreams(                
                    JobConfigMuxStreamArgs.builder()
                        .key("ts_aes128")
                        .container("ts")
                        .elementaryStreams(                        
                            "es_video",
                            "es_audio")
                        .segmentSettings(JobConfigMuxStreamSegmentSettingsArgs.builder()
                            .segmentDuration("6s")
                            .build())
                        .encryptionId("aes-128")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("fmp4_cenc_video")
                        .container("fmp4")
                        .elementaryStreams("es_video")
                        .segmentSettings(JobConfigMuxStreamSegmentSettingsArgs.builder()
                            .segmentDuration("6s")
                            .build())
                        .encryptionId("cenc")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("fmp4_cenc_audio")
                        .container("fmp4")
                        .elementaryStreams("es_audio")
                        .segmentSettings(JobConfigMuxStreamSegmentSettingsArgs.builder()
                            .segmentDuration("6s")
                            .build())
                        .encryptionId("cenc")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("fmp4_cbcs_video")
                        .container("fmp4")
                        .elementaryStreams("es_video")
                        .segmentSettings(JobConfigMuxStreamSegmentSettingsArgs.builder()
                            .segmentDuration("6s")
                            .build())
                        .encryptionId("cbcs")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("fmp4_cbcs_audio")
                        .container("fmp4")
                        .elementaryStreams("es_audio")
                        .segmentSettings(JobConfigMuxStreamSegmentSettingsArgs.builder()
                            .segmentDuration("6s")
                            .build())
                        .encryptionId("cbcs")
                        .build())
                .manifests(                
                    JobConfigManifestArgs.builder()
                        .fileName("manifest_aes128.m3u8")
                        .type("HLS")
                        .muxStreams("ts_aes128")
                        .build(),
                    JobConfigManifestArgs.builder()
                        .fileName("manifest_cenc.mpd")
                        .type("DASH")
                        .muxStreams(                        
                            "fmp4_cenc_video",
                            "fmp4_cenc_audio")
                        .build(),
                    JobConfigManifestArgs.builder()
                        .fileName("manifest_cbcs.mpd")
                        .type("DASH")
                        .muxStreams(                        
                            "fmp4_cbcs_video",
                            "fmp4_cbcs_audio")
                        .build())
                .output(JobConfigOutputArgs.builder()
                    .uri(default_.name().applyValue(_name -> String.format("gs://%s/outputs/", _name)))
                    .build())
                .build())
            .labels(Map.of("label", "key"))
            .build());

    }
}
resources:
  default:
    type: gcp:storage:Bucket
    properties:
      name: transcoder-job
      location: US
      forceDestroy: true
      uniformBucketLevelAccess: true
      publicAccessPrevention: enforced
  exampleMp4:
    type: gcp:storage:BucketObject
    name: example_mp4
    properties:
      name: example.mp4
      source:
        fn::FileAsset: ./test-fixtures/example.mp4
      bucket: ${default.name}
  encryptionKey:
    type: gcp:secretmanager:Secret
    name: encryption_key
    properties:
      secretId: transcoder-encryption-key
      replication:
        auto: {}
  encryptionKeySecretVersion:
    type: gcp:secretmanager:SecretVersion
    name: encryption_key
    properties:
      secret: ${encryptionKey.name}
      secretData: 4A67F2C1B8E93A4F6D3E7890A1BC23DF
  # this is required to allow the transcoder service identity to access the secret
  transcoder:
    type: gcp:projects:ServiceIdentity
    properties:
      project: ${project.projectId}
      service: transcoder.googleapis.com
  transcoderEncryptionKeyAccessor:
    type: gcp:secretmanager:SecretIamMember
    name: transcoder_encryption_key_accessor
    properties:
      secretId: ${encryptionKey.secretId}
      project: ${encryptionKey.project}
      role: roles/secretmanager.secretAccessor
      member: serviceAccount:${transcoder.email}
  defaultJob:
    type: gcp:transcoder:Job
    name: default
    properties:
      location: us-central1
      config:
        inputs:
          - key: input0
            uri: gs://${default.name}/${exampleMp4.name}
        elementaryStreams:
          - key: es_video
            videoStream:
              h264:
                profile: main
                heightPixels: 600
                widthPixels: 800
                bitrateBps: 1e+06
                frameRate: 60
          - key: es_audio
            audioStream:
              codec: aac
              channelCount: 2
              bitrateBps: 160000
        encryptions:
          - id: aes-128
            secretManagerKeySource:
              secretVersion: ${encryptionKeySecretVersion.name}
            drmSystems:
              clearkey: {}
            aes128: {}
          - id: cenc
            secretManagerKeySource:
              secretVersion: ${encryptionKeySecretVersion.name}
            drmSystems:
              widevine: {}
            mpegCenc:
              scheme: cenc
          - id: cbcs
            secretManagerKeySource:
              secretVersion: ${encryptionKeySecretVersion.name}
            drmSystems:
              widevine: {}
            mpegCenc:
              scheme: cbcs
        muxStreams:
          - key: ts_aes128
            container: ts
            elementaryStreams:
              - es_video
              - es_audio
            segmentSettings:
              segmentDuration: 6s
            encryptionId: aes-128
          - key: fmp4_cenc_video
            container: fmp4
            elementaryStreams:
              - es_video
            segmentSettings:
              segmentDuration: 6s
            encryptionId: cenc
          - key: fmp4_cenc_audio
            container: fmp4
            elementaryStreams:
              - es_audio
            segmentSettings:
              segmentDuration: 6s
            encryptionId: cenc
          - key: fmp4_cbcs_video
            container: fmp4
            elementaryStreams:
              - es_video
            segmentSettings:
              segmentDuration: 6s
            encryptionId: cbcs
          - key: fmp4_cbcs_audio
            container: fmp4
            elementaryStreams:
              - es_audio
            segmentSettings:
              segmentDuration: 6s
            encryptionId: cbcs
        manifests:
          - fileName: manifest_aes128.m3u8
            type: HLS
            muxStreams:
              - ts_aes128
          - fileName: manifest_cenc.mpd
            type: DASH
            muxStreams:
              - fmp4_cenc_video
              - fmp4_cenc_audio
          - fileName: manifest_cbcs.mpd
            type: DASH
            muxStreams:
              - fmp4_cbcs_video
              - fmp4_cbcs_audio
        output:
          uri: gs://${default.name}/outputs/
      labels:
        label: key
variables:
  project:
    fn::invoke:
      function: gcp:organizations:getProject
      arguments: {}

The encryptions array defines multiple DRM schemes applied to different output formats. Each encryption references a secretManagerKeySource pointing to a Secret Manager secret containing the encryption key. The drmSystems property specifies which DRM technologies to use (Widevine, Clearkey). The mpegCenc property configures MPEG Common Encryption with either “cenc” or “cbcs” schemes. Each muxStream references an encryptionId to apply the appropriate protection. The Transcoder service identity requires the secretAccessor role on the Secret Manager secret.

Generate adaptive streaming manifests for HLS and DASH

Adaptive bitrate streaming requires manifest files that tell players which quality levels are available and how to switch between them.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.storage.Bucket("default", {
    name: "transcoder-job",
    location: "US",
    forceDestroy: true,
    uniformBucketLevelAccess: true,
    publicAccessPrevention: "enforced",
});
const exampleMp4 = new gcp.storage.BucketObject("example_mp4", {
    name: "example.mp4",
    source: new pulumi.asset.FileAsset("./test-fixtures/example.mp4"),
    bucket: _default.name,
});
const defaultJob = new gcp.transcoder.Job("default", {
    location: "us-central1",
    config: {
        inputs: [{
            key: "input0",
            uri: pulumi.interpolate`gs://${_default.name}/${exampleMp4.name}`,
        }],
        editLists: [{
            key: "atom0",
            startTimeOffset: "0s",
            inputs: ["input0"],
        }],
        adBreaks: [{
            startTimeOffset: "3.500s",
        }],
        elementaryStreams: [
            {
                key: "video-stream0",
                videoStream: {
                    h264: {
                        widthPixels: 640,
                        heightPixels: 360,
                        bitrateBps: 550000,
                        frameRate: 60,
                        pixelFormat: "yuv420p",
                        rateControlMode: "vbr",
                        crfLevel: 21,
                        gopDuration: "3s",
                        vbvSizeBits: 550000,
                        vbvFullnessBits: 495000,
                        entropyCoder: "cabac",
                        profile: "high",
                        preset: "veryfast",
                    },
                },
            },
            {
                key: "video-stream1",
                videoStream: {
                    h264: {
                        widthPixels: 1280,
                        heightPixels: 720,
                        bitrateBps: 550000,
                        frameRate: 60,
                        pixelFormat: "yuv420p",
                        rateControlMode: "vbr",
                        crfLevel: 21,
                        gopDuration: "3s",
                        vbvSizeBits: 2500000,
                        vbvFullnessBits: 2250000,
                        entropyCoder: "cabac",
                        profile: "high",
                        preset: "veryfast",
                    },
                },
            },
            {
                key: "audio-stream0",
                audioStream: {
                    codec: "aac",
                    bitrateBps: 64000,
                    channelCount: 2,
                    channelLayouts: [
                        "fl",
                        "fr",
                    ],
                    sampleRateHertz: 48000,
                },
            },
        ],
        muxStreams: [
            {
                key: "sd",
                fileName: "sd.mp4",
                container: "mp4",
                elementaryStreams: [
                    "video-stream0",
                    "audio-stream0",
                ],
            },
            {
                key: "hd",
                fileName: "hd.mp4",
                container: "mp4",
                elementaryStreams: [
                    "video-stream1",
                    "audio-stream0",
                ],
            },
            {
                key: "media-sd",
                fileName: "media-sd.ts",
                container: "ts",
                elementaryStreams: [
                    "video-stream0",
                    "audio-stream0",
                ],
            },
            {
                key: "media-hd",
                fileName: "media-hd.ts",
                container: "ts",
                elementaryStreams: [
                    "video-stream1",
                    "audio-stream0",
                ],
            },
            {
                key: "video-only-sd",
                fileName: "video-only-sd.m4s",
                container: "fmp4",
                elementaryStreams: ["video-stream0"],
            },
            {
                key: "video-only-hd",
                fileName: "video-only-hd.m4s",
                container: "fmp4",
                elementaryStreams: ["video-stream1"],
            },
            {
                key: "audio-only",
                fileName: "audio-only.m4s",
                container: "fmp4",
                elementaryStreams: ["audio-stream0"],
            },
        ],
        manifests: [
            {
                fileName: "manifest.m3u8",
                type: "HLS",
                muxStreams: [
                    "media-sd",
                    "media-hd",
                ],
            },
            {
                fileName: "manifest.mpd",
                type: "DASH",
                muxStreams: [
                    "video-only-sd",
                    "video-only-hd",
                    "audio-only",
                ],
            },
        ],
        output: {
            uri: pulumi.interpolate`gs://${_default.name}/outputs/`,
        },
    },
    labels: {
        label: "key",
    },
});
import pulumi
import pulumi_gcp as gcp

default = gcp.storage.Bucket("default",
    name="transcoder-job",
    location="US",
    force_destroy=True,
    uniform_bucket_level_access=True,
    public_access_prevention="enforced")
example_mp4 = gcp.storage.BucketObject("example_mp4",
    name="example.mp4",
    source=pulumi.FileAsset("./test-fixtures/example.mp4"),
    bucket=default.name)
default_job = gcp.transcoder.Job("default",
    location="us-central1",
    config={
        "inputs": [{
            "key": "input0",
            "uri": pulumi.Output.all(
                defaultName=default.name,
                exampleMp4Name=example_mp4.name
).apply(lambda resolved_outputs: f"gs://{resolved_outputs['defaultName']}/{resolved_outputs['exampleMp4Name']}")
,
        }],
        "edit_lists": [{
            "key": "atom0",
            "start_time_offset": "0s",
            "inputs": ["input0"],
        }],
        "ad_breaks": [{
            "start_time_offset": "3.500s",
        }],
        "elementary_streams": [
            {
                "key": "video-stream0",
                "video_stream": {
                    "h264": {
                        "width_pixels": 640,
                        "height_pixels": 360,
                        "bitrate_bps": 550000,
                        "frame_rate": 60,
                        "pixel_format": "yuv420p",
                        "rate_control_mode": "vbr",
                        "crf_level": 21,
                        "gop_duration": "3s",
                        "vbv_size_bits": 550000,
                        "vbv_fullness_bits": 495000,
                        "entropy_coder": "cabac",
                        "profile": "high",
                        "preset": "veryfast",
                    },
                },
            },
            {
                "key": "video-stream1",
                "video_stream": {
                    "h264": {
                        "width_pixels": 1280,
                        "height_pixels": 720,
                        "bitrate_bps": 550000,
                        "frame_rate": 60,
                        "pixel_format": "yuv420p",
                        "rate_control_mode": "vbr",
                        "crf_level": 21,
                        "gop_duration": "3s",
                        "vbv_size_bits": 2500000,
                        "vbv_fullness_bits": 2250000,
                        "entropy_coder": "cabac",
                        "profile": "high",
                        "preset": "veryfast",
                    },
                },
            },
            {
                "key": "audio-stream0",
                "audio_stream": {
                    "codec": "aac",
                    "bitrate_bps": 64000,
                    "channel_count": 2,
                    "channel_layouts": [
                        "fl",
                        "fr",
                    ],
                    "sample_rate_hertz": 48000,
                },
            },
        ],
        "mux_streams": [
            {
                "key": "sd",
                "file_name": "sd.mp4",
                "container": "mp4",
                "elementary_streams": [
                    "video-stream0",
                    "audio-stream0",
                ],
            },
            {
                "key": "hd",
                "file_name": "hd.mp4",
                "container": "mp4",
                "elementary_streams": [
                    "video-stream1",
                    "audio-stream0",
                ],
            },
            {
                "key": "media-sd",
                "file_name": "media-sd.ts",
                "container": "ts",
                "elementary_streams": [
                    "video-stream0",
                    "audio-stream0",
                ],
            },
            {
                "key": "media-hd",
                "file_name": "media-hd.ts",
                "container": "ts",
                "elementary_streams": [
                    "video-stream1",
                    "audio-stream0",
                ],
            },
            {
                "key": "video-only-sd",
                "file_name": "video-only-sd.m4s",
                "container": "fmp4",
                "elementary_streams": ["video-stream0"],
            },
            {
                "key": "video-only-hd",
                "file_name": "video-only-hd.m4s",
                "container": "fmp4",
                "elementary_streams": ["video-stream1"],
            },
            {
                "key": "audio-only",
                "file_name": "audio-only.m4s",
                "container": "fmp4",
                "elementary_streams": ["audio-stream0"],
            },
        ],
        "manifests": [
            {
                "file_name": "manifest.m3u8",
                "type": "HLS",
                "mux_streams": [
                    "media-sd",
                    "media-hd",
                ],
            },
            {
                "file_name": "manifest.mpd",
                "type": "DASH",
                "mux_streams": [
                    "video-only-sd",
                    "video-only-hd",
                    "audio-only",
                ],
            },
        ],
        "output": {
            "uri": default.name.apply(lambda name: f"gs://{name}/outputs/"),
        },
    },
    labels={
        "label": "key",
    })
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/storage"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/transcoder"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := storage.NewBucket(ctx, "default", &storage.BucketArgs{
			Name:                     pulumi.String("transcoder-job"),
			Location:                 pulumi.String("US"),
			ForceDestroy:             pulumi.Bool(true),
			UniformBucketLevelAccess: pulumi.Bool(true),
			PublicAccessPrevention:   pulumi.String("enforced"),
		})
		if err != nil {
			return err
		}
		exampleMp4, err := storage.NewBucketObject(ctx, "example_mp4", &storage.BucketObjectArgs{
			Name:   pulumi.String("example.mp4"),
			Source: pulumi.NewFileAsset("./test-fixtures/example.mp4"),
			Bucket: _default.Name,
		})
		if err != nil {
			return err
		}
		_, err = transcoder.NewJob(ctx, "default", &transcoder.JobArgs{
			Location: pulumi.String("us-central1"),
			Config: &transcoder.JobConfigArgs{
				Inputs: transcoder.JobConfigInputTypeArray{
					&transcoder.JobConfigInputTypeArgs{
						Key: pulumi.String("input0"),
						Uri: pulumi.All(_default.Name, exampleMp4.Name).ApplyT(func(_args []interface{}) (string, error) {
							defaultName := _args[0].(string)
							exampleMp4Name := _args[1].(string)
							return fmt.Sprintf("gs://%v/%v", defaultName, exampleMp4Name), nil
						}).(pulumi.StringOutput),
					},
				},
				EditLists: transcoder.JobConfigEditListArray{
					&transcoder.JobConfigEditListArgs{
						Key:             pulumi.String("atom0"),
						StartTimeOffset: pulumi.String("0s"),
						Inputs: pulumi.StringArray{
							pulumi.String("input0"),
						},
					},
				},
				AdBreaks: transcoder.JobConfigAdBreakArray{
					&transcoder.JobConfigAdBreakArgs{
						StartTimeOffset: pulumi.String("3.500s"),
					},
				},
				ElementaryStreams: transcoder.JobConfigElementaryStreamArray{
					&transcoder.JobConfigElementaryStreamArgs{
						Key: pulumi.String("video-stream0"),
						VideoStream: &transcoder.JobConfigElementaryStreamVideoStreamArgs{
							H264: &transcoder.JobConfigElementaryStreamVideoStreamH264Args{
								WidthPixels:     pulumi.Int(640),
								HeightPixels:    pulumi.Int(360),
								BitrateBps:      pulumi.Int(550000),
								FrameRate:       pulumi.Int(60),
								PixelFormat:     pulumi.String("yuv420p"),
								RateControlMode: pulumi.String("vbr"),
								CrfLevel:        pulumi.Int(21),
								GopDuration:     pulumi.String("3s"),
								VbvSizeBits:     pulumi.Int(550000),
								VbvFullnessBits: pulumi.Int(495000),
								EntropyCoder:    pulumi.String("cabac"),
								Profile:         pulumi.String("high"),
								Preset:          pulumi.String("veryfast"),
							},
						},
					},
					&transcoder.JobConfigElementaryStreamArgs{
						Key: pulumi.String("video-stream1"),
						VideoStream: &transcoder.JobConfigElementaryStreamVideoStreamArgs{
							H264: &transcoder.JobConfigElementaryStreamVideoStreamH264Args{
								WidthPixels:     pulumi.Int(1280),
								HeightPixels:    pulumi.Int(720),
								BitrateBps:      pulumi.Int(550000),
								FrameRate:       pulumi.Int(60),
								PixelFormat:     pulumi.String("yuv420p"),
								RateControlMode: pulumi.String("vbr"),
								CrfLevel:        pulumi.Int(21),
								GopDuration:     pulumi.String("3s"),
								VbvSizeBits:     pulumi.Int(2500000),
								VbvFullnessBits: pulumi.Int(2250000),
								EntropyCoder:    pulumi.String("cabac"),
								Profile:         pulumi.String("high"),
								Preset:          pulumi.String("veryfast"),
							},
						},
					},
					&transcoder.JobConfigElementaryStreamArgs{
						Key: pulumi.String("audio-stream0"),
						AudioStream: &transcoder.JobConfigElementaryStreamAudioStreamArgs{
							Codec:        pulumi.String("aac"),
							BitrateBps:   pulumi.Int(64000),
							ChannelCount: pulumi.Int(2),
							ChannelLayouts: pulumi.StringArray{
								pulumi.String("fl"),
								pulumi.String("fr"),
							},
							SampleRateHertz: pulumi.Int(48000),
						},
					},
				},
				MuxStreams: transcoder.JobConfigMuxStreamArray{
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("sd"),
						FileName:  pulumi.String("sd.mp4"),
						Container: pulumi.String("mp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream0"),
							pulumi.String("audio-stream0"),
						},
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("hd"),
						FileName:  pulumi.String("hd.mp4"),
						Container: pulumi.String("mp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream1"),
							pulumi.String("audio-stream0"),
						},
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("media-sd"),
						FileName:  pulumi.String("media-sd.ts"),
						Container: pulumi.String("ts"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream0"),
							pulumi.String("audio-stream0"),
						},
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("media-hd"),
						FileName:  pulumi.String("media-hd.ts"),
						Container: pulumi.String("ts"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream1"),
							pulumi.String("audio-stream0"),
						},
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("video-only-sd"),
						FileName:  pulumi.String("video-only-sd.m4s"),
						Container: pulumi.String("fmp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream0"),
						},
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("video-only-hd"),
						FileName:  pulumi.String("video-only-hd.m4s"),
						Container: pulumi.String("fmp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("video-stream1"),
						},
					},
					&transcoder.JobConfigMuxStreamArgs{
						Key:       pulumi.String("audio-only"),
						FileName:  pulumi.String("audio-only.m4s"),
						Container: pulumi.String("fmp4"),
						ElementaryStreams: pulumi.StringArray{
							pulumi.String("audio-stream0"),
						},
					},
				},
				Manifests: transcoder.JobConfigManifestArray{
					&transcoder.JobConfigManifestArgs{
						FileName: pulumi.String("manifest.m3u8"),
						Type:     pulumi.String("HLS"),
						MuxStreams: pulumi.StringArray{
							pulumi.String("media-sd"),
							pulumi.String("media-hd"),
						},
					},
					&transcoder.JobConfigManifestArgs{
						FileName: pulumi.String("manifest.mpd"),
						Type:     pulumi.String("DASH"),
						MuxStreams: pulumi.StringArray{
							pulumi.String("video-only-sd"),
							pulumi.String("video-only-hd"),
							pulumi.String("audio-only"),
						},
					},
				},
				Output: &transcoder.JobConfigOutputTypeArgs{
					Uri: _default.Name.ApplyT(func(name string) (string, error) {
						return fmt.Sprintf("gs://%v/outputs/", name), nil
					}).(pulumi.StringOutput),
				},
			},
			Labels: pulumi.StringMap{
				"label": pulumi.String("key"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Storage.Bucket("default", new()
    {
        Name = "transcoder-job",
        Location = "US",
        ForceDestroy = true,
        UniformBucketLevelAccess = true,
        PublicAccessPrevention = "enforced",
    });

    var exampleMp4 = new Gcp.Storage.BucketObject("example_mp4", new()
    {
        Name = "example.mp4",
        Source = new FileAsset("./test-fixtures/example.mp4"),
        Bucket = @default.Name,
    });

    var defaultJob = new Gcp.Transcoder.Job("default", new()
    {
        Location = "us-central1",
        Config = new Gcp.Transcoder.Inputs.JobConfigArgs
        {
            Inputs = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigInputArgs
                {
                    Key = "input0",
                    Uri = Output.Tuple(@default.Name, exampleMp4.Name).Apply(values =>
                    {
                        var defaultName = values.Item1;
                        var exampleMp4Name = values.Item2;
                        return $"gs://{defaultName}/{exampleMp4Name}";
                    }),
                },
            },
            EditLists = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigEditListArgs
                {
                    Key = "atom0",
                    StartTimeOffset = "0s",
                    Inputs = new[]
                    {
                        "input0",
                    },
                },
            },
            AdBreaks = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigAdBreakArgs
                {
                    StartTimeOffset = "3.500s",
                },
            },
            ElementaryStreams = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigElementaryStreamArgs
                {
                    Key = "video-stream0",
                    VideoStream = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamVideoStreamArgs
                    {
                        H264 = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamVideoStreamH264Args
                        {
                            WidthPixels = 640,
                            HeightPixels = 360,
                            BitrateBps = 550000,
                            FrameRate = 60,
                            PixelFormat = "yuv420p",
                            RateControlMode = "vbr",
                            CrfLevel = 21,
                            GopDuration = "3s",
                            VbvSizeBits = 550000,
                            VbvFullnessBits = 495000,
                            EntropyCoder = "cabac",
                            Profile = "high",
                            Preset = "veryfast",
                        },
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigElementaryStreamArgs
                {
                    Key = "video-stream1",
                    VideoStream = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamVideoStreamArgs
                    {
                        H264 = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamVideoStreamH264Args
                        {
                            WidthPixels = 1280,
                            HeightPixels = 720,
                            BitrateBps = 550000,
                            FrameRate = 60,
                            PixelFormat = "yuv420p",
                            RateControlMode = "vbr",
                            CrfLevel = 21,
                            GopDuration = "3s",
                            VbvSizeBits = 2500000,
                            VbvFullnessBits = 2250000,
                            EntropyCoder = "cabac",
                            Profile = "high",
                            Preset = "veryfast",
                        },
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigElementaryStreamArgs
                {
                    Key = "audio-stream0",
                    AudioStream = new Gcp.Transcoder.Inputs.JobConfigElementaryStreamAudioStreamArgs
                    {
                        Codec = "aac",
                        BitrateBps = 64000,
                        ChannelCount = 2,
                        ChannelLayouts = new[]
                        {
                            "fl",
                            "fr",
                        },
                        SampleRateHertz = 48000,
                    },
                },
            },
            MuxStreams = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "sd",
                    FileName = "sd.mp4",
                    Container = "mp4",
                    ElementaryStreams = new[]
                    {
                        "video-stream0",
                        "audio-stream0",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "hd",
                    FileName = "hd.mp4",
                    Container = "mp4",
                    ElementaryStreams = new[]
                    {
                        "video-stream1",
                        "audio-stream0",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "media-sd",
                    FileName = "media-sd.ts",
                    Container = "ts",
                    ElementaryStreams = new[]
                    {
                        "video-stream0",
                        "audio-stream0",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "media-hd",
                    FileName = "media-hd.ts",
                    Container = "ts",
                    ElementaryStreams = new[]
                    {
                        "video-stream1",
                        "audio-stream0",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "video-only-sd",
                    FileName = "video-only-sd.m4s",
                    Container = "fmp4",
                    ElementaryStreams = new[]
                    {
                        "video-stream0",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "video-only-hd",
                    FileName = "video-only-hd.m4s",
                    Container = "fmp4",
                    ElementaryStreams = new[]
                    {
                        "video-stream1",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigMuxStreamArgs
                {
                    Key = "audio-only",
                    FileName = "audio-only.m4s",
                    Container = "fmp4",
                    ElementaryStreams = new[]
                    {
                        "audio-stream0",
                    },
                },
            },
            Manifests = new[]
            {
                new Gcp.Transcoder.Inputs.JobConfigManifestArgs
                {
                    FileName = "manifest.m3u8",
                    Type = "HLS",
                    MuxStreams = new[]
                    {
                        "media-sd",
                        "media-hd",
                    },
                },
                new Gcp.Transcoder.Inputs.JobConfigManifestArgs
                {
                    FileName = "manifest.mpd",
                    Type = "DASH",
                    MuxStreams = new[]
                    {
                        "video-only-sd",
                        "video-only-hd",
                        "audio-only",
                    },
                },
            },
            Output = new Gcp.Transcoder.Inputs.JobConfigOutputArgs
            {
                Uri = @default.Name.Apply(name => $"gs://{name}/outputs/"),
            },
        },
        Labels = 
        {
            { "label", "key" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.storage.BucketObject;
import com.pulumi.gcp.storage.BucketObjectArgs;
import com.pulumi.gcp.transcoder.Job;
import com.pulumi.gcp.transcoder.JobArgs;
import com.pulumi.gcp.transcoder.inputs.JobConfigArgs;
import com.pulumi.gcp.transcoder.inputs.JobConfigOutputArgs;
import com.pulumi.asset.FileAsset;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new Bucket("default", BucketArgs.builder()
            .name("transcoder-job")
            .location("US")
            .forceDestroy(true)
            .uniformBucketLevelAccess(true)
            .publicAccessPrevention("enforced")
            .build());

        var exampleMp4 = new BucketObject("exampleMp4", BucketObjectArgs.builder()
            .name("example.mp4")
            .source(new FileAsset("./test-fixtures/example.mp4"))
            .bucket(default_.name())
            .build());

        var defaultJob = new Job("defaultJob", JobArgs.builder()
            .location("us-central1")
            .config(JobConfigArgs.builder()
                .inputs(JobConfigInputArgs.builder()
                    .key("input0")
                    .uri(Output.tuple(default_.name(), exampleMp4.name()).applyValue(values -> {
                        var defaultName = values.t1;
                        var exampleMp4Name = values.t2;
                        return String.format("gs://%s/%s", defaultName,exampleMp4Name);
                    }))
                    .build())
                .editLists(JobConfigEditListArgs.builder()
                    .key("atom0")
                    .startTimeOffset("0s")
                    .inputs("input0")
                    .build())
                .adBreaks(JobConfigAdBreakArgs.builder()
                    .startTimeOffset("3.500s")
                    .build())
                .elementaryStreams(                
                    JobConfigElementaryStreamArgs.builder()
                        .key("video-stream0")
                        .videoStream(JobConfigElementaryStreamVideoStreamArgs.builder()
                            .h264(JobConfigElementaryStreamVideoStreamH264Args.builder()
                                .widthPixels(640)
                                .heightPixels(360)
                                .bitrateBps(550000)
                                .frameRate(60)
                                .pixelFormat("yuv420p")
                                .rateControlMode("vbr")
                                .crfLevel(21)
                                .gopDuration("3s")
                                .vbvSizeBits(550000)
                                .vbvFullnessBits(495000)
                                .entropyCoder("cabac")
                                .profile("high")
                                .preset("veryfast")
                                .build())
                            .build())
                        .build(),
                    JobConfigElementaryStreamArgs.builder()
                        .key("video-stream1")
                        .videoStream(JobConfigElementaryStreamVideoStreamArgs.builder()
                            .h264(JobConfigElementaryStreamVideoStreamH264Args.builder()
                                .widthPixels(1280)
                                .heightPixels(720)
                                .bitrateBps(550000)
                                .frameRate(60)
                                .pixelFormat("yuv420p")
                                .rateControlMode("vbr")
                                .crfLevel(21)
                                .gopDuration("3s")
                                .vbvSizeBits(2500000)
                                .vbvFullnessBits(2250000)
                                .entropyCoder("cabac")
                                .profile("high")
                                .preset("veryfast")
                                .build())
                            .build())
                        .build(),
                    JobConfigElementaryStreamArgs.builder()
                        .key("audio-stream0")
                        .audioStream(JobConfigElementaryStreamAudioStreamArgs.builder()
                            .codec("aac")
                            .bitrateBps(64000)
                            .channelCount(2)
                            .channelLayouts(                            
                                "fl",
                                "fr")
                            .sampleRateHertz(48000)
                            .build())
                        .build())
                .muxStreams(                
                    JobConfigMuxStreamArgs.builder()
                        .key("sd")
                        .fileName("sd.mp4")
                        .container("mp4")
                        .elementaryStreams(                        
                            "video-stream0",
                            "audio-stream0")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("hd")
                        .fileName("hd.mp4")
                        .container("mp4")
                        .elementaryStreams(                        
                            "video-stream1",
                            "audio-stream0")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("media-sd")
                        .fileName("media-sd.ts")
                        .container("ts")
                        .elementaryStreams(                        
                            "video-stream0",
                            "audio-stream0")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("media-hd")
                        .fileName("media-hd.ts")
                        .container("ts")
                        .elementaryStreams(                        
                            "video-stream1",
                            "audio-stream0")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("video-only-sd")
                        .fileName("video-only-sd.m4s")
                        .container("fmp4")
                        .elementaryStreams("video-stream0")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("video-only-hd")
                        .fileName("video-only-hd.m4s")
                        .container("fmp4")
                        .elementaryStreams("video-stream1")
                        .build(),
                    JobConfigMuxStreamArgs.builder()
                        .key("audio-only")
                        .fileName("audio-only.m4s")
                        .container("fmp4")
                        .elementaryStreams("audio-stream0")
                        .build())
                .manifests(                
                    JobConfigManifestArgs.builder()
                        .fileName("manifest.m3u8")
                        .type("HLS")
                        .muxStreams(                        
                            "media-sd",
                            "media-hd")
                        .build(),
                    JobConfigManifestArgs.builder()
                        .fileName("manifest.mpd")
                        .type("DASH")
                        .muxStreams(                        
                            "video-only-sd",
                            "video-only-hd",
                            "audio-only")
                        .build())
                .output(JobConfigOutputArgs.builder()
                    .uri(default_.name().applyValue(_name -> String.format("gs://%s/outputs/", _name)))
                    .build())
                .build())
            .labels(Map.of("label", "key"))
            .build());

    }
}
resources:
  default:
    type: gcp:storage:Bucket
    properties:
      name: transcoder-job
      location: US
      forceDestroy: true
      uniformBucketLevelAccess: true
      publicAccessPrevention: enforced
  exampleMp4:
    type: gcp:storage:BucketObject
    name: example_mp4
    properties:
      name: example.mp4
      source:
        fn::FileAsset: ./test-fixtures/example.mp4
      bucket: ${default.name}
  defaultJob:
    type: gcp:transcoder:Job
    name: default
    properties:
      location: us-central1
      config:
        inputs:
          - key: input0
            uri: gs://${default.name}/${exampleMp4.name}
        editLists:
          - key: atom0
            startTimeOffset: 0s
            inputs:
              - input0
        adBreaks:
          - startTimeOffset: 3.500s
        elementaryStreams:
          - key: video-stream0
            videoStream:
              h264:
                widthPixels: 640
                heightPixels: 360
                bitrateBps: 550000
                frameRate: 60
                pixelFormat: yuv420p
                rateControlMode: vbr
                crfLevel: 21
                gopDuration: 3s
                vbvSizeBits: 550000
                vbvFullnessBits: 495000
                entropyCoder: cabac
                profile: high
                preset: veryfast
          - key: video-stream1
            videoStream:
              h264:
                widthPixels: 1280
                heightPixels: 720
                bitrateBps: 550000
                frameRate: 60
                pixelFormat: yuv420p
                rateControlMode: vbr
                crfLevel: 21
                gopDuration: 3s
                vbvSizeBits: 2.5e+06
                vbvFullnessBits: 2.25e+06
                entropyCoder: cabac
                profile: high
                preset: veryfast
          - key: audio-stream0
            audioStream:
              codec: aac
              bitrateBps: 64000
              channelCount: 2
              channelLayouts:
                - fl
                - fr
              sampleRateHertz: 48000
        muxStreams:
          - key: sd
            fileName: sd.mp4
            container: mp4
            elementaryStreams:
              - video-stream0
              - audio-stream0
          - key: hd
            fileName: hd.mp4
            container: mp4
            elementaryStreams:
              - video-stream1
              - audio-stream0
          - key: media-sd
            fileName: media-sd.ts
            container: ts
            elementaryStreams:
              - video-stream0
              - audio-stream0
          - key: media-hd
            fileName: media-hd.ts
            container: ts
            elementaryStreams:
              - video-stream1
              - audio-stream0
          - key: video-only-sd
            fileName: video-only-sd.m4s
            container: fmp4
            elementaryStreams:
              - video-stream0
          - key: video-only-hd
            fileName: video-only-hd.m4s
            container: fmp4
            elementaryStreams:
              - video-stream1
          - key: audio-only
            fileName: audio-only.m4s
            container: fmp4
            elementaryStreams:
              - audio-stream0
        manifests:
          - fileName: manifest.m3u8
            type: HLS
            muxStreams:
              - media-sd
              - media-hd
          - fileName: manifest.mpd
            type: DASH
            muxStreams:
              - video-only-sd
              - video-only-hd
              - audio-only
        output:
          uri: gs://${default.name}/outputs/
      labels:
        label: key

The manifests array generates playlist files for adaptive streaming. Each manifest specifies a type (HLS or DASH), a fileName for the output, and which muxStreams to include. HLS manifests reference .ts container streams, while DASH manifests reference .m4s fragmented MP4 streams. The muxStreams must use appropriate containers: “ts” for HLS, “fmp4” for DASH. Players use these manifests to switch between quality levels based on network conditions.

Beyond these examples

These snippets focus on specific job-level features: template-based and inline job configuration, DRM encryption with Secret Manager integration, and adaptive streaming manifest generation. They’re intentionally minimal rather than full video processing pipelines.

The examples may reference pre-existing infrastructure such as GCS buckets for input video and output files, Secret Manager secrets for encryption keys, and IAM permissions for Transcoder service identity. They focus on configuring the transcoding job rather than provisioning the surrounding storage and security infrastructure.

To keep things focused, common transcoding patterns are omitted, including:

  • Pub/Sub notifications for job status (pubsubDestination)
  • Image overlays and watermarking (overlays)
  • Ad break insertion markers (adBreaks)
  • Edit lists for trimming and concatenation

These omissions are intentional: the goal is to illustrate how each transcoding feature is wired, not provide drop-in video processing modules. See the Transcoder Job resource reference for all available configuration options.

Let's create GCP Transcoder Jobs

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Job Configuration & Immutability
What properties can't I change after creating a transcoding job?
All core properties are immutable: config, location, project, and templateId. Changing any of these requires recreating the job.
Can I use a custom job template?
You can reference an existing gcp.transcoder.JobTemplate via templateId. The default is preset/web-hd, which is currently the only supported preset.
How do I use a job template instead of inline configuration?
Set templateId to the name of an existing gcp.transcoder.JobTemplate resource. The job will inherit the template’s configuration.
Encryption & Security
How do I encrypt transcoded output?
Configure encryptions in the job config with a Secret Manager key source. Supported encryption schemes include AES-128 (for HLS), CENC, and CBCS (for DASH with Widevine).
Why can't my transcoder job access the encryption key?
The transcoder service identity needs roles/secretmanager.secretAccessor on the Secret Manager secret. Grant this role to the service identity email.
Outputs & Notifications
How do I get notified when a transcoding job completes?
Configure pubsubDestination in the job config with a Pub/Sub topic ID. Job status updates will be published to that topic.
How do I generate HLS or DASH manifests?
Configure manifests in the job config, specifying type (HLS or DASH), fileName, and the muxStreams to include. HLS uses .m3u8 files, DASH uses .mpd files.
How do I add image overlays to transcoded video?
Configure overlays in the job config with an image URI and optional animations (e.g., fade in/out with timing and position).
Labels & Metadata
What's the difference between labels and effectiveLabels?
The labels field only manages labels in your Pulumi configuration. Use effectiveLabels to see all labels on the resource, including those set by other clients or services.
How do I organize multiple transcoding jobs?
Use the labels property to add key/value pairs for organizing and grouping jobs. Labels are useful for filtering and management.

Using a different cloud?

Explore analytics guides for other cloud providers: