Crear clips de VOD a partir de una emisión en directo

En esta página se describe cómo crear clips de vídeo bajo demanda (VOD) a partir de una emisión en directo mediante la API Live Stream. Los clips de vídeo bajo demanda se componen de archivos de manifiesto HLS y archivos de segmento que se han guardado de una emisión en directo. Solo se admiten manifiestos HLS.

Diferencias entre los clips de vídeo bajo demanda y las sesiones de DVR

Los clips de VOD (también conocidos como "clips de canal") son similares a las sesiones de DVR, pero con las siguientes diferencias clave:

  • Sesiones de DVR:
    • La API guarda el manifiesto de DVR en la misma ubicación que los segmentos de la emisión en directo, por lo que no es necesario copiarlo en Cloud Storage. El archivo de manifiesto de la grabación de vídeo es similar al de la emisión en directo, pero más largo. Cuando caduca el periodo de conservación, el manifiesto se elimina junto con los archivos de segmento.
    • Puedes crear una sesión de grabación para contenido pasado, actual y futuro. Por ejemplo, una sesión de DVR puede seguir a una emisión en directo o puedes programar una sesión de DVR para que empiece y termine en un momento posterior.
    • Un caso de uso habitual de las sesiones de DVR es admitir las funciones de DVR en eventos de streaming en directo. Por ejemplo, un usuario puede unirse a la emisión en directo una hora después de que empiece y ver el contenido con una hora de retraso (o saltarse partes).
  • Clips del canal:
    • La API Live Stream copia el manifiesto del clip y los archivos de segmento asociados en un directorio especificado por el usuario para que no se eliminen cuando caduque el periodo de conservación. Tienes control total sobre el clip.
    • Solo se puede recortar el contenido anterior. No se admiten los clips en directo ni la programación de clips futuros.
    • Un caso de uso habitual de los clips es archivar una emisión en directo para que esté disponible como archivo de vídeo bajo demanda indefinidamente.

Para obtener más información sobre las sesiones de DVR, consulta Crear una sesión de DVR.

Configurar el Google Cloud proyecto y la autenticación

Si no has creado un Google Cloud proyecto y credenciales, consulta la sección Antes de empezar.

Crear un endpoint de entrada

Para crear un endpoint de entrada, usa el método projects.locations.inputs.create.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • PROJECT_NUMBER: número de tu proyecto. Google Cloud Se encuentra en el campo Número de proyecto de la página Configuración de gestión de identidades y accesos.
  • LOCATION: ubicación en la que se creará el punto final de entrada. Usa una de las regiones admitidas.
    Mostrar ubicaciones
    • us-central1
    • us-east1
    • us-east4
    • us-west1
    • us-west2
    • northamerica-northeast1
    • southamerica-east1
    • asia-east1
    • asia-east2
    • asia-south1
    • asia-northeast1
    • asia-southeast1
    • australia-southeast1
    • europe-north1
    • europe-west1
    • europe-west2
    • europe-west3
    • europe-west4
  • INPUT_ID: identificador definido por el usuario del nuevo endpoint de entrada que se va a crear (al que se envía el flujo de entrada). Este valor debe tener entre 1 y 63 caracteres, empezar y terminar con [a-z0-9], y puede incluir guiones (-) entre caracteres. Por ejemplo, my-input.

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
    "createTime": CREATE_TIME,
    "target": "projects/PROJECT_NUMBER/locations/LOCATION/inputs/INPUT_ID",
    "verb": "create",
    "requestedCancellation": false,
    "apiVersion": "v1"
  },
  "done": false
}

Este comando crea una operación de larga duración (OLD) que puedes usar para monitorizar el progreso de tu solicitud. Consulta más información en el artículo sobre cómo gestionar operaciones de larga duración .

Obtener detalles de un endpoint de entrada

Para obtener los detalles del endpoint de entrada, utiliza el método projects.locations.inputs.get.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • PROJECT_NUMBER: número de tu proyecto. Google Cloud Se encuentra en el campo Número de proyecto de la página Configuración de gestión de identidades y accesos.
  • LOCATION: la ubicación de tu endpoint de entrada. Usa una de las regiones admitidas.
    Mostrar ubicaciones
    • us-central1
    • us-east1
    • us-east4
    • us-west1
    • us-west2
    • northamerica-northeast1
    • southamerica-east1
    • asia-east1
    • asia-east2
    • asia-south1
    • asia-northeast1
    • asia-southeast1
    • australia-southeast1
    • europe-north1
    • europe-west1
    • europe-west2
    • europe-west3
    • europe-west4
  • INPUT_ID: identificador definido por el usuario del endpoint de entrada

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/inputs/INPUT_ID",
  "createTime": CREATE_TIME,
  "updateTime": UPDATE_TIME,
  "type": "RTMP_PUSH",
  "uri":  "INPUT_STREAM_URI", # For example, "rtmp://1.2.3.4/live/b8ebdd94-c8d9-4d88-a16e-b963c43a953b",
  "tier": "HD"
}

Busca el campo uri y copia el valor devuelto INPUT_STREAM_URI para usarlo más adelante en la sección Enviar el flujo de entrada.

Crear canales

Para crear un canal, usa el método projects.locations.channels.create. En los siguientes ejemplos se crea un canal que genera una emisión en directo HLS. La emisión en directo consta de una sola versión en alta definición (1280x720).

Para habilitar la creación de clips de VOD, añade el objeto retentionConfig a la configuración del canal.

"retentionConfig": {
  "retentionWindowDuration": {
      "seconds": 86400
    }
},

Cuando la retención está habilitada en un canal de emisión en directo, los segmentos y el archivo de manifiesto de la emisión se conservan para crear clips de vídeo bajo demanda. El objeto retentionWindowDuration especifica el tiempo durante el que se guarda la salida de la emisión en directo después de subirse a Cloud Storage. El periodo de retención comienza en el momento en que se crea el segmento en Cloud Storage.

La ventana de conservación está limitada a 30 días. Una vez que haya transcurrido el periodo de conservación, los archivos de segmento de la emisión en directo y el archivo de manifiesto se eliminarán automáticamente de Cloud Storage. El manifiesto del clip de VOD y sus archivos de segmento asociados no se eliminan automáticamente. No puedes crear clips de vídeo bajo demanda con segmentos eliminados. El proceso de eliminación es asíncrono y puede tardar hasta 24 horas en completarse.

Especifica una clave para el manifiesto para habilitar la creación de clips de vídeo bajo demanda. Esta clave se utiliza al crear el clip. Solo se admiten manifiestos HLS.

"manifests": [
{
  ...
  "key": "manifest_hls"
}

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • PROJECT_NUMBER: número de tu proyecto. Google Cloud Se encuentra en el campo Número de proyecto de la página Configuración de gestión de identidades y accesos.
  • LOCATION: la ubicación en la que se creará el canal. Usa una de las regiones admitidas.
    Mostrar ubicaciones
    • us-central1
    • us-east1
    • us-east4
    • us-west1
    • us-west2
    • northamerica-northeast1
    • southamerica-east1
    • asia-east1
    • asia-east2
    • asia-south1
    • asia-northeast1
    • asia-southeast1
    • australia-southeast1
    • europe-north1
    • europe-west1
    • europe-west2
    • europe-west3
    • europe-west4
  • CHANNEL_ID: identificador definido por el usuario del canal que se va a crear. Este valor debe tener entre 1 y 63 caracteres, empezar y terminar con [a-z0-9], y puede contener guiones (-) entre caracteres.
  • INPUT_ID: identificador definido por el usuario del endpoint de entrada
  • BUCKET_NAME: el nombre del segmento de Cloud Storage que has creado para alojar el manifiesto de la emisión en directo y los archivos de segmento

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
    "createTime": CREATE_TIME,
    "target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID",
    "verb": "create",
    "requestedCancellation": false,
    "apiVersion": "v1"
  },
  "done": false
}

Este comando crea una operación de larga duración (OLD) que puedes usar para monitorizar el progreso de tu solicitud. Consulta más información en el artículo sobre cómo gestionar operaciones de larga duración .

Iniciar el canal

Para iniciar un canal, utiliza el método projects.locations.channels.start.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • PROJECT_NUMBER: número de tu proyecto. Google Cloud Se encuentra en el campo Número de proyecto de la página Configuración de gestión de identidades y accesos.
  • LOCATION: la ubicación de tu canal. Elige una de las regiones admitidas.
    Mostrar ubicaciones
    • us-central1
    • us-east1
    • us-east4
    • us-west1
    • us-west2
    • northamerica-northeast1
    • southamerica-east1
    • asia-east1
    • asia-east2
    • asia-south1
    • asia-northeast1
    • asia-southeast1
    • australia-southeast1
    • europe-north1
    • europe-west1
    • europe-west2
    • europe-west3
    • europe-west4
  • CHANNEL_ID: identificador definido por el usuario del canal

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
    "createTime": CREATE_TIME,
    "target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID",
    "verb": "start",
    "requestedCancellation": false,
    "apiVersion": "v1"
  },
  "done": false
}

Este comando crea una operación de larga duración (OLD) que puedes usar para monitorizar el progreso de tu solicitud. Consulta más información en el artículo sobre cómo gestionar operaciones de larga duración .

Enviar el flujo de entrada

Abre una nueva ventana de terminal. Ejecuta el siguiente comando con INPUT_STREAM_URI de la sección Obtener detalles del endpoint de entrada:

ffmpeg -re -f lavfi -i "testsrc=size=1280x720 [out0]; sine=frequency=500 [out1]" \
  -acodec aac -vcodec h264 -f flv INPUT_STREAM_URI

Crear un clip de VOD

Para crear un clip de vídeo bajo demanda, usa el método projects.locations.channels.clips.create.

Usa el campo outputUri para especificar la ubicación en la que se guardarán los clips y el archivo de manifiesto de clips en Cloud Storage. Puedes usar el mismo segmento que creaste para el archivo de manifiesto de la emisión en directo u otro. También puedes añadir un nombre de directorio al nombre del contenedor (por ejemplo, my-bucket/vod-clip).

Usa el campo manifestKey de la matriz clipManifests para especificar el manifiesto desde el que se guardarán los clips. En el ejemplo de configuración de canal de esta página, esta clave tiene el valor manifest_hls.

Usa el campo outputType para especificar uno de los formatos de salida de clip admitidos: MANIFEST (predeterminado) o MP4. En la configuración de canal de ejemplo de esta página, este campo tiene el valor MANIFEST, que genera un manifiesto de VOD similar al de la salida del canal.

Puedes combinar varias secciones de tiempo de la emisión en directo en un solo clip añadiendo objetos timeSlice a la matriz slices.

"outputUri": "gs://my-bucket",
"clipManifests":[
  {
    "manifestKey": "manifest_hls"
  }
],
"slices":[
  {
    "timeSlice": {
      "markinTime": "2022-07-08T23:03:20.000Z",
      "markoutTime": "2022-07-08T23:04:20.000Z"
    }
  },
  {
    "timeSlice": {
      "markinTime": "2022-07-08T23:05:20.000Z",
      "markoutTime": "2022-07-08T23:06:20.000Z"
    }
  }
]

Ten en cuenta lo siguiente:

  • Cada clip debe contener al menos un timeSlice en slices.
  • El campo clipManifests.manifestKey debe hacer referencia a un manifiesto HLS definido en el canal principal del clip. Si la solicitud de creación del trabajo de clip se realiza correctamente, el URI del archivo de manifiesto del clip generado se devuelve en el campo clipManifests.outputUri. Este URI se encuentra en la ruta especificada por el campo outputUri del clip.
  • La matriz clipManifests solo admite un archivo de manifiesto por solicitud. Si quieres generar varios manifiestos para el mismo trabajo de recorte, debes dividir los manifiestos en varias solicitudes de trabajo de recorte.
  • Los segmentos de clip deben ser homogéneos. Todos los elementos deben ser del tipo timeSlice.
  • El conjunto de objetos timeSlice no debe superponerse y debe estar en orden cronológico. El markinTime debe ser anterior al markoutTime de cada timeSlice.
  • Si el markinTime más reciente de un clip es anterior a la hora de inicio del canal o al inicio del periodo de conservación, la hora de entrada se establece en la más reciente de las dos.
  • Si el último markoutTime de un clip es posterior a la hora de finalización del canal, se establece la hora de finalización del canal. Si el último markoutTime de un clip es posterior a la hora actual del reloj del sistema, se establece la hora en la que la API inicia la tarea de recorte.
  • En el caso de los clips con el tipo de salida MANIFEST, la duración máxima es de 24 horas. En el caso de los clips con el tipo de salida MP4, la duración máxima es de 6 horas.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • PROJECT_NUMBER: número de tu proyecto. Google Cloud Se encuentra en el campo Número de proyecto de la página Configuración de gestión de identidades y accesos.
  • LOCATION: la ubicación de tu canal. Elige una de las regiones admitidas.
    Mostrar ubicaciones
    • us-central1
    • us-east1
    • us-east4
    • us-west1
    • us-west2
    • northamerica-northeast1
    • southamerica-east1
    • asia-east1
    • asia-east2
    • asia-south1
    • asia-northeast1
    • asia-southeast1
    • australia-southeast1
    • europe-north1
    • europe-west1
    • europe-west2
    • europe-west3
    • europe-west4
  • CHANNEL_ID: identificador definido por el usuario del canal
  • CLIP_ID: identificador definido por el usuario del clip de VOD.
  • MARK_IN_TIME: marca de tiempo de inicio de la época de Unix en el manifiesto de la emisión en directo original. Usa una marca de tiempo en formato RFC3339 UTC "Zulu" (por ejemplo, 2014-10-02T15:01:23Z).
  • MARK_OUT_TIME: hora de inicio de la marca de tiempo de Unix en el manifiesto de la emisión en directo original. Usa una marca de tiempo en formato RFC3339 UTC "Zulu" (por ejemplo, 2014-10-02T15:01:23Z).
  • BUCKET_NAME: el nombre del segmento de Cloud Storage que has creado para alojar el manifiesto del clip de VOD y los archivos de segmento. Puedes usar el mismo segmento que has creado para el manifiesto de la emisión en directo u otro segmento. También puedes añadir un nombre de directorio al nombre del segmento (por ejemplo, my-bucket/vod-clip).

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
    "createTime": CREATE_TIME,
    "target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID/clips/CLIP_ID",
    "verb": "create",
    "requestedCancellation": false,
    "apiVersion": "v1"
  },
  "done": false
}

Este comando crea una operación de larga duración (OLD) que puedes usar para monitorizar el progreso de tu solicitud. Consulta más información en el artículo sobre cómo gestionar operaciones de larga duración .

Obtener el clip de VOD

Para obtener un clip de vídeo bajo demanda, usa el método projects.locations.channels.clips.get.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • PROJECT_NUMBER: número de tu proyecto. Google Cloud Se encuentra en el campo Número de proyecto de la página Configuración de gestión de identidades y accesos.
  • LOCATION: la ubicación de tu canal. Elige una de las regiones admitidas.
    Mostrar ubicaciones
    • us-central1
    • us-east1
    • us-east4
    • us-west1
    • us-west2
    • northamerica-northeast1
    • southamerica-east1
    • asia-east1
    • asia-east2
    • asia-south1
    • asia-northeast1
    • asia-southeast1
    • australia-southeast1
    • europe-north1
    • europe-west1
    • europe-west2
    • europe-west3
    • europe-west4
  • CHANNEL_ID: identificador definido por el usuario del canal
  • CLIP_ID: identificador definido por el usuario del clip de VOD.

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID/clips/CLIP_ID",
  "createTime": CREATE_TIME,
  "startTime": START_TIME,
  "updateTime": UPDATE_TIME,
  "state": "SUCCEEDED",
  "outputUri": "gs://BUCKET_NAME",
  "slices": [
    {
      "timeSlice": {
        "markinTime": "MARK_IN_TIME",
        "markoutTime": "MARK_OUT_TIME"
      }
    }
  ],
  "features": {},
  "clipManifests": [
    {
      "manifestKey": "manifest_hls",
      "outputUri": "gs://BUCKET_NAME/main.m3u8"
    }
  ]
}

El manifiesto generado se encuentra en el URI especificado en el campo clipManifests.outputUri. El nombre de archivo del manifiesto es el mismo que el valor del campo manifests.fileName del canal principal.

La respuesta debe contener lo siguiente:

{
  ...
  "state": "SUCCEEDED"
  ...
}

Solo se pueden obtener los 1000 registros de trabajos de clips más recientes por canal con el método projects.locations.channels.clips.get. Se eliminan los registros de trabajos de clips que superen el límite. Debes gestionar los archivos de clip generados especificados por outputUri, ya que la Live Stream API no elimina estos archivos de Cloud Storage.

Verificar el contenido del segmento

Abre el segmento de Cloud Storage especificado en el campo outputUri del clip. Comprueba que contenga los siguientes archivos y directorios:

  • Un manifiesto de nivel superior para el clip con el mismo nombre que el manifests.fileName especificado en la configuración del canal (por ejemplo, main.m3u8). Puedes reproducir este manifiesto con un reproductor multimedia online.
  • Un directorio para cada muxStreams.key especificado en el canal (por ejemplo, mux_video_ts)
    • Una lista de reproducción para el clip (por ejemplo, index-1.m3u8)
    • Un directorio con el formato YYYYMMDDTHHMMSSZ (por ejemplo, 20220708T203309Z/). Este directorio contiene los segmentos del clip de vídeo bajo demanda.
      • Varios archivos segment-number.ts que componen el clip de VOD

Reproducir el clip de VOD

Para reproducir el archivo multimedia generado en Shaka Player, sigue estos pasos:

  1. Haz que el segmento de Cloud Storage que has creado se pueda leer públicamente.
  2. Para habilitar el uso compartido de recursos entre dominios (CORS) en un segmento de Cloud Storage, sigue estos pasos:
    1. Crea un archivo JSON que contenga lo siguiente:
      [
        {
          "origin": ["https://shaka-player-demo.appspot.com/"],
          "responseHeader": ["Content-Type", "Range"],
          "method": ["GET", "HEAD"],
          "maxAgeSeconds": 3600
        }
      ]
    2. Ejecuta el siguiente comando después de sustituir JSON_FILE_NAME por el nombre del archivo JSON que has creado en el paso anterior:
      gcloud storage buckets update gs://BUCKET_NAME --cors-file=JSON_FILE_NAME.json
  3. En el segmento de Cloud Storage, busca el archivo generado. En la columna Acceso público del archivo, haz clic en Copiar URL.
  4. Ve a Shaka Player, un reproductor de emisiones en directo online.
  5. En la barra de navegación superior, haga clic en Contenido personalizado.
  6. Haz clic en el botón +.
  7. Pega la URL pública del archivo en el cuadro URL del manifiesto.

  8. Escribe un nombre en el cuadro Nombre.

  9. Haz clic en Guardar.

  10. Haz clic en Reproducir.

Deberías ver una carta de ajuste como emisión en directo.

Vídeo de carta de ajuste

Eventos de pausas publicitarias y de pases

Si creaste un evento de pausa publicitaria para la emisión en directo, los clips de vídeo bajo demanda no contendrán los anuncios. La API genera una lista de reproducción con los puntos de interrupción de los anuncios sustituidos por las siguientes etiquetas:

#EXT-X-CUE-OUT: AD_BREAK_DURATION
#EXT-X-CUE-IN

Las pizarras que aparecen al principio o al final del clip de vídeo bajo demanda se eliminan automáticamente. Las pizarras que aparecen en la emisión, rodeadas del contenido de la emisión en directo, se conservan en el clip de vídeo bajo demanda generado.