This page explains how to generate a spritesheet that contains frames from a
video you transcode. These reduced-sized frames, also known as thumbnails, are
useful for organizing and previewing content. To generate the spritesheet, use
the
spriteSheets
array in the JobConfig
template.
You have two options for generating the spritesheet:
Generate a set number of thumbnail images
The following configuration generates a 10x10 spritesheet of large
images and a 10x10 spritesheet of small images, each with 100
thumbnails. Note that spritesheets require at least one VideoStream
in the job
configuration.
You can add this configuration to a
job template or include it in an
ad-hoc job configuration :
REST
Before using any of the request data,
make the following replacements:
PROJECT_ID
: Your Google Cloud project ID listed in
the IAM Settings .
LOCATION
: The location where your job will run. Use
one of the supported regions .
Show locations
us-central1
us-west1
us-west2
us-east1
us-east4
southamerica-east1
northamerica-northeast1
asia-east1
asia-northeast1
asia-northeast3
asia-south1
asia-southeast1
australia-southeast1
europe-west1
europe-west2
europe-west4
STORAGE_BUCKET_NAME
: The name of the Cloud Storage
bucket you created.
STORAGE_INPUT_VIDEO
: The name of the video in your
Cloud Storage bucket that you are transcoding, such as my-vid.mp4
.
This field should take into account any folders that you created in the
bucket (for example, input/my-vid.mp4
).
STORAGE_OUTPUT_FOLDER
: The Cloud Storage
folder name where you want to save the encoded video outputs.
Note: You don't need to create the output folder object before
creating the job. When processing the job, the Transcoder API automatically prepends the
folder name you specify as part of the names of the objects saved to Cloud Storage.
To send your request, expand one of these options:
curl (Linux, macOS, or Cloud Shell)
Note:
The following command assumes that you have logged in to
the gcloud
CLI with your user account by running
gcloud init
or
gcloud auth login
, or by using Cloud Shell ,
which automatically logs you into the gcloud
CLI
.
You can check the currently active account by running
gcloud auth list
.
Save the request body in a file named request.json
.
Run the following command in the terminal to create or overwrite
this file in the current directory:
cat > request.json << 'EOF'
{
"config": {
"inputs": [
{
"key": "input0",
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_INPUT_VIDEO "
}
],
"elementaryStreams": [
{
"key": "video-stream0",
"videoStream": {
"h264": {
"heightPixels": 360,
"widthPixels": 640,
"bitrateBps": 550000,
"frameRate": 60
}
}
},
{
"key": "audio-stream0",
"audioStream": {
"codec": "aac",
"bitrateBps": 64000
}
}
],
"muxStreams": [
{
"key": "sd",
"container": "mp4",
"elementaryStreams": [
"video-stream0",
"audio-stream0"
]
}
],
"output": {
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_OUTPUT_FOLDER /"
},
"spriteSheets": [
{
"filePrefix": "small-sprite-sheet",
"spriteHeightPixels": 32,
"spriteWidthPixels": 64,
"columnCount": 10,
"rowCount": 10,
"totalCount": 100
},
{
"filePrefix": "large-sprite-sheet",
"spriteHeightPixels": 72,
"spriteWidthPixels": 128,
"columnCount": 10,
"rowCount": 10,
"totalCount": 100
}
]
}
}
EOF
Then execute the following command to send your REST request:
curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d @request.json \ "https://transcoder.googleapis.com/v1/projects/PROJECT_ID /locations/LOCATION /jobs"
PowerShell (Windows)
Save the request body in a file named request.json
.
Run the following command in the terminal to create or overwrite
this file in the current directory:
@'
{
"config": {
"inputs": [
{
"key": "input0",
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_INPUT_VIDEO "
}
],
"elementaryStreams": [
{
"key": "video-stream0",
"videoStream": {
"h264": {
"heightPixels": 360,
"widthPixels": 640,
"bitrateBps": 550000,
"frameRate": 60
}
}
},
{
"key": "audio-stream0",
"audioStream": {
"codec": "aac",
"bitrateBps": 64000
}
}
],
"muxStreams": [
{
"key": "sd",
"container": "mp4",
"elementaryStreams": [
"video-stream0",
"audio-stream0"
]
}
],
"output": {
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_OUTPUT_FOLDER /"
},
"spriteSheets": [
{
"filePrefix": "small-sprite-sheet",
"spriteHeightPixels": 32,
"spriteWidthPixels": 64,
"columnCount": 10,
"rowCount": 10,
"totalCount": 100
},
{
"filePrefix": "large-sprite-sheet",
"spriteHeightPixels": 72,
"spriteWidthPixels": 128,
"columnCount": 10,
"rowCount": 10,
"totalCount": 100
}
]
}
}
'@ | Out-File -FilePath request.json -Encoding utf8
Then execute the following command to send your REST request:
$cred = gcloud auth print-access-token $headers = @{ "Authorization" = "Bearer $cred" } Invoke-WebRequest ` -Method POST ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -InFile request.json ` -Uri "https://transcoder.googleapis.com/v1/projects/PROJECT_ID /locations/LOCATION /jobs" | Select-Object -Expand Content
You should receive a JSON response similar to the following:
{
"name": "projects/PROJECT_NUMBER /locations/LOCATION /jobs/JOB_ID ",
"config": {
...
},
"state": "PENDING",
"createTime": CREATE_TIME ,
"ttlAfterCompletionDays": 30
}
gcloud
Create a request.json
file that defines the job fields. Make
the following replacements for the
gcloud
command:
STORAGE_BUCKET_NAME : The
name of the Cloud Storage bucket you created.
STORAGE_INPUT_VIDEO : The
name of the video in your Cloud Storage bucket that you are
transcoding, such as my-vid.mp4
. This field should take into
account any folders that you created in the bucket (for example,
input/my-vid.mp4
).
LOCATION : The location where
your job will run. Use a location from the following list.
Show locations
us-central1
us-west1
us-west2
us-east1
us-east4
southamerica-east1
northamerica-northeast1
asia-east1
asia-northeast1
asia-northeast3
asia-south1
asia-southeast1
australia-southeast1
europe-west1
europe-west2
europe-west4
STORAGE_OUTPUT_FOLDER : The
Cloud Storage folder name where you want to save the encoded video
outputs.
Note: You don't need to create the output folder object before
creating the job. When processing the job, the Transcoder API automatically prepends the
folder name you specify as part of the names of the objects saved to Cloud Storage.
{
"config": {
"inputs": [
{
"key": "input0",
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_INPUT_VIDEO "
}
],
"elementaryStreams": [
{
"key": "video-stream0",
"videoStream": {
"h264": {
"heightPixels": 360,
"widthPixels": 640,
"bitrateBps": 550000,
"frameRate": 60
}
}
},
{
"key": "audio-stream0",
"audioStream": {
"codec": "aac",
"bitrateBps": 64000
}
}
],
"muxStreams": [
{
"key": "sd",
"container": "mp4",
"elementaryStreams": [
"video-stream0",
"audio-stream0"
]
}
],
"output": {
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_OUTPUT_FOLDER /"
},
"spriteSheets": [
{
"filePrefix": "small-sprite-sheet",
"spriteHeightPixels": 32,
"spriteWidthPixels": 64,
"columnCount": 10,
"rowCount": 10,
"totalCount": 100
},
{
"filePrefix": "large-sprite-sheet",
"spriteHeightPixels": 72,
"spriteWidthPixels": 128,
"columnCount": 10,
"rowCount": 10,
"totalCount": 100
}
]
}
}
Run the following command:
gcloud transcoder jobs create --location=LOCATION --file="request.json"
You should see a response similar to the following:
{
"name": "projects/PROJECT_NUMBER /locations/LOCATION /jobs/JOB_ID ",
"config": {
...
},
"state": "PENDING",
"createTime": CREATE_TIME ,
"ttlAfterCompletionDays": 30
}
Go
Before trying this sample, follow the Go setup instructions in the
Transcoder API quickstart using
client libraries .
For more information, see the
Transcoder API Go API
reference documentation .
To authenticate to Transcoder API, set up Application Default Credentials.
For more information, see
Set up authentication for a local development environment .
import (
"context"
"fmt"
"io"
transcoder "cloud.google.com/go/video/transcoder/apiv1"
"cloud.google.com/go/video/transcoder/apiv1/transcoderpb"
)
// createJobWithSetNumberImagesSpritesheet creates a job from an ad-hoc configuration and generates
// two spritesheets from the input video. Each spritesheet contains a set number of images.
func createJobWithSetNumberImagesSpritesheet(w io.Writer, projectID string, location string, inputURI string, outputURI string) error {
// projectID := "my-project-id"
// location := "us-central1"
// inputURI := "gs://my-bucket/my-video-file"
// outputURI := "gs://my-bucket/my-output-folder/"
ctx := context.Background()
client, err := transcoder.NewClient(ctx)
if err != nil {
return fmt.Errorf("NewClient: %w", err)
}
defer client.Close()
req := &transcoderpb.CreateJobRequest{
Parent: fmt.Sprintf("projects/%s/locations/%s", projectID, location),
Job: &transcoderpb.Job{
InputUri: inputURI,
OutputUri: outputURI,
JobConfig: &transcoderpb.Job_Config{
Config: &transcoderpb.JobConfig{
ElementaryStreams: []*transcoderpb.ElementaryStream{
{
Key: "video_stream0",
ElementaryStream: &transcoderpb.ElementaryStream_VideoStream{
VideoStream: &transcoderpb.VideoStream{
CodecSettings: &transcoderpb.VideoStream_H264{
H264: &transcoderpb.VideoStream_H264CodecSettings{
BitrateBps: 550000,
FrameRate: 60,
HeightPixels: 360,
WidthPixels: 640,
},
},
},
},
},
{
Key: "audio_stream0",
ElementaryStream: &transcoderpb.ElementaryStream_AudioStream{
AudioStream: &transcoderpb.AudioStream{
Codec: "aac",
BitrateBps: 64000,
},
},
},
},
MuxStreams: []*transcoderpb.MuxStream{
{
Key: "sd",
Container: "mp4",
ElementaryStreams: []string{"video_stream0", "audio_stream0"},
},
},
SpriteSheets: []*transcoderpb.SpriteSheet{
{
FilePrefix: "small-sprite-sheet",
SpriteWidthPixels: 64,
SpriteHeightPixels: 32,
ColumnCount: 10,
RowCount: 10,
ExtractionStrategy: &transcoderpb.SpriteSheet_TotalCount{
TotalCount: 100,
},
},
{
FilePrefix: "large-sprite-sheet",
SpriteWidthPixels: 128,
SpriteHeightPixels: 72,
ColumnCount: 10,
RowCount: 10,
ExtractionStrategy: &transcoderpb.SpriteSheet_TotalCount{
TotalCount: 100,
},
},
},
},
},
},
}
// Creates the job. Jobs take a variable amount of time to run. You can query for the job state.
// See https://cloud.google.com/transcoder/docs/how-to/jobs#check_job_status for more info.
response, err := client.CreateJob(ctx, req)
if err != nil {
return fmt.Errorf("createJobWithSetNumberImagesSpritesheet: %w", err)
}
fmt.Fprintf(w, "Job: %v", response.GetName())
return nil
}
Node.js
Before trying this sample, follow the Node.js setup instructions in the
Transcoder API quickstart using
client libraries .
For more information, see the
Transcoder API Node.js API
reference documentation .
To authenticate to Transcoder API, set up Application Default Credentials.
For more information, see
Set up authentication for a local development environment .
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// projectId = 'my-project-id';
// location = 'us-central1';
// inputUri = 'gs://my-bucket/my-video-file';
// outputUri = 'gs://my-bucket/my-output-folder/';
// Imports the Transcoder library
const {TranscoderServiceClient} =
require('@google-cloud/video-transcoder').v1;
// Instantiates a client
const transcoderServiceClient = new TranscoderServiceClient();
async function createJobWithSetNumberImagesSpritesheet() {
// Construct request
const request = {
parent: transcoderServiceClient.locationPath(projectId, location),
job: {
inputUri: inputUri,
outputUri: outputUri,
config: {
elementaryStreams: [
{
key: 'video-stream0',
videoStream: {
h264: {
heightPixels: 360,
widthPixels: 640,
bitrateBps: 550000,
frameRate: 60,
},
},
},
{
key: 'audio-stream0',
audioStream: {
codec: 'aac',
bitrateBps: 64000,
},
},
],
muxStreams: [
{
key: 'sd',
container: 'mp4',
elementaryStreams: ['video-stream0', 'audio-stream0'],
},
],
spriteSheets: [
{
filePrefix: 'small-sprite-sheet',
spriteHeightPixels: 32,
spriteWidthPixels: 64,
columnCount: 10,
rowCount: 10,
totalCount: 100,
},
{
filePrefix: 'large-sprite-sheet',
spriteHeightPixels: 72,
spriteWidthPixels: 128,
columnCount: 10,
rowCount: 10,
totalCount: 100,
},
],
},
},
};
// Run request
const [response] = await transcoderServiceClient.createJob(request);
console.log(`Job: ${response.name}`);
}
createJobWithSetNumberImagesSpritesheet();
Python
Before trying this sample, follow the Python setup instructions in the
Transcoder API quickstart using
client libraries .
For more information, see the
Transcoder API Python API
reference documentation .
To authenticate to Transcoder API, set up Application Default Credentials.
For more information, see
Set up authentication for a local development environment .
import argparse
from google.cloud.video import transcoder_v1
from google.cloud.video.transcoder_v1.services.transcoder_service import (
TranscoderServiceClient,
)
def create_job_with_set_number_images_spritesheet(
project_id: str,
location: str,
input_uri: str,
output_uri: str,
) -> transcoder_v1.types.resources.Job:
"""Creates a job based on an ad-hoc job configuration that generates two spritesheets.
Args:
project_id: The GCP project ID.
location: The location to start the job in.
input_uri: Uri of the video in the Cloud Storage bucket.
output_uri: Uri of the video output folder in the Cloud Storage bucket.
Returns:
The job resource.
"""
client = TranscoderServiceClient()
parent = f"projects/{project_id}/locations/{location}"
job = transcoder_v1.types.Job()
job.input_uri = input_uri
job.output_uri = output_uri
job.config = transcoder_v1.types.JobConfig(
# Create an ad-hoc job. For more information, see https://cloud.google.com/transcoder/docs/how-to/jobs#create_jobs_ad_hoc.
# See all options for the job config at https://cloud.google.com/transcoder/docs/reference/rest/v1/JobConfig.
elementary_streams=[
# This section defines the output video stream.
transcoder_v1.types.ElementaryStream(
key="video-stream0",
video_stream=transcoder_v1.types.VideoStream(
h264=transcoder_v1.types.VideoStream.H264CodecSettings(
height_pixels=360,
width_pixels=640,
bitrate_bps=550000,
frame_rate=60,
),
),
),
# This section defines the output audio stream.
transcoder_v1.types.ElementaryStream(
key="audio-stream0",
audio_stream=transcoder_v1.types.AudioStream(
codec="aac", bitrate_bps=64000
),
),
],
# This section multiplexes the output audio and video together into a container.
mux_streams=[
transcoder_v1.types.MuxStream(
key="sd",
container="mp4",
elementary_streams=["video-stream0", "audio-stream0"],
),
],
# Generate two sprite sheets from the input video into the GCS bucket. For more information, see
# https://cloud.google.com/transcoder/docs/how-to/generate-spritesheet#generate_set_number_of_images.
sprite_sheets=[
# Generate a 10x10 sprite sheet with 64x32px images.
transcoder_v1.types.SpriteSheet(
file_prefix="small-sprite-sheet",
sprite_width_pixels=64,
sprite_height_pixels=32,
column_count=10,
row_count=10,
total_count=100,
),
# Generate a 10x10 sprite sheet with 128x72px images.
transcoder_v1.types.SpriteSheet(
file_prefix="large-sprite-sheet",
sprite_width_pixels=128,
sprite_height_pixels=72,
column_count=10,
row_count=10,
total_count=100,
),
],
)
response = client.create_job(parent=parent, job=job)
print(f"Job: {response.name}")
return response
Note: To preserve the source aspect ratio, set the spriteWidthPixels
field or
the spriteHeightPixels
field, but not both (the API will automatically
calculate the missing field).
Use this configuration on the sample video
to generate the following spritesheets:
Figure 1. Small image spritesheet (100 thumbnails)
Figure 2. Large image spritesheet (100 thumbnails)
Generate a thumbnail image periodically
The following configuration generates a spritesheet of small images
and a spritesheet of large images. Each spritesheet contains
thumbnails that were generated every 7 seconds from the input video. Note that spritesheets require at least one VideoStream
in the job
configuration.
You can add this configuration to a
job template or include it in an
ad-hoc job configuration :
REST
Before using any of the request data,
make the following replacements:
PROJECT_ID
: Your Google Cloud project ID listed in
the IAM Settings .
LOCATION
: The location where your job will run. Use
one of the supported regions .
Show locations
us-central1
us-west1
us-west2
us-east1
us-east4
southamerica-east1
northamerica-northeast1
asia-east1
asia-northeast1
asia-northeast3
asia-south1
asia-southeast1
australia-southeast1
europe-west1
europe-west2
europe-west4
STORAGE_BUCKET_NAME
: The name of the Cloud Storage
bucket you created.
STORAGE_INPUT_VIDEO
: The name of the video in your
Cloud Storage bucket that you are transcoding, such as my-vid.mp4
.
This field should take into account any folders that you created in the
bucket (for example, input/my-vid.mp4
).
STORAGE_OUTPUT_FOLDER
: The Cloud Storage
folder name where you want to save the encoded video outputs.
Note: You don't need to create the output folder object before
creating the job. When processing the job, the Transcoder API automatically prepends the
folder name you specify as part of the names of the objects saved to Cloud Storage.
To send your request, expand one of these options:
curl (Linux, macOS, or Cloud Shell)
Note:
The following command assumes that you have logged in to
the gcloud
CLI with your user account by running
gcloud init
or
gcloud auth login
, or by using Cloud Shell ,
which automatically logs you into the gcloud
CLI
.
You can check the currently active account by running
gcloud auth list
.
Save the request body in a file named request.json
.
Run the following command in the terminal to create or overwrite
this file in the current directory:
cat > request.json << 'EOF'
{
"config": {
"inputs": [
{
"key": "input0",
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_INPUT_VIDEO "
}
],
"elementaryStreams": [
{
"key": "video-stream0",
"videoStream": {
"h264": {
"heightPixels": 360,
"widthPixels": 640,
"bitrateBps": 550000,
"frameRate": 60
}
}
},
{
"key": "audio-stream0",
"audioStream": {
"codec": "aac",
"bitrateBps": 64000
}
}
],
"muxStreams": [
{
"key": "sd",
"container": "mp4",
"elementaryStreams": [
"video-stream0",
"audio-stream0"
]
}
],
"output": {
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_OUTPUT_FOLDER /"
},
"spriteSheets": [
{
"filePrefix": "small-sprite-sheet",
"spriteHeightPixels": 32,
"spriteWidthPixels": 64,
"interval": "7s"
},
{
"filePrefix": "large-sprite-sheet",
"spriteHeightPixels": 72,
"spriteWidthPixels": 128,
"interval": "7s"
}
]
}
}
EOF
Then execute the following command to send your REST request:
curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d @request.json \ "https://transcoder.googleapis.com/v1/projects/PROJECT_ID /locations/LOCATION /jobs"
PowerShell (Windows)
Save the request body in a file named request.json
.
Run the following command in the terminal to create or overwrite
this file in the current directory:
@'
{
"config": {
"inputs": [
{
"key": "input0",
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_INPUT_VIDEO "
}
],
"elementaryStreams": [
{
"key": "video-stream0",
"videoStream": {
"h264": {
"heightPixels": 360,
"widthPixels": 640,
"bitrateBps": 550000,
"frameRate": 60
}
}
},
{
"key": "audio-stream0",
"audioStream": {
"codec": "aac",
"bitrateBps": 64000
}
}
],
"muxStreams": [
{
"key": "sd",
"container": "mp4",
"elementaryStreams": [
"video-stream0",
"audio-stream0"
]
}
],
"output": {
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_OUTPUT_FOLDER /"
},
"spriteSheets": [
{
"filePrefix": "small-sprite-sheet",
"spriteHeightPixels": 32,
"spriteWidthPixels": 64,
"interval": "7s"
},
{
"filePrefix": "large-sprite-sheet",
"spriteHeightPixels": 72,
"spriteWidthPixels": 128,
"interval": "7s"
}
]
}
}
'@ | Out-File -FilePath request.json -Encoding utf8
Then execute the following command to send your REST request:
$cred = gcloud auth print-access-token $headers = @{ "Authorization" = "Bearer $cred" } Invoke-WebRequest ` -Method POST ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -InFile request.json ` -Uri "https://transcoder.googleapis.com/v1/projects/PROJECT_ID /locations/LOCATION /jobs" | Select-Object -Expand Content
You should receive a JSON response similar to the following:
{
"name": "projects/PROJECT_NUMBER /locations/LOCATION /jobs/JOB_ID ",
"config": {
...
},
"state": "PENDING",
"createTime": CREATE_TIME ,
"ttlAfterCompletionDays": 30
}
gcloud
Create a request.json
file that defines the job fields. Make
the following replacements for the
gcloud
command:
STORAGE_BUCKET_NAME : The
name of the Cloud Storage bucket you created.
STORAGE_INPUT_VIDEO : The
name of the video in your Cloud Storage bucket that you are
transcoding, such as my-vid.mp4
. This field should take into
account any folders that you created in the bucket (for example,
input/my-vid.mp4
).
LOCATION : The location where
your job will run. Use a location from the following list.
Show locations
us-central1
us-west1
us-west2
us-east1
us-east4
southamerica-east1
northamerica-northeast1
asia-east1
asia-northeast1
asia-northeast3
asia-south1
asia-southeast1
australia-southeast1
europe-west1
europe-west2
europe-west4
STORAGE_OUTPUT_FOLDER : The
Cloud Storage folder name where you want to save the encoded video
outputs.
Note: You don't need to create the output folder object before
creating the job. When processing the job, the Transcoder API automatically prepends the
folder name you specify as part of the names of the objects saved to Cloud Storage.
{
"config": {
"inputs": [
{
"key": "input0",
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_INPUT_VIDEO "
}
],
"elementaryStreams": [
{
"key": "video-stream0",
"videoStream": {
"h264": {
"heightPixels": 360,
"widthPixels": 640,
"bitrateBps": 550000,
"frameRate": 60
}
}
},
{
"key": "audio-stream0",
"audioStream": {
"codec": "aac",
"bitrateBps": 64000
}
}
],
"muxStreams": [
{
"key": "sd",
"container": "mp4",
"elementaryStreams": [
"video-stream0",
"audio-stream0"
]
}
],
"output": {
"uri": "gs://STORAGE_BUCKET_NAME /STORAGE_OUTPUT_FOLDER /"
},
"spriteSheets": [
{
"filePrefix": "small-sprite-sheet",
"spriteHeightPixels": 32,
"spriteWidthPixels": 64,
"interval": "7s"
},
{
"filePrefix": "large-sprite-sheet",
"spriteHeightPixels": 72,
"spriteWidthPixels": 128,
"interval": "7s"
}
]
}
}
Run the following command:
gcloud transcoder jobs create --location=LOCATION --file="request.json"
You should see a response similar to the following:
{
"name": "projects/PROJECT_NUMBER /locations/LOCATION /jobs/JOB_ID ",
"config": {
...
},
"state": "PENDING",
"createTime": CREATE_TIME ,
"ttlAfterCompletionDays": 30
}
Go
Before trying this sample, follow the Go setup instructions in the
Transcoder API quickstart using
client libraries .
For more information, see the
Transcoder API Go API
reference documentation .
To authenticate to Transcoder API, set up Application Default Credentials.
For more information, see
Set up authentication for a local development environment .
import (
"context"
"fmt"
"io"
"github.com/golang/protobuf/ptypes/duration"
transcoder "cloud.google.com/go/video/transcoder/apiv1"
"cloud.google.com/go/video/transcoder/apiv1/transcoderpb"
)
// createJobWithPeriodicImagesSpritesheet creates a job from an ad-hoc configuration and generates
// two spritesheets from the input video. Each spritesheet contains images that are captured
// periodically based on a user-defined time interval.
func createJobWithPeriodicImagesSpritesheet(w io.Writer, projectID string, location string, inputURI string, outputURI string) error {
// projectID := "my-project-id"
// location := "us-central1"
// inputURI := "gs://my-bucket/my-video-file"
// outputURI := "gs://my-bucket/my-output-folder/"
ctx := context.Background()
client, err := transcoder.NewClient(ctx)
if err != nil {
return fmt.Errorf("NewClient: %w", err)
}
defer client.Close()
req := &transcoderpb.CreateJobRequest{
Parent: fmt.Sprintf("projects/%s/locations/%s", projectID, location),
Job: &transcoderpb.Job{
InputUri: inputURI,
OutputUri: outputURI,
JobConfig: &transcoderpb.Job_Config{
Config: &transcoderpb.JobConfig{
ElementaryStreams: []*transcoderpb.ElementaryStream{
{
Key: "video_stream0",
ElementaryStream: &transcoderpb.ElementaryStream_VideoStream{
VideoStream: &transcoderpb.VideoStream{
CodecSettings: &transcoderpb.VideoStream_H264{
H264: &transcoderpb.VideoStream_H264CodecSettings{
BitrateBps: 550000,
FrameRate: 60,
HeightPixels: 360,
WidthPixels: 640,
},
},
},
},
},
{
Key: "audio_stream0",
ElementaryStream: &transcoderpb.ElementaryStream_AudioStream{
AudioStream: &transcoderpb.AudioStream{
Codec: "aac",
BitrateBps: 64000,
},
},
},
},
MuxStreams: []*transcoderpb.MuxStream{
{
Key: "sd",
Container: "mp4",
ElementaryStreams: []string{"video_stream0", "audio_stream0"},
},
},
SpriteSheets: []*transcoderpb.SpriteSheet{
{
FilePrefix: "small-sprite-sheet",
SpriteWidthPixels: 64,
SpriteHeightPixels: 32,
ExtractionStrategy: &transcoderpb.SpriteSheet_Interval{
Interval: &duration.Duration{
Seconds: 7,
},
},
},
{
FilePrefix: "large-sprite-sheet",
SpriteWidthPixels: 128,
SpriteHeightPixels: 72,
ExtractionStrategy: &transcoderpb.SpriteSheet_Interval{
Interval: &duration.Duration{
Seconds: 7,
},
},
},
},
},
},
},
}
// Creates the job. Jobs take a variable amount of time to run. You can query for the job state.
// See https://cloud.google.com/transcoder/docs/how-to/jobs#check_job_status for more info.
response, err := client.CreateJob(ctx, req)
if err != nil {
return fmt.Errorf("createJobWithPeriodicImagesSpritesheet: %w", err)
}
fmt.Fprintf(w, "Job: %v", response.GetName())
return nil
}
Python
Before trying this sample, follow the Python setup instructions in the
Transcoder API quickstart using
client libraries .
For more information, see the
Transcoder API Python API
reference documentation .
To authenticate to Transcoder API, set up Application Default Credentials.
For more information, see
Set up authentication for a local development environment .
import argparse
from google.cloud.video import transcoder_v1
from google.cloud.video.transcoder_v1.services.transcoder_service import (
TranscoderServiceClient,
)
from google.protobuf import duration_pb2 as duration
def create_job_with_periodic_images_spritesheet(
project_id: str,
location: str,
input_uri: str,
output_uri: str,
) -> transcoder_v1.types.resources.Job:
"""Creates a job based on an ad-hoc job configuration that generates two spritesheets.
Args:
project_id: The GCP project ID.
location: The location to start the job in.
input_uri: Uri of the video in the Cloud Storage bucket.
output_uri: Uri of the video output folder in the Cloud Storage bucket.
Returns:
The job resource.
"""
client = TranscoderServiceClient()
parent = f"projects/{project_id}/locations/{location}"
job = transcoder_v1.types.Job()
job.input_uri = input_uri
job.output_uri = output_uri
job.config = transcoder_v1.types.JobConfig(
# Create an ad-hoc job. For more information, see https://cloud.google.com/transcoder/docs/how-to/jobs#create_jobs_ad_hoc.
# See all options for the job config at https://cloud.google.com/transcoder/docs/reference/rest/v1/JobConfig.
elementary_streams=[
# This section defines the output video stream.
transcoder_v1.types.ElementaryStream(
key="video-stream0",
video_stream=transcoder_v1.types.VideoStream(
h264=transcoder_v1.types.VideoStream.H264CodecSettings(
height_pixels=360,
width_pixels=640,
bitrate_bps=550000,
frame_rate=60,
),
),
),
# This section defines the output audio stream.
transcoder_v1.types.ElementaryStream(
key="audio-stream0",
audio_stream=transcoder_v1.types.AudioStream(
codec="aac", bitrate_bps=64000
),
),
],
# This section multiplexes the output audio and video together into a container.
mux_streams=[
transcoder_v1.types.MuxStream(
key="sd",
container="mp4",
elementary_streams=["video-stream0", "audio-stream0"],
),
],
# Generate two sprite sheets from the input video into the GCS bucket. For more information, see
# https://cloud.google.com/transcoder/docs/how-to/generate-spritesheet#generate_image_periodically.
sprite_sheets=[
# Generate a sprite sheet with 64x32px images. An image is taken every 7 seconds from the video.
transcoder_v1.types.SpriteSheet(
file_prefix="small-sprite-sheet",
sprite_width_pixels=64,
sprite_height_pixels=32,
interval=duration.Duration(
seconds=7,
),
),
# Generate a sprite sheet with 128x72px images. An image is taken every 7 seconds from the video.
transcoder_v1.types.SpriteSheet(
file_prefix="large-sprite-sheet",
sprite_width_pixels=128,
sprite_height_pixels=72,
interval=duration.Duration(
seconds=7,
),
),
],
)
response = client.create_job(parent=parent, job=job)
print(f"Job: {response.name}")
return response
Note: To preserve the source aspect ratio, set the spriteWidthPixels
field or
the spriteHeightPixels
field, but not both (the API will automatically
calculate the missing field).
Use this configuration on the sample video
to generate the following spritesheets:
Figure 3. Small image spritesheet (1 thumbnail every 7 seconds)
Figure 4. Large image spritesheet (1 thumbnail every 7 seconds)
Eight thumbnails are generated from the sample video, which is 60 seconds in
length.