This page explains how to add closed captions and subtitles to an output video.
Closed captions (or just captions) are the visual display of the audio in a video. Closed captions are typically in the same language as the audio and include background sounds and speaker changes.
Subtitles are typically used to translate the dialogue of a video into a different language. Subtitles usually do not include background sounds and speaker changes.
This page uses the term input caption file to refer to a text file that contains closed captions or subtitles. You provide this file as an input to a job.
Add captions and subtitles to a job configuration
Refer to the supported inputs and outputs for the supported input caption file formats. A sample video file and sample input caption files are provided for you to test your configuration.
Use the information in the following sections to add captions and subtitles to a job configuration. This page assumes you are familiar with a basic JobConfig. For more information on creating transcoding jobs, see Creating and managing jobs.
Add captions
To create a job that embeds captions in the output video file container, do the following:
Add an
inputs
array to the beginning of the job configuration.Add an
Input
object to theinputs
array that defines the key and URI for the associated input video.Add another
Input
object that includes the path to the input caption file.Add an
editList
array to the job configuration. This array is used to add inputs to the output video timeline.Add an
EditAtom
object to theeditList
array. ThisEditAtom
object must reference the keys for the input video and captions you added in theinputs
array. You can designate astartTimeOffset
andendTimeOffset
to trim the input video.Add the captions to the output containers by adding a
textStream
object to theelementaryStreams
array. Only one embedded text stream is supported and it is added to all output videos (as there is only one output timeline).Use the
mapping
array in thetextStream
configuration object to reference theEditAtom
object key.
The following example configuration embeds CEA-608 closed captions in a video.
You can add this configuration to a job template or include it in an ad-hoc job configuration:
Add subtitles
To create a job that produces multi-language subtitle files played from a manifest, do the following:
Add an
inputs
array to the job configuration.Add an
Input
object to theinputs
array that defines the key and URI for the associated input video.Add another
Input
object that defines the URI for the input caption file.Add an
editList
array to the configuration. This array is used to add the inputs to the output video timeline.Add an
EditAtom
object to theeditList
array that references the objects in theinputs
array by key. You can designate astartTimeOffset
andendTimeOffset
to trim the input video.Add the captions to the output containers by adding a
textStream
object to theelementaryStreams
array.For the standalone caption file, specify the container in the
muxStream
array; see the objects with keystext-vtt-en
andtext-vtt-es
in the following configuration. For embedded captions, you only need the elementary stream.
The following configuration generates multiple WebVTT files, one for English subtitles and one for Spanish subtitles. DASH subtitles in WebVTT files are created in the fMP4 container format.
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 locationsus-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 a video in your Cloud Storage bucket that you are transcoding, such asmy-vid.mp4
. This field should take into account any folders that you created in the bucket (for example,input/my-vid.mp4
).STORAGE_SUBTITLES_FILE1
: The name of the subtitles file in your Cloud Storage bucket, such assubtitles-en.srt
for English language subtitles. This field should take into account any folders that you created in the bucket (for example,input/subtitles-en.srt
).STORAGE_SUBTITLES_FILE2
: The name of another subtitles file in your Cloud Storage bucket, such assubtitles-es.srt
for Spanish language subtitles. This field should take into account any folders that you created in the bucket (for example,input/subtitles-es.srt
).STORAGE_OUTPUT_FOLDER
: The name of the output folder in your Cloud Storage bucket where you want to save the encoded video outputs.
To send your request, expand one of these options:
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
Before using any of the command data below, make the following replacements:
LOCATION
: The location where your job will run. Use one of the supported regions.Show locationsus-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 a video in your Cloud Storage bucket that you are transcoding, such asmy-vid.mp4
. This field should take into account any folders that you created in the bucket (for example,input/my-vid.mp4
).STORAGE_SUBTITLES_FILE1
: The name of the subtitles file in your Cloud Storage bucket, such assubtitles-en.srt
for English language subtitles. This field should take into account any folders that you created in the bucket (for example,input/subtitles-en.srt
).STORAGE_SUBTITLES_FILE2
: The name of another subtitles file in your Cloud Storage bucket, such assubtitles-es.srt
for Spanish language subtitles. This field should take into account any folders that you created in the bucket (for example,input/subtitles-es.srt
).STORAGE_OUTPUT_FOLDER
: The name of the output folder in your Cloud Storage bucket where you want to save the encoded video outputs.
Save the following content in a file called request.json
:
{ "config": { "inputs": [ { "key": "input0", "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_INPUT_VIDEO" }, { "key": "subtitle_input_en", "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_SUBTITLES_FILE1" }, { "key": "subtitle_input_es", "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_SUBTITLES_FILE2" } ], "editList": [ { "key": "atom0", "inputs": [ "input0", "subtitle_input_en", "subtitle_input_es" ] } ], "elementaryStreams": [ { "key": "video-stream0", "videoStream": { "h264": { "heightPixels": 360, "widthPixels": 640, "bitrateBps": 550000, "frameRate": 60 } } }, { "key": "audio-stream0", "audioStream": { "codec": "aac", "bitrateBps": 64000 } }, { "key": "vtt-stream-en", "textStream": { "codec": "webvtt", "languageCode": "en-US", "displayName": "English", "mapping": [ { "atomKey": "atom0", "inputKey": "subtitle_input_en" } ] } }, { "key": "vtt-stream-es", "textStream": { "codec": "webvtt", "languageCode": "es-ES", "displayName": "Spanish", "mapping": [ { "atomKey": "atom0", "inputKey": "subtitle_input_es" } ] } } ], "muxStreams": [ { "key": "sd-hls-fmp4", "container": "fmp4", "elementaryStreams": [ "video-stream0" ] }, { "key": "audio-hls-fmp4", "container": "fmp4", "elementaryStreams": [ "audio-stream0" ] }, { "key": "text-vtt-en", "container": "vtt", "elementaryStreams": [ "vtt-stream-en" ], "segmentSettings": { "segmentDuration": "6s", "individualSegments": true } }, { "key": "text-vtt-es", "container": "vtt", "elementaryStreams": [ "vtt-stream-es" ], "segmentSettings": { "segmentDuration": "6s", "individualSegments": true } } ], "manifests": [ { "fileName": "manifest.m3u8", "type": "HLS", "muxStreams": [ "sd-hls-fmp4", "audio-hls-fmp4", "text-vtt-en", "text-vtt-es" ] } ], "output": { "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_OUTPUT_FOLDER/" } } }
Execute the following command:
Linux, macOS, or Cloud Shell
gcloud transcoder jobs create --location=LOCATION --file=request.json
Windows (PowerShell)
gcloud transcoder jobs create --location=LOCATION --file=request.json
Windows (cmd.exe)
gcloud transcoder jobs create --location=LOCATION --file=request.json
You should receive 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.
Java
Before trying this sample, follow the Java setup instructions in the Transcoder API quickstart using client libraries. For more information, see the Transcoder API Java 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.
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.
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.
Play your video
To view the captions or subtitles on Windows, play the video in the Movies & TV app. Make sure to select the subtitles track.
To view the captions or subtitles on MacOS or Linux, you can play the video in Shaka Player. Make sure to enable captions or subtitles from the Captions menu.
To play the generated media file in Shaka Player, complete the following steps:
- Make the Cloud Storage bucket you created publicly readable.
- To enable cross-origin resource
sharing (CORS) on a Cloud Storage bucket, do the following:
- Create a JSON file that contains the following:
[ { "origin": ["https://shaka-player-demo.appspot.com/"], "responseHeader": ["Content-Type", "Range"], "method": ["GET", "HEAD"], "maxAgeSeconds": 3600 } ]
-
Run the following command after replacing JSON_FILE_NAME with
the name of the JSON file you created in the previous step:
gcloud storage buckets update gs://STORAGE_BUCKET_NAME --cors-file=JSON_FILE_NAME.json
- Create a JSON file that contains the following:
- Pick one of the MP4 or manifest files generated by the transcoding job in the Cloud Storage bucket. Click Copy URL in the file's Public access column.
- Navigate to Shaka Player, an online live stream player.
- Click Custom Content in the top navigation bar.
- Click the + button.
Paste the public URL of the file into the Manifest URL box.
Type a name in the Name box.
Click Save.
Click Play.
Select the ellipsis button on the bottom right of the player and enable captions.
Example
You can use the following files for a test job:
- Sample input video
- Sample input caption file for closed captions
- Sample input caption file for English subtitles
- Sample input caption file for Spanish subtitles
The input caption file must not contain blank lines in between text lines.