Crea clips de VOD a partir de una transmisión en vivo

En esta página, se describe cómo crear clips de video on demand (VOD) a partir de una transmisión en vivo con la API de Live Stream. Los clips de VOD se componen de archivos de manifiesto HLS y archivos de segmentos que se guardaron de una transmisión en vivo. Solo se admiten manifiestos HLS.

Diferencias entre los clips de VOD y las sesiones de DVR

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

  • Sesiones de DVR:
    • La API guarda el manifiesto del DVR en la misma ubicación que los segmentos de la transmisión en vivo para que no se realicen copias adicionales en Cloud Storage. El manifiesto del DVR es similar al manifiesto de la transmisión en vivo, pero es más largo. Cuando vence la ventana de retención, se borra el manifiesto junto con los archivos de segmentos.
    • Puedes crear una sesión de DVR para contenido pasado, actual y futuro. Por ejemplo, una sesión de DVR puede seguir una transmisión en vivo, o bien puedes programar una sesión de DVR para que comience y se detenga en un momento futuro.
    • Un caso de uso típico para las sesiones de DVR es admitir las funciones de DVR para eventos de transmisión en vivo. Por ejemplo, un usuario puede unirse a la transmisión en vivo una hora después de que comienza y ver el contenido con una demora de una hora (o omitir partes de él).
  • Clips del canal:
    • La API de Live Stream copia el manifiesto del clip y los archivos de segmentos asociados a un directorio especificado por el usuario para que no se borren cuando venza la ventana de retención. Tienes el control total del clip.
    • Solo se puede recortar el contenido anterior. No se admiten clips en vivo ni la programación de clips futuros.
    • Un caso de uso típico de los clips es archivar una transmisión en vivo para que esté disponible como archivo de VOD de forma indefinida.

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

Configura el proyecto de Google Cloud y la autenticación

Si no creaste un proyecto de Google Cloud ni credenciales, consulta Antes de comenzar.

Crea un extremo de entrada

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

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_NUMBER: Es el número de tu proyecto de Google Cloud, que se encuentra en el campo Número de proyecto de la página Configuración de IAM.
  • LOCATION: Es la ubicación en la que se creará el extremo de entrada. Usa una de las regiones compatibles.
    Cómo 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: Es un identificador definido por el usuario para el nuevo extremo de entrada que se creará (al que envías tu flujo de entrada). Este valor debe tener entre 1 y 63 caracteres, comenzar y terminar con [a-z0-9], y puede contener guiones (-) entre los caracteres. Por ejemplo, my-input.

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "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 (LRO) que puedes usar para hacer un seguimiento del progreso de tu solicitud. Consulta Administra operaciones de larga duración para obtener más información.

Obtén detalles del extremo de entrada

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

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_NUMBER: Es el número de proyecto de Google Cloud, que se encuentra en el campo Número de proyecto de la página Configuración de IAM.
  • LOCATION: Es la ubicación en la que se encuentra el extremo de entrada. Usa una de las regiones compatibles.
    Cómo 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: Es el identificador definido por el usuario para el extremo de entrada.

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "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 INPUT_STREAM_URI que se muestra para usarlo más adelante en la sección Envía el flujo de entrada.

Crea un canal

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

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

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

Cuando se habilita la retención para un canal de transmisión en vivo, se retienen los segmentos y el manifiesto de la transmisión para crear clips de VOD. El objeto retentionWindowDuration especifica el tiempo durante el cual se guarda el resultado de la transmisión en vivo después de subirlo a Cloud Storage. El período de retención comienza en el momento en que se crea el segmento en Cloud Storage.

El período de retención es limitado a 30 días. Una vez que haya transcurrido la ventana de retención, los archivos de segmentos de la transmisión en vivo y el archivo de manifiesto se borrarán automáticamente de Cloud Storage. (El manifiesto de clips de VOD y sus archivos de segmentos asociados no se borran automáticamente). No puedes crear clips de VOD con segmentos borrados. 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 VOD. Te referirás a esta clave cuando crees el clip. Solo se admiten manifiestos HLS.

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

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_NUMBER: Es el número de proyecto de Google Cloud, que se encuentra en el campo Número de proyecto de la página Configuración de IAM.
  • LOCATION: Es la ubicación en la que se creará el canal. Usa una de las regiones compatibles.
    Cómo 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: Es un identificador definido por el usuario para el canal que se creará. Este valor debe tener entre 1 y 63 caracteres, comenzar y terminar con [a-z0-9], y puede contener guiones (-) entre los caracteres.
  • INPUT_ID: Es el identificador definido por el usuario para el extremo de entrada.
  • BUCKET_NAME: Es el nombre del bucket de Cloud Storage que creaste para contener el manifiesto y los archivos de segmentos de la transmisión en vivo.

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "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 (LRO) que puedes usar para hacer un seguimiento del progreso de tu solicitud. Consulta Administra operaciones de larga duración para obtener más información.

Inicia el canal

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

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_NUMBER: Es el número de proyecto de Google Cloud, que se encuentra en el campo Número de proyecto de la página Configuración de IAM.
  • LOCATION: Es la ubicación en la que se encuentra tu canal. Usa una de las regiones admitidas.
    Cómo 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: Es un identificador definido por el usuario para el canal.

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "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 (LRO) que puedes usar para hacer un seguimiento del progreso de tu solicitud. Consulta Administra operaciones de larga duración para obtener más información.

Envía el flujo de entrada

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

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

Cómo crear un clip de VOD

Para crear un clip de VOD, 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 bucket que creaste para el manifiesto de la transmisión en vivo o uno diferente. También puedes agregar un nombre de directorio al nombre del bucket (por ejemplo, my-bucket/vod-clip).

Usa el campo manifestKey en el array clipManifests para especificar el manifiesto desde el que se guardarán los clips. En la configuración de canales de ejemplo de esta página, esta clave se establece en manifest_hls.

Para combinar varias secciones de tiempo de la transmisión en vivo en un solo clip, agrega objetos timeSlice al array 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 superior del clip. Si la solicitud de creación de trabajos de clip se realiza correctamente, se muestra el URI del manifiesto de clip generado en el campo clipManifests.outputUri. Este URI se encuentra en la ruta de acceso especificada por el campo outputUri del clip.
  • El array clipManifests solo admite un manifiesto por solicitud. Si deseas generar varios manifiestos para el mismo trabajo de clip, debes dividirlos en varias solicitudes de trabajo de clip.
  • Las secciones de clip deben ser homogéneas; cada elemento debe 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 en cada timeSlice.
  • Si el markinTime más reciente de un clip es anterior a la hora de inicio del canal o al inicio de la ventana de retención, la hora de inserción se establece en la más reciente de las dos.
  • Si el markoutTime más reciente de un clip es posterior a la hora de detención del canal, se establece en la hora de detención del canal. Si el markoutTime más reciente de un clip es posterior a la hora del reloj del sistema actual, se establece en la hora en que la API inicia la tarea de recorte.
  • La duración máxima de un clip es de 24 horas.

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_NUMBER: Es el número de tu proyecto de Google Cloud, que se encuentra en el campo Número de proyecto de la página Configuración de IAM.
  • LOCATION: Es la ubicación en la que se encuentra tu canal. Usa una de las regiones admitidas.
    Cómo 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: Es un identificador definido por el usuario para el canal.
  • CLIP_ID: Es un identificador definido por el usuario para el clip de VOD.
  • MARK_IN_TIME: Es la marca de tiempo de época Unix en el manifiesto de transmisión en vivo original. Usa una marca de tiempo en formato RFC3339 UTC “Zulu” (por ejemplo, 2014-10-02T15:01:23Z).
  • MARK_OUT_TIME: Es la marca de tiempo de época Unix en el manifiesto de transmisión en vivo original. Usa una marca de tiempo en formato RFC3339 UTC “Zulu” (por ejemplo, 2014-10-02T15:01:23Z).
  • BUCKET_NAME: Es el nombre del bucket de Cloud Storage que creaste para contener el manifiesto de clips de VOD y los archivos de segmentos. Puedes usar el mismo bucket que creaste para el manifiesto de transmisión en vivo o uno diferente. También puedes agregar un nombre de directorio al nombre del bucket (por ejemplo, my-bucket/vod-clip).

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "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 (LRO) que puedes usar para hacer un seguimiento del progreso de tu solicitud. Consulta Administra operaciones de larga duración para obtener más información.

Cómo obtener el clip de VOD

Para obtener un clip de VOD, usa el método projects.locations.channels.clips.get.

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • PROJECT_NUMBER: Es el número de proyecto de Google Cloud, que se encuentra en el campo Número de proyecto de la página Configuración de IAM.
  • LOCATION: Es la ubicación en la que se encuentra tu canal. Usa una de las regiones admitidas.
    Cómo 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: Es un identificador definido por el usuario para el canal.
  • CLIP_ID: Es un identificador definido por el usuario para el clip de VOD.

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "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 del archivo del manifiesto es el mismo que el valor del campo manifests.fileName del canal superior.

La respuesta debe contener lo siguiente:

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

Solo los 1,000 registros de trabajos de clips más recientes por canal están disponibles con el método projects.locations.channels.clips.get. Se quitarán los registros de trabajos de clip que sean anteriores al límite. Debes administrar los archivos de clip generados que especifica outputUri. La API de Live Stream no borra estos archivos de Cloud Storage.

Verifica el contenido del bucket

Abre el bucket de Cloud Storage como se especifica en el campo outputUri del clip. Verifica 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 en línea.
  • Un directorio para cada muxStreams.key especificado en el canal (por ejemplo, mux_video_ts)
    • Una playlist para el clip (por ejemplo, index-1.m3u8)
    • Un directorio con el nombre en el formato YYYYMMDDTHHMMSSZ (por ejemplo, 20220708T203309Z/). Este directorio contiene los segmentos de clips de VOD.
      • Varios archivos segment-number.ts de segmentos que conforman el clip de VOD

Reproducir el clip de VOD

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

  1. Configura el bucket de Cloud Storage para que sea legible de forma pública.
  2. Para habilitar el uso compartido de recursos multiorigen (CORS) en un depósito de Cloud Storage, haz lo siguiente:
    1. Crea un archivo JSON que contenga la siguiente información:
      [
        {
          "origin": ["https://shaka-player-demo.appspot.com/"],
          "responseHeader": ["Content-Type", "Range"],
          "method": ["GET", "HEAD"],
          "maxAgeSeconds": 3600
        }
      ]
    2. Ejecuta el siguiente comando después de reemplazar JSON_FILE_NAME por el nombre del archivo JSON que creaste en el paso anterior:
      gcloud storage buckets update gs://BUCKET_NAME --cors-file=JSON_FILE_NAME.json
  3. En el bucket de Cloud Storage, busca el archivo generado. Haz clic en Copiar URL en la columna Acceso público del archivo.
  4. Navega a Shaka Player, un reproductor en línea de transmisión en vivo.
  5. Haz clic en Contenido personalizado en la barra de navegación superior.
  6. Haz clic en el botón +.
  7. Pega la URL pública del archivo en la casilla URL del manifiesto.

  8. Escribe un nombre en el cuadro Nombre.

  9. Haz clic en Guardar.

  10. Haz clic en Reproducir.

Deberías ver que un patrón de prueba se reproduce como la transmisión en vivo.

Video del patrón de prueba

Eventos de pausa publicitaria y cortinilla

Si creaste un evento de pausa publicitaria para la transmisión en vivo, los clips de VOD no contendrán los anuncios. La API genera una playlist con los puntos de pausa de anuncios reemplazados por las siguientes etiquetas:

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

Las cortinillas que aparecen al principio o al final del clip de VOD se quitan automáticamente. Las cortinillas que aparecen en la transmisión, rodeadas por el contenido de la transmisión en vivo, se conservan en el clip de VOD generado.