Crea un trabajo de transcodificación que incorpore los subtítulos en el video de salida. Pueden incluir subtítulos.
Explora más
Para obtener documentación en la que se incluye esta muestra de código, consulta lo siguiente:
Muestra de código
Go
Antes de probar esta muestra, sigue las instrucciones de configuración de Go que se encuentran en la guía de inicio rápido sobre la API de Transcoder mediante bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Go para la API de Transcoder.
import (
"context"
"fmt"
"io"
transcoder "cloud.google.com/go/video/transcoder/apiv1"
"cloud.google.com/go/video/transcoder/apiv1/transcoderpb"
)
// createJobWithEmbeddedCaptions creates a job that embeds closed captions in the
// output video. See https://cloud.google.com/transcoder/docs/how-to/captions-and-subtitles
// for more information.
func createJobWithEmbeddedCaptions(w io.Writer, projectID string, location string, inputVideoURI string, inputCaptionsURI string, outputURI string) error {
// projectID := "my-project-id"
// location := "us-central1"
// inputVideoURI := "gs://my-bucket/my-video-file"
// inputCaptionsURI := "gs://my-bucket/my-captions-file"
// outputURI := "gs://my-bucket/my-output-folder/"
ctx := context.Background()
client, err := transcoder.NewClient(ctx)
if err != nil {
return fmt.Errorf("NewClient: %v", err)
}
defer client.Close()
// Set up elementary streams. The InputKey field refers to inputs in
// the Inputs array defined the job config.
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,
},
},
},
{
Key: "cea_stream0",
ElementaryStream: &transcoderpb.ElementaryStream_TextStream{
TextStream: &transcoderpb.TextStream{
Codec: "cea608",
Mapping: []*transcoderpb.TextStream_TextMapping{
{
AtomKey: "atom0",
InputKey: "caption_input0",
InputTrack: 0,
},
},
LanguageCode: "en-US",
DisplayName: "English",
},
},
},
}
req := &transcoderpb.CreateJobRequest{
Parent: fmt.Sprintf("projects/%s/locations/%s", projectID, location),
Job: &transcoderpb.Job{
OutputUri: outputURI,
JobConfig: &transcoderpb.Job_Config{
Config: &transcoderpb.JobConfig{
Inputs: []*transcoderpb.Input{
{
Key: "input0",
Uri: inputVideoURI,
},
{
Key: "caption_input0",
Uri: inputCaptionsURI,
},
},
EditList: []*transcoderpb.EditAtom{
{
Key: "atom0",
Inputs: []string{"input0", "caption_input0"},
},
},
ElementaryStreams: elementaryStreams,
MuxStreams: []*transcoderpb.MuxStream{
{
Key: "sd-hls",
Container: "ts",
ElementaryStreams: []string{"video_stream0", "audio_stream0"},
},
{
Key: "sd-dash",
Container: "fmp4",
ElementaryStreams: []string{"video_stream0"},
},
{
Key: "audio-dash",
Container: "fmp4",
ElementaryStreams: []string{"audio_stream0"},
},
},
Manifests: []*transcoderpb.Manifest{
{
FileName: "manifest.m3u8",
Type: transcoderpb.Manifest_HLS,
MuxStreams: []string{"sd-hls"},
},
{
FileName: "manifest.mpd",
Type: transcoderpb.Manifest_DASH,
MuxStreams: []string{"sd-dash", "audio-dash"},
},
},
},
},
},
}
// Creates the job. Jobs take a variable amount of time to run.
// You can query for the job state; see getJob() in get_job.go.
response, err := client.CreateJob(ctx, req)
if err != nil {
return fmt.Errorf("CreateJob: %v", err)
}
fmt.Fprintf(w, "Job: %v", response.GetName())
return nil
}
Java
Antes de probar esta muestra, sigue las instrucciones de configuración de Java que se encuentran en la guía de inicio rápido sobre la API de Transcoder mediante bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Java para la API de Transcoder.
import com.google.cloud.video.transcoder.v1.AudioStream;
import com.google.cloud.video.transcoder.v1.CreateJobRequest;
import com.google.cloud.video.transcoder.v1.EditAtom;
import com.google.cloud.video.transcoder.v1.ElementaryStream;
import com.google.cloud.video.transcoder.v1.Input;
import com.google.cloud.video.transcoder.v1.Job;
import com.google.cloud.video.transcoder.v1.JobConfig;
import com.google.cloud.video.transcoder.v1.LocationName;
import com.google.cloud.video.transcoder.v1.Manifest;
import com.google.cloud.video.transcoder.v1.Manifest.ManifestType;
import com.google.cloud.video.transcoder.v1.MuxStream;
import com.google.cloud.video.transcoder.v1.Output;
import com.google.cloud.video.transcoder.v1.TextStream;
import com.google.cloud.video.transcoder.v1.TextStream.TextMapping;
import com.google.cloud.video.transcoder.v1.TranscoderServiceClient;
import com.google.cloud.video.transcoder.v1.VideoStream;
import java.io.IOException;
public class CreateJobWithEmbeddedCaptions {
public static void main(String[] args) throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "my-project-id";
String location = "us-central1";
String inputVideoUri = "gs://my-bucket/my-video-file";
String inputCaptionsUri = "gs://my-bucket/my-captions-file";
String outputUri = "gs://my-bucket/my-output-folder/";
createJobWithEmbeddedCaptions(projectId, location, inputVideoUri, inputCaptionsUri, outputUri);
}
// Creates a job from an ad-hoc configuration that embeds captions in the output video.
public static void createJobWithEmbeddedCaptions(
String projectId,
String location,
String inputVideoUri,
String inputCaptionsUri,
String outputUri)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try (TranscoderServiceClient transcoderServiceClient = TranscoderServiceClient.create()) {
VideoStream videoStream0 =
VideoStream.newBuilder()
.setH264(
VideoStream.H264CodecSettings.newBuilder()
.setBitrateBps(550000)
.setFrameRate(60)
.setHeightPixels(360)
.setWidthPixels(640))
.build();
AudioStream audioStream0 =
AudioStream.newBuilder().setCodec("aac").setBitrateBps(64000).build();
TextStream textStream0 =
TextStream.newBuilder()
.setCodec("cea608")
.addMapping(
0,
TextMapping.newBuilder()
.setAtomKey("atom0")
.setInputKey("caption_input0")
.setInputTrack(0)
.build())
.build();
JobConfig config =
JobConfig.newBuilder()
.addInputs(Input.newBuilder().setKey("input0").setUri(inputVideoUri))
.addInputs(Input.newBuilder().setKey("caption_input0").setUri(inputCaptionsUri))
.addEditList(
0, // Index in the edit list
EditAtom.newBuilder()
.setKey("atom0")
.addInputs("input0")
.addInputs("caption_input0")
.build())
.setOutput(Output.newBuilder().setUri(outputUri))
.addElementaryStreams(
ElementaryStream.newBuilder()
.setKey("video_stream0")
.setVideoStream(videoStream0))
.addElementaryStreams(
ElementaryStream.newBuilder()
.setKey("audio_stream0")
.setAudioStream(audioStream0))
.addElementaryStreams(
ElementaryStream.newBuilder().setKey("cea_stream0").setTextStream(textStream0))
.addMuxStreams(
0,
MuxStream.newBuilder()
.setKey("sd")
.setContainer("mp4")
.addElementaryStreams("video_stream0")
.addElementaryStreams("audio_stream0")
.build())
.addMuxStreams(
1,
MuxStream.newBuilder()
.setKey("sd_hls")
.setContainer("ts")
.addElementaryStreams("video_stream0")
.addElementaryStreams("audio_stream0")
.build())
.addMuxStreams(
2,
MuxStream.newBuilder()
.setKey("sd_dash")
.setContainer("fmp4")
.addElementaryStreams("video_stream0")
.build())
.addMuxStreams(
3,
MuxStream.newBuilder()
.setKey("audio_dash")
.setContainer("fmp4")
.addElementaryStreams("audio_stream0")
.build())
.addManifests(
0,
Manifest.newBuilder()
.setFileName("manifest.m3u8")
.setType(ManifestType.HLS)
.addMuxStreams("sd_hls")
.build())
.addManifests(
1,
Manifest.newBuilder()
.setFileName("manifest.mpd")
.setType(ManifestType.DASH)
.addMuxStreams("sd_dash")
.addMuxStreams("audio_dash")
.build())
.build();
var createJobRequest =
CreateJobRequest.newBuilder()
.setJob(Job.newBuilder().setOutputUri(outputUri).setConfig(config).build())
.setParent(LocationName.of(projectId, location).toString())
.build();
// Send the job creation request and process the response.
Job job = transcoderServiceClient.createJob(createJobRequest);
System.out.println("Job: " + job.getName());
}
}
}
Node.js
Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js que se encuentran en la guía de inicio rápido sobre la API de Transcoder mediante bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Node.js para la API de Transcoder.
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// projectId = 'my-project-id';
// location = 'us-central1';
// inputVideoUri = 'gs://my-bucket/my-video-file';
// inputCaptionsUri = 'gs://my-bucket/my-captions-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 createJobWithEmbeddedCaptions() {
// Construct request
const request = {
parent: transcoderServiceClient.locationPath(projectId, location),
job: {
outputUri: outputUri,
config: {
inputs: [
{
key: 'input0',
uri: inputVideoUri,
},
{
key: 'caption_input0',
uri: inputCaptionsUri,
},
],
editList: [
{
key: 'atom0',
inputs: ['input0', 'caption_input0'],
},
],
elementaryStreams: [
{
key: 'video-stream0',
videoStream: {
h264: {
heightPixels: 360,
widthPixels: 640,
bitrateBps: 550000,
frameRate: 60,
},
},
},
{
key: 'audio-stream0',
audioStream: {
codec: 'aac',
bitrateBps: 64000,
},
},
{
key: 'cea-stream0',
textStream: {
codec: 'cea608',
mapping: [
{
atomKey: 'atom0',
inputKey: 'caption_input0',
inputTrack: 0,
},
],
languageCode: 'en-US',
displayName: 'English',
},
},
],
muxStreams: [
{
key: 'sd-hls',
container: 'ts',
elementaryStreams: ['video-stream0', 'audio-stream0'],
},
{
key: 'sd-dash',
container: 'fmp4',
elementaryStreams: ['video-stream0'],
},
{
key: 'audio-dash',
container: 'fmp4',
elementaryStreams: ['audio-stream0'],
},
],
manifests: [
{
fileName: 'manifest.m3u8',
type: 'HLS',
muxStreams: ['sd-hls'],
},
{
fileName: 'manifest.mpd',
type: 'DASH',
muxStreams: ['sd-dash', 'audio-dash'],
},
],
},
},
};
// Run request
const [response] = await transcoderServiceClient.createJob(request);
console.log(`Job: ${response.name}`);
}
createJobWithEmbeddedCaptions();
Python
Antes de probar esta muestra, sigue las instrucciones de configuración de Python que se encuentran en la guía de inicio rápido sobre la API de Transcoder mediante bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Python para la API de Transcoder.
import argparse
from google.cloud.video import transcoder_v1
from google.cloud.video.transcoder_v1.services.transcoder_service import (
TranscoderServiceClient,
)
def create_job_with_embedded_captions(
project_id,
location,
input_video_uri,
input_captions_uri,
output_uri,
):
"""Creates a job based on an ad-hoc job configuration that embeds captions in the output video.
Args:
project_id (str): The GCP project ID.
location (str): The location to start the job in.
input_video_uri (str): Uri of the input video in the Cloud Storage
bucket.
input_captions_uri (str): Uri of the input captions file in the Cloud
Storage bucket.
output_uri (str): Uri of the video output folder in the Cloud Storage
bucket."""
client = TranscoderServiceClient()
parent = f"projects/{project_id}/locations/{location}"
job = transcoder_v1.types.Job()
job.output_uri = output_uri
job.config = transcoder_v1.types.JobConfig(
inputs=[
transcoder_v1.types.Input(
key="input0",
uri=input_video_uri,
),
transcoder_v1.types.Input(
key="caption-input0",
uri=input_captions_uri,
),
],
edit_list=[
transcoder_v1.types.EditAtom(
key="atom0",
inputs=["input0", "caption-input0"],
),
],
elementary_streams=[
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,
),
),
),
transcoder_v1.types.ElementaryStream(
key="audio-stream0",
audio_stream=transcoder_v1.types.AudioStream(
codec="aac", bitrate_bps=64000
),
),
transcoder_v1.types.ElementaryStream(
key="cea-stream0",
text_stream=transcoder_v1.types.TextStream(
codec="cea608",
mapping_=[
transcoder_v1.types.TextStream.TextMapping(
atom_key="atom0",
input_key="caption-input0",
input_track=0,
),
],
),
),
],
mux_streams=[
transcoder_v1.types.MuxStream(
key="sd",
container="mp4",
elementary_streams=["video-stream0", "audio-stream0"],
),
transcoder_v1.types.MuxStream(
key="sd-hls",
container="ts",
elementary_streams=["video-stream0", "audio-stream0"],
),
transcoder_v1.types.MuxStream(
key="sd-dash",
container="fmp4",
elementary_streams=["video-stream0"],
),
transcoder_v1.types.MuxStream(
key="audio-dash",
container="fmp4",
elementary_streams=["audio-stream0"],
),
],
manifests=[
transcoder_v1.types.Manifest(
file_name="manifest.m3u8",
type_="HLS",
mux_streams=["sd-hls"],
),
transcoder_v1.types.Manifest(
file_name="manifest.mpd",
type_="DASH",
mux_streams=["sd-dash", "audio-dash"],
),
],
)
response = client.create_job(parent=parent, job=job)
print(f"Job: {response.name}")
return response
¿Qué sigue?
Para buscar y filtrar muestras de código en otros productos de Google Cloud, consulta el navegador de muestra de Google Cloud.