1. Introducción
Las redes de distribución de contenidos (CDN) mejoran el rendimiento del usuario almacenando en caché el contenido al que se accede con frecuencia más cerca de los usuarios finales, finalizando las conexiones más cerca de los clientes, reutilizando las conexiones al origen y adoptando protocolos y personalizaciones de redes modernos. Para los usuarios (y nuestros clientes), esto significa una menor latencia, más confiabilidad y costos reducidos, lo que genera mejores ventas, una mejor experiencia web y un aumento neto en la experiencia del usuario. Hoy en día, muy pocos sitios y plataformas de transmisión de video modernos operan sin una CDN.
Qué aprenderás
En este lab, se explicarán los pasos para implementar un entorno de flujo de trabajo de transmisión en vivo con Media CDN (CDN) + API de Cloud Media Live Streaming (transcodificación de video en vivo) + Cloud Storage (almacenamiento para los videos) + Reproductor de video (VLC, Google Shaka Player, etc., reproductor listo para HLS y MPEG-DASH).
Configuraremos los componentes de la API de Live Streaming (entrada y canal) y comenzaremos un feed en vivo para la entrada o el canal con FFmpeg (FFmpeg puede generar una señal de prueba en vivo). La API de Live Streaming transcodificará el feed en vivo. El manifiesto y los segmentos de video transcodificados se almacenarán en un bucket de Cloud Storage. Luego, configuraremos Media CDN con el bucket de Cloud Storage de video en vivo como origen. Por último, se usará el reproductor VLC para reproducir el contenido en vivo almacenado en caché a través de Media CDN. También configuraremos un panel de Cloud Monitoring para visualizar la actividad de Media CDN.
Qué compilarás
En este lab, configuraremos el entorno según la siguiente arquitectura:

Configuraremos los siguientes componentes y realizaremos las siguientes tareas como parte del lab:
- Crea un bucket de Google Cloud Storage (GCS) para almacenar los videos transcodificados en vivo
- Configura la API de Live Streaming para transcodificar el video a varios formatos: HLS + MPEG DASH, SD y HD
- Configura los componentes de transmisión en vivo: Input/Channel
- Cómo iniciar el canal de transmisión en vivo
- Configura Media CDN con el bucket de GCS como origen
- Configura FFmpeg para que transmita el canal en vivo
- Transmite el feed en vivo transcodificado con un reproductor de video
- Configura un panel de Cloud Monitoring para supervisar la actividad de Media CDN (latencia, aciertos de caché, errores de caché, etcétera).
Nota: Para este lab, suponemos que los usuarios tienen acceso a la consola de Google Cloud y ya tienen un proyecto configurado. También suponemos que los usuarios comienzan con un entorno nuevo y no tienen nada configurado para esta demostración.
Todas las acciones de configuración se realizarán a través de la línea de comandos en Cloud Shell. Siempre podemos verificar los componentes configurados a través de la línea de comandos en la consola. A lo largo del lab, verás punteros que te indicarán dónde encontrar la consola de Google Cloud.
2. Antes de comenzar
El acceso a Media CDN está restringido. Para obtener acceso a Media CDN, comunícate con tu equipo de cuentas. Pueden crear una solicitud de acceso en tu nombre. Si formas parte de Google y quieres probar la transmisión en vivo con Media CDN, comunícate con el APM de Media CDN para solicitar acceso a Media CDN.
3. Configuración y requisitos
Inicia Cloud Shell
Si bien Google Cloud y Spanner se pueden operar de manera remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.
En Google Cloud Console, haz clic en el ícono de Cloud Shell en la barra de herramientas en la parte superior derecha:

El aprovisionamiento y la conexión al entorno deberían tomar solo unos minutos. Cuando termine el proceso, debería ver algo como lo siguiente:

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Todo tu trabajo en este codelab se puede hacer en un navegador. No es necesario que instales nada.
4. Versión del SDK de Google Cloud
En el momento de la redacción, 408.0.0 es la versión más reciente del SDK de Google Cloud. Todos los comandos de este lab se probaron con la versión más reciente del SDK de Google Cloud. Antes de continuar, asegúrate de que Cloud Shell use la versión más reciente del SDK.
Cómo verificar la versión del SDK
Usaremos el comando gcloud version para verificar la versión del SDK.
Comando
gcloud version | grep "Google Cloud SDK"
Ejemplo de resultado
Google Cloud SDK 408.0.0
Próximos pasos
- Si la versión del SDK es
408.0.0o posterior, pasa a la siguiente sección. - Si la versión del SDK es inferior a
408.0.0, ejecuta el siguiente comando para actualizar el SDK.
sudo apt-get update && sudo apt-get install google-cloud-sdk
5. Requisitos previos
Antes de comenzar a configurar los recursos de GCP, debemos hacer lo siguiente:
- Configura variables de entorno
- Habilita las APIs de servicio obligatorias
1. Configura variables de entorno
A lo largo de este lab, ejecutaremos comandos gcloud y curl con algunas variables. Debemos configurar las siguientes variables de entorno.
- ID del proyecto
- Número del proyecto
- Nombre del usuario
- Región
- ID de entrada
- ID del canal
ID del proyecto y nombre de usuario
Por lo general, estas variables de entorno están preconfiguradas en Cloud Shell. Usaremos el comando env para verificarlo.
Comando
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME'
Ejemplo de resultado
DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME>
Crea el archivo env_variables
Usa el comando cat para crear el archivo env_variables.txt. El siguiente comando creará el archivo env_variables.txt en el directorio principal del usuario.
Comandos
cat > ~/env_variables.txt << EOF export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)") export LOCATION=us-west2 export INPUT_ID=lab-live-input export CHANNEL_ID=lab-live-channel EOF
Configura las variables de entorno
Usaremos el comando source para establecer las variables de entorno.
Comando
source ~/env_variables.txt
Verifica que las variables estén configuradas
Verifiquemos que todas las variables de entorno necesarias estén configuradas. Deberíamos ver un total de 6 variables de entorno en el resultado.
Comando
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
Ejemplo de resultado
LOCATION=us-west2 DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME> PROJECT_NUMBER=<YOUR_PROJECT_NUMBER> INPUT_ID=lab-live-input CHANNEL_ID=lab-live-channel
2. Habilita las APIs de servicio obligatorias
Debemos asegurarnos de que las siguientes APIs estén habilitadas en nuestro proyecto.
- API de servicios de red
- API de Certificate Manager
- API de Livestream
- API de caché perimetral de Media CDN
Habilita la API de Network Services
Para habilitar la API de Network Services, ejecuta el siguiente comando:
Comando
gcloud services enable networkservices.googleapis.com
Habilita la API de Certificate Manager
Para habilitar el certificado de la API de Management, ejecuta el siguiente comando:
Comando
gcloud services enable certificatemanager.googleapis.com
Habilita la API de Live Stream
Para habilitar la API de Live Stream, ejecuta el siguiente comando:
Comando
gcloud services enable livestream.googleapis.com
Habilita la API de Media CDN Edge Cache
Para habilitar la API de Media CDN Edge Cache, ejecuta el siguiente comando:
Comando
gcloud services enable edgecache.googleapis.com
Verifica que las APIs estén habilitadas
Ejecuta el comando gcloud services list para enumerar todas las APIs habilitadas. Deberíamos ver 4 APIs en el resultado.
Comando
gcloud services list | grep -E 'networkservices|certificatemanager|livestream|edgecache'
Ejemplo de resultado
NAME: certificatemanager.googleapis.com NAME: livestream.googleapis.com NAME: networkservices.googleapis.com NAME: edgecache.googleapis.com
6. Crea el bucket de Cloud Storage
En esta sección, haremos lo siguiente:
- Cree un bucket de Cloud Storage
- Permite el acceso público al bucket
Más adelante en el lab, usaremos este bucket para almacenar los archivos de video transcodificados. Este bucket también actuará como almacenamiento de origen para el servicio de Media CDN.
1. Crea un bucket
Usaremos el comando gsutil mb para crear el bucket:
Comando
gsutil mb gs://live-streaming-storage-$LOGNAME
2. Permite el acceso público al bucket
Usaremos el comando gsutil iam para que los archivos estén disponibles de forma pública:
Comando
gsutil iam ch allUsers:objectViewer gs://live-streaming-storage-$LOGNAME
7. Cómo configurar el entorno de la API de Live Streaming
Los componentes de la cadena de la API de Live Streaming se diseñaron de la siguiente manera:

Creamos el bucket de Cloud Storage live-streaming-storage-$LOGNAME en la sección anterior. En las próximas dos secciones, crearemos los siguientes recursos:
- Entrada de transmisión en vivo: Un extremo de entrada es un extremo al que tu codificador envía tu transmisión de entrada. Puedes usar el extremo de entrada para especificar la configuración de tu transmisión, como la resolución de entrada, el tipo de entrada y el recorte de video.
- Canal de transmisión en vivo: Un canal es un recurso que transfiere la transmisión de entrada a través de un extremo de entrada, transcodifica la transmisión de entrada en múltiples versiones y publica transmisiones en vivo de salida en ciertos formatos en la ubicación especificada. Puedes incluir una transmisión de entrada principal y una de copia de seguridad en el mismo canal.
Más adelante en el lab, crearemos los siguientes recursos:
- Codificador: Un codificador es un programa que se usa para enviar transmisiones de entrada. En este lab, usaremos FFmpeg.
8. Crea y configura el extremo de entrada
Crea el archivo input.json
Crearemos un archivo input.json para especificar el tipo de señal de transmisión en vivo. En este lab, usaremos el canal en vivo de RTMP.
Comando
cat > input.json << EOF
{
"type": "RTMP_PUSH"
}
EOF
Crea el extremo de entrada
En el momento de escribir este lab, no hay compatibilidad con gcloud para la API de Live Stream. Usaremos el comando curl para realizar las llamadas a la API.
Comando
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d @input.json \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs?inputId=$INPUT_ID"
Ejemplo de resultado
{
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T05:39:32.884030164Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
El resultado tiene mucha información útil, pero, en este momento, debemos enfocarnos en dos campos:
- ID de operación: Copia y anota el ID de operación del resultado. A continuación, se muestra el ID de operación del ejemplo de salida. Puedes encontrarlo en la línea de salida que comienza con
"name"."operation-1661405972853-5e70a38d6f27f-79100d00-310671b4" - Estado: Debemos esperar a que el estado cambie de
"done": falsea"done": true
Verifica el estado
Antes de continuar, debemos verificar que el extremo de entrada se haya creado correctamente y esté listo.
En el siguiente comando, reemplaza <OPERATION> por el ID de la operación que acabamos de obtener. En este ejemplo, es "operation-1661405972853-5e70a38d6f27f-79100d00-310671b4".
Comando
export OPERATION_ID_1=<OPERATION>
Comando
curl -X GET \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/operations/$OPERATION_ID_1"
Ejemplo de resultado
{
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661408816982-5e70ae25cea49-617844f0-8fdcb4a1",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T06:26:57.001530499Z",
"endTime": "2022-08-25T06:26:57.043623522Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.Input",
"name": "projects/PROJECT_ID/locations/us-west2/inputs/lab-live-input",
"createTime": "2022-08-25T06:26:56.997623672Z",
"updateTime": "2022-08-25T06:26:56.997623672Z",
"type": "RTMP_PUSH",
"uri": "rtmp://34.94.97.220/live/4b7846a1-4a67-44ed-bfd0-d98281b6464a",
"tier": "HD"
}
}
Vuelve a ejecutar el comando hasta que veas "done:true", que indica que se creó el extremo de entrada y está listo.
Cómo guardar el URI
Usaremos el URI del resultado anterior más adelante en el lab. En este momento, estableceremos una variable de entorno para URI.
Comando
export URI=<uri>
Reemplaza <uri> por el URI que acabas de anotar. De manera opcional, también puedes usar el método GET para recuperar el URI.
Comando
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID" | jq .uri
9. Crea y configura el canal de transmisión en vivo
Creemos el canal de transmisión en vivo, asociado al extremo de entrada que acabamos de crear en la sección anterior. En el siguiente ejemplo, se crea un canal que genera una transmisión en vivo HLS que consta de una sola representación en alta definición (1280 x 720). El canal se asociará con el extremo de entrada y el bucket de almacenamiento que creamos anteriormente.
Crea el archivo channel.json
En la terminal de Cloud Shell, escribe el siguiente comando para crear un archivo "channel.json":
Comando
cat > channel.json << EOF
{
"inputAttachments": [
{
"key": "my-input",
"input": "projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID"
}
],
"output": {
"uri": "gs://live-streaming-storage-$LOGNAME"
},
"elementaryStreams": [
{
"key": "es_video",
"videoStream": {
"h264": {
"profile": "high",
"widthPixels": 1280,
"heightPixels": 720,
"bitrateBps": 3000000,
"frameRate": 30
}
}
},
{
"key": "es_audio",
"audioStream": {
"codec": "aac",
"channelCount": 2,
"bitrateBps": 160000
}
}
],
"muxStreams": [
{
"key": "mux_video_ts",
"container": "ts",
"elementaryStreams": ["es_video", "es_audio"],
"segmentSettings": { "segmentDuration": "2s" }
}
],
"manifests": [
{
"fileName": "main.m3u8",
"type": "HLS",
"muxStreams": [
"mux_video_ts"
],
"maxSegmentCount": 5
}
]
}
EOF
Crea el canal
Ejecuta el siguiente comando curl para crear el canal:
Comando
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d @channel.json \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels?channelId=$CHANNEL_ID"
Ejemplo de resultado
{
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T05:39:32.884030164Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
Anota y copia el ID de operación. La necesitaremos en uno de los próximos pasos. Puedes encontrarlo en la línea de salida que comienza con "name".
Verifica el estado
Antes de continuar, debemos verificar que el canal se haya creado correctamente y esté listo.
En el siguiente comando, reemplaza <OPERATION> por el ID de la operación que acabamos de obtener. En este ejemplo, es operation-1661405972853-5e70a38d6f27f-79100d00-310671b4.
Comando
export OPERATION_ID_2=<OPERATION>
Comando
curl -s -X GET \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/operations/$OPERATION_ID_2"
Ejemplo de resultado
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1668666801461-5eda4c3f31852-a4d2229f-0efeef9e",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-11-17T06:33:21.500841488Z",
"endTime": "2022-11-17T06:33:21.529311112Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.Channel",
"name": "projects/PROJECT_NAME/locations/us-west2/channels/lab-live-channel",
"createTime": "2022-11-17T06:33:21.497818033Z",
"updateTime": "2022-11-17T06:33:21.497818033Z",
"activeInput": "my-input",
"output": {
"uri": "gs://live-streaming-storage-LOGNAME"
},
"elementaryStreams": [
{
"videoStream": {
"h264": {
"widthPixels": 1280,
"heightPixels": 720,
"frameRate": 30,
"bitrateBps": 3000000,
"gopDuration": "2s",
"vbvSizeBits": 3000000,
"vbvFullnessBits": 2700000,
"entropyCoder": "cabac",
"profile": "high"
}
},
"key": "es_video"
},
{
"audioStream": {
"codec": "aac",
"bitrateBps": 160000,
"channelCount": 2,
"sampleRateHertz": 48000
},
"key": "es_audio"
}
],
"muxStreams": [
{
"key": "mux_video_ts",
"container": "ts",
"elementaryStreams": [
"es_video",
"es_audio"
],
"segmentSettings": {
"segmentDuration": "2s"
}
}
],
"manifests": [
{
"fileName": "main.m3u8",
"type": "HLS",
"muxStreams": [
"mux_video_ts"
],
"maxSegmentCount": 5,
"segmentKeepDuration": "60s"
}
],
"streamingState": "STOPPED",
"inputAttachments": [
{
"key": "my-input",
"input": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input"
}
],
"logConfig": {
"logSeverity": "OFF"
}
}
}
Vuelve a ejecutar el comando hasta que veas "done:true", que indica que se creó el extremo de entrada y está listo.
Ten en cuenta que, en este momento, "streamingState" es "STOPPED". Comenzaremos el canal en la siguiente sección.
10. Inicia el canal de transmisión en vivo
Ahora que creamos nuestro canal de transmisión en vivo, vamos a iniciarlo. En esta sección, haremos lo siguiente:
- Inicia el canal de transmisión en vivo
- Verifica el estado del canal. Debemos asegurarnos de que
streamingStatesea"AWAITING INPUT".
1. Inicia el canal
En Cloud Shell, ejecuta el siguiente comando curl para iniciar el canal:
Comando
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d "" \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID:start"
Ejemplo de resultado
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T05:39:32.884030164Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel",
"verb": "start",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
2. Verifica el estado del canal
Ejecuta el siguiente comando curl para obtener el estado del canal:
Comando
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID" | grep "streamingState"
Ejemplo de resultado
"streamingState": "AWAITING_INPUT",
Vuelve a ejecutar el comando hasta que veas "AWAITING_INPUT", lo que indica que el canal se está ejecutando y está listo para recibir un indicador.
11. Configura Media CDN
En esta sección, implementaremos Media CDN, la infraestructura de CDN. Crearemos los siguientes recursos:
- Origen del almacenamiento en caché perimetral
- Servicio de caché perimetral
1. Crea un origen del almacenamiento en caché perimetral
Un origen de caché perimetral representa una ubicación de contenido, como un bucket de Cloud Storage, una ubicación de almacenamiento de terceros o un balanceador de cargas. En términos de CDN, el origen (o servidor de origen) es la ubicación en la que se encuentra la fuente del contenido que queremos distribuir, p.ej., todo el CSS, los JavaScripts, el HTML, las imágenes, etcétera. Para este lab, crearemos un origen que se asigne al bucket de Cloud Storage que creamos al principio del lab. Llamaremos al origen del almacenamiento en caché perimetral cme-origin. El origen de una CDN es el lugar donde se almacena todo el contenido fuente antes de distribuirse a los servidores de caché perimetrales.
Usaremos el comando gcloud edge-cache origins create para crear el origen. El comando tardará unos minutos en completarse.
Comando
gcloud edge-cache origins create cme-origin \ --origin-address="gs://live-streaming-storage-$LOGNAME"
Resultado de ejemplo
Create request issued for: cme-origin Waiting for operation [projects/my-project/locations/global/operations/operation-1612121774168-5ba3759af1919- 3fdcd7b1-99f59223] to complete...done Created origin cme-origin
2. Crea un servicio de caché perimetral
Ahora que configuramos un origen del almacenamiento en caché perimetral, podemos crear el servicio de almacenamiento en caché perimetral.
Crea el archivo cme-demo.yaml
La configuración del servicio de caché perimetral se realiza a través de un archivo YAML. En Cloud Shell, crea un archivo local llamado cme-demo.yaml. Usa vi, nano o cualquier otro editor y pega las siguientes líneas en el archivo YAML:
name: cme-demo
routing:
hostRules:
- hosts:
- demo.cme.com
pathMatcher: routes
pathMatchers:
- name: routes
routeRules:
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- prefixMatch: /
origin: cme-origin
priority: 100
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 3600s
signedRequestMode: DISABLED
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- pathTemplateMatch: /**.m3u8
origin: cme-origin
priority: 25
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 1s
signedRequestMode: DISABLED
- headerAction: {}
matchRules:
- pathTemplateMatch: /**.ts
origin: cme-origin
priority: 50
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 2s
signedRequestMode: DISABLED
Dejaremos todos los parámetros de configuración predeterminados del servicio de almacenamiento en caché perimetral. En el archivo anterior, hay 3 valores de campo que los usuarios podrían querer actualizar:
name: El nombre de la instancia de Media CDN (en este caso,cme-demo)hosts:la lista de nombres de dominio que resolverá este servicio de Media CDN (aquí:demo.cme.com). Usaremos esto durante la demostración. Usaremos la dirección IP de la instancia de Media CDN.Origin:es el origen del almacenamiento en caché perimetral que acabamos de crear en el paso anterior. Establécelo encme-origin, el nombre del origen de Media CDN.
Para obtener más información sobre las diferentes variables que puedes usar en el archivo YAML, consulta la guía de configuración del servicio de caché perimetral.
Crea el servicio de almacenamiento en caché perimetral
Crearemos un servicio de almacenamiento en caché perimetral llamado cme-demo en el origen del almacenamiento en caché perimetral cme-origin con el host demo.cme.com. Para crear el servicio, ejecuta el siguiente comando en Cloud Shell:
Comando
gcloud edge-cache services import cme-demo \
--source=cme-demo.yaml
La creación del servicio de Edge Cache puede tardar unos minutos.
Ejemplo de resultado
Request issued for: [cme-demo]
Waiting for operation [projects/PROJECT_ID/locations/global/operations/operation-1670476252264-5ef4a0f9f36ce-dd380af5-321be9a0] to complete...done.
createTime: '2022-12-07T18:08:54.403446942Z'
ipv4Addresses:
- 34.104.35.152
ipv6Addresses:
- '2600:1900:4110:d18::'
name: projects/PROJECT_ID/locations/global/edgeCacheServices/cme-demo
routing:
hostRules:
- hosts:
- demo.cme.com
- 34.104.35.152
pathMatcher: routes
pathMatchers:
- name: routes
routeRules:
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: '{cdn_cache_status}'
matchRules:
- prefixMatch: /
origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin
priority: '100'
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 3600s
signedRequestMode: DISABLED
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: '{cdn_cache_status}'
matchRules:
- pathTemplateMatch: /**.m3u8
origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin
priority: '25'
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 1s
signedRequestMode: DISABLED
- headerAction: {}
matchRules:
- pathTemplateMatch: /**.ts
origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin
priority: '50'
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 2s
signedRequestMode: DISABLED
updateTime: '2022-12-08T05:11:31.598744308Z'
Anota y copia el ipv4Addresses de la instancia del servicio de caché perimetral (aquí 34.104.36.157). Lo usaremos para actualizar el archivo cme-demo.yaml y, luego, para transmitir el video transcodificado.
Actualiza el servicio de caché perimetral
En este punto, es una buena idea actualizar la configuración del servicio de caché perimetral para poder usar la IP del servicio y transmitir el video más adelante. El archivo YAML del servicio de Edge Cache nos permite enumerar todos los nombres de host o las IPs desde los que el servicio de Edge Cache aceptará solicitudes. En este punto, solo especificamos demo.cme.com como host. Para proporcionar resolución de nombres para este dominio, puedes configurar una zona de DNS. Sin embargo, una solución más sencilla sería agregar la dirección IP a la lista de hosts en el archivo yaml. Vuelve a editar el archivo YAML para que se vea como el siguiente:
name: cme-demo
routing:
hostRules:
- hosts:
- demo.cme.com
- IPADDRESS
pathMatcher: routes
pathMatchers:
- name: routes
routeRules:
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- prefixMatch: /
origin: cme-origin
priority: 100
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 3600s
signedRequestMode: DISABLED
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- pathTemplateMatch: /**.m3u8
origin: cme-origin
priority: 25
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 1s
signedRequestMode: DISABLED
- headerAction: {}
matchRules:
- pathTemplateMatch: /**.ts
origin: cme-origin
priority: 50
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 2s
signedRequestMode: DISABLED
Para reflejar los cambios, solo necesitamos volver a importar el archivo YAML. En la terminal de Cloud Shell, ejecuta el siguiente comando:
Comando
gcloud edge-cache services import cme-demo \
--source=cme-demo.yaml
Revisa el resultado del comando y verifica que la IP aparezca en la lista de hosts.
En este punto, la instancia del servicio de almacenamiento en caché perimetral aceptará solicitudes con "demo.cme.com" o la dirección IP como host.
12. Genera el Input Signal
Ahora que configuramos todos los servicios necesarios, generemos el indicador de entrada de la transmisión en vivo. En esta sección, haremos lo siguiente:
- Instala FFmpeg, un software de código abierto gratuito
- Envía una señal de prueba en vivo a la entrada o al canal
1. Instala FFmpeg
FFmpeg es un proyecto de software gratuito y de código abierto que consta de un conjunto de bibliotecas y programas para controlar archivos y transmisiones de video, audio y otros archivos multimedia. En la terminal de Cloud Shell, usa el siguiente comando para instalar FFmpeg:
Comando
sudo apt install ffmpeg -y
Cuando finalice la instalación, verifiquemos que FFmpeg se haya instalado correctamente. Para ello, consulta su versión:
Comando
ffmpeg -version
Ejemplo de resultado
ffmpeg version 4.3.4-0+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 10 (Debian 10.2.1-6) ...
FFmpeg se instaló correctamente.
2. Inicia la señal de transmisión en vivo hacia el canal o la entrada
Ahora que FFmpeg está instalado, enviaremos una transmisión de entrada de prueba al extremo de entrada para generar la transmisión en vivo.
En la terminal de Cloud Shell, ejecuta el siguiente comando con la variable de entorno URI que creamos en la sección "Crea y configura el extremo de entrada".
Comando
ffmpeg -re -f lavfi -i "testsrc=size=1280x720 [out0]; sine=frequency=500 [out1]" \ -acodec aac -vcodec h264 -f flv $URI
Deberías ver que FFmpeg envía la señal de prueba en vivo. El comando no devolverá el mensaje. El indicador se generará hasta que lo detengas. Deberás abrir una nueva ventana de Cloud Shell para el resto del lab.
13. Abre una nueva sesión de Cloud Shell
En este punto, deberás abrir una nueva ventana de Cloud Shell para continuar con el lab, ya que FFmpeg se ejecutará de forma permanente hasta que presiones <Ctrl+C> para detener el comando y, por lo tanto, detener la generación de la señal en vivo.
Haz clic en el signo "+" junto al nombre de la terminal de Cloud Shell actual. Se abrirá una ventana adicional de Cloud Shell.

Ejecuta el resto del lab en la ventana de Cloud Shell que se abrió recientemente.
Configura las variables de entorno
Dado que se trata de un nuevo Cloud Shell, debemos volver a configurar las variables de entorno. Usaremos el comando source para establecer las variables de entorno.
Comando
source ~/env_variables.txt
Verifica que las variables estén configuradas
Verifiquemos que todas las variables de entorno necesarias estén configuradas. Deberíamos ver un total de 6 variables de entorno en el resultado.
Comando
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
Ejemplo de resultado
LOCATION=us-west2 DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME> PROJECT_NUMBER=<YOUR_PROJECT_NUMBER> INPUT_ID=lab-live-input CHANNEL_ID=lab-live-channel
14. Verifica que la señal en vivo se esté transcodificando
Ejecutaremos un curl para describir el canal. En el resultado, deberíamos ver que streamingState cambió de "AWAITING_INPUT" a "STREAMING".
Comando
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID" | grep "streamingState"
En la respuesta del archivo JSON de salida, deberías ver "streamingState": "STREAMING", lo que indica que el canal está transmitiendo y que se está transcodificando la señal en vivo.
También verificaremos el contenido del bucket, en el que deberíamos ver un archivo de manifiesto y varios segmentos de video en formato TS. Ejecuta el siguiente comando en Cloud Shell para enumerar el contenido del bucket que creamos al principio del lab y que usa la API de Live Streaming para generar el manifiesto de la señal en vivo transcodificada y los segmentos de video en formato TS:
Comando
gcloud storage ls --recursive gs://live-streaming-storage-$LOGNAME/**
Ejemplo de resultado
gs://live-streaming-storage-$LOGNAME/ gs://live-streaming-storage-$LOGNAME/main.m3u8 gs://live-streaming-storage-$LOGNAME/mux_video_ts/index-1.m3u8 gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000016.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000017.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000018.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000019.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000020.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000021.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000022.ts ...
Deberías ver lo siguiente:
- el archivo de manifiesto de HLS:
main.m3u8 - Los segmentos de video en formato TS correspondientes: una serie de archivos numerados
segment-000000000X.ts
En este punto, ya terminamos con lo siguiente:
- API de Live Streaming: La señal en vivo se genera y se transcodifica en un bucket a través de la API de Live Streaming.
- Media CDN: Se configuró Media CDN con el bucket de almacenamiento de transmisión en vivo como origen de Media CDN.
En las siguientes secciones, validaremos el servicio de caché perimetral y, luego, transmitiremos el video transcodificado con la dirección IP de Anycast de Media CDN.
15. Verifica que la instancia del servicio de Edge Cache funcione
En esta sección, verificaremos que la instancia del servicio de caché perimetral funcione según lo previsto. Para ello, intentaremos acceder a un archivo desde la instancia del servicio de almacenamiento en caché perimetral con la dirección IP del servicio de almacenamiento en caché perimetral. La primera vez que se accede a un objeto, aún no se almacena en caché. Deberíamos observar una caché MISS. En la primera solicitud, el objeto se lee desde el origen y se almacena en caché en el borde. Todos los siguientes intentos de acceder al mismo archivo devolverán un HIT de caché, ya que el objeto ahora se almacena en caché en el borde. Verifiquemos este comportamiento:
Ejecuta el siguiente comando curl en Cloud Shell para acceder al archivo de manifiesto del video transcodificado que se almacena en el origen de la caché perimetral:
Comando
curl -svo /dev/null --resolve demo.cme.com:80:<Replace_With_Edge_Cache_IP> \ "http://demo.cme.com/main.m3u8"
Observa la resolución en la que usamos la dirección IP de la instancia del servicio de almacenamiento en caché perimetral para resolver su nombre. Asegúrate de usar demo.cme.com:<IP>, donde IP es la IP de la instancia del servicio de Edge Cache que acabamos de crear.
Busca el encabezado x-cache-status en el resultado.
Ejemplo de resultado
Added demo.cme.com:80:34.104.35.152 to DNS cache
* Hostname demo.cme.com was found in DNS cache
* Trying 34.104.35.152:80...
* Connected to demo.cme.com (34.104.35.152) port 80 (#0)
> GET /main.m3u8 HTTP/1.1
> Host: demo.cme.com
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< x-guploader-uploadid: ADPycdtKtflWt4Kha5YxXNNRwO-Eu6fGSPs-T-XY4HJmNMo46VJyWlD4EAk-8a6SegxjWq3o1gTPqZbpkU_sjW__HPAdDw
< date: Wed, 07 Dec 2022 18:23:46 GMT
< last-modified: Wed, 07 Dec 2022 18:23:45 GMT
< etag: "6bff620ccca4a9849ba4e17fa7c521fb"
< x-goog-generation: 1670437425805400
< x-goog-metageneration: 1
< x-goog-stored-content-encoding: identity
< x-goog-stored-content-length: 193
< content-type: application/x-mpegURL
< x-goog-hash: crc32c=sPO3zw==
< x-goog-hash: md5=a/9iDMykqYSbpOF/p8Uh+w==
< x-goog-storage-class: STANDARD
< accept-ranges: bytes
< content-length: 193
< server: Google-Edge-Cache
< x-request-id: fd25285b-fc1a-4fd4-981a-c50ead2c85ed
< x-xss-protection: 0
< x-frame-options: SAMEORIGIN
< x-cache-status: den;miss
< cache-control: public,max-age=3600
<
{ [193 bytes data]
* Connection #0 to host demo.cme.com left intact
Observa la falla de caché, ya que el objeto aún no se almacenó en caché y se lee desde el origen.
Ahora realizaremos varias solicitudes para el archivo m3u8 y, si todo está configurado correctamente, Media CDN debería comenzar a entregar el contenido desde su caché. El siguiente comando realizará 10 solicitudes de curl y solo imprimirá el encabezado x-cache-status.
Comando
for i in {1..10};do curl -Is --resolve demo.cme.com:80:<Replace_With_Edge_Cache_IP> "http://demo.cme.com/main.m3u8" | grep x-cache-status;done
El resultado debe ser una combinación de caché hit y miss. Si ves aciertos de caché en el resultado, significa que Media CDN funciona según lo esperado.
Ejemplo de resultado
x-cache-status: den;miss x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit
Observa el acierto de caché, ya que el objeto ahora está almacenado en caché en el borde. El servicio de Cloud Media Edge funciona según lo esperado.
16. Transmite el video de la señal en vivo transcodificada con VLC
Esta es la parte en la que conectamos los puntos y vinculamos todos los pasos en los que trabajamos hasta ahora:
- Creamos un bucket llamado
live-streaming-storage-$LOGNAMEque recibe el resultado de la señal en vivo transcodificada en contenido HLS por la API de Live Streaming. - Configuramos la API de Live Streaming.
- Comenzamos una señal en vivo de RTMP con FFmpeg que alimenta la entrada o el canal de la API de Live Streaming.
- Verificamos que el feed de la transmisión en vivo se haya enviado al canal y que este se encuentre en modo
streaming. - Verificamos que los archivos transcodificados resultantes (segmentos de manifiesto y TS) se generaron y almacenaron en el bucket
live-streaming-storage-$LOGNAME. - Se configuró un origen del almacenamiento en caché perimetral llamado
cme-origincon el bucket de GCSlive-streaming-storage-$LOGNAMEcomo origen. - Se configuró una instancia de Edge Cache llamada
cme-democoncme-origincomo su origen. - Verificamos el comportamiento (error de caché, acierto de caché) de la instancia del servicio de Edge Cache.
Ahora podemos usar un reproductor de video para transmitir la señal en vivo transcodificada a través de la caché de Media CDN. Para ello, usaremos el reproductor VLC. El reproductor VLC es un reproductor y framework multimedia multiplataforma de código abierto y gratuito que reproduce la mayoría de los archivos multimedia. Reproduce formatos multimedia adaptables (como DASH y HLS). Utiliza el principio de la transmisión adaptable: Según la calidad de tu conexión de red y el ancho de banda disponible, el reproductor adaptará la calidad del video que se reproduzca. Con el trabajo de transcodificación que acabamos de realizar, usamos los parámetros de configuración predeterminados y generamos "solo" dos calidades: SD y HD. Cuando comencemos a reproducir el video en el reproductor, deberías ver que comienza a reproducirse en formato SD y que cambia rápidamente al formato HD si tu conexión de red es lo suficientemente buena.
Transmitiremos la señal en vivo transcodificada de HLS (formato de video de Apple ampliamente compatible). El archivo correspondiente se llama main.m3u8, que es el manifiesto de HLS. El manifiesto apunta a los segmentos de video en formato TS.
Para usar el reproductor VLC, ve a https://www.videolan.org/vlc/ y descarga una versión del reproductor para el sistema operativo de tu laptop. VLC está disponible para Windows, macOS, Linux, Android y iOS.

Instala el reproductor en tu laptop y ejecútalo. Usaremos la versión para MacOSX del reproductor en los próximos pasos.
Para reproducir un video, ve a "Archivo" / "Abrir red":

Configúralo con lo siguiente:
- URL: http://<Replace_With_Edge_Cache_IP>/main.m3u8. Esta es la URL del video que queremos transmitir. Aviso:
- La IP de la instancia de Media CDN:
34.105.35.246. Reemplaza por la IP del servicio de Cloud Media que implementaste. - La ruta de acceso al archivo de video de manifiesto: "
/". Esta es la ruta de acceso que usamos en el bucketlive-streaming-storage-$LOGNAMEpara almacenar los archivos de señal en vivo transcodificados. La ruta de acceso es la ruta raíz aquí: “/”. - Nombre del archivo de manifiesto de video: el archivo de manifiesto de HLS,
main.m3u8.
Luego, haz clic en “Abrir”. Deberías ver que comienza a reproducirse el video en vivo transcodificado. El video se verá como en la siguiente captura de pantalla. El contador en pantalla se ejecutará en incrementos de 1, y deberías poder escuchar un pitido continuo.
Es una señal en vivo de prueba básica de RTMP generada por FFmpeg, transcodificada a HLS por la API de Live Streaming y publicada a través de la caché de Media CDN:

Si lo deseas, puedes usar cualquier otro reproductor HLS y MPEG-DASH. Aquí tienes algunos que puedes considerar:
- Reproductor QuickTime: Se instala de forma predeterminada en las Mac. Lo mismo aquí: abre una conexión de red a http://34.104.36.157/main.m3u8. Reemplaza la dirección IP por la de tu instancia del servicio de caché de Edge.
17. Supervisa Media CDN
El equipo de SME creó una plantilla de panel de Media CDN: https://gist.github.com/elithrar/1c511d00f5cd3736fb2a3897867209c1.
Para instalarlo, ejecuta los siguientes comandos en la ventana de Cloud Shell:
Descarga el archivo YAML:
curl https://gist.githubusercontent.com/elithrar/1c511d00f5cd3736fb2a3897867209c1/raw/3cb70855304f29e5c06b8d63063196354db0dec3/media-edge-20210208-dashboard --output media-edge-20210208-dashboard.yaml
Crea el panel de Cloud Monitoring:
gcloud monitoring dashboards create --config-from-file media-edge-20210208-dashboard.yaml
La configuración puede tardar unos minutos. Ve a la consola de Google Cloud y haz clic en las 3 barras > Operaciones > Monitoring > Paneles. Deberías ver un panel llamado "Métricas de Media Edge". Haz clic en él y verás las métricas:

18. Limpia el entorno del lab
¡Felicitaciones por completar el lab! En esta sección, borraremos todos los recursos que creamos a lo largo del lab.
Detén el indicador de FFmpeg:
Presiona <CTRL+C> en la terminal de Cloud Shell en la que se ejecuta FFmpeg.
Detén el canal de transmisión en vivo:
Comando
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d "" \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID:stop"
Borra el canal de transmisión en vivo:
Comando
curl -X DELETE -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID"
Borra el extremo de entrada de transmisión en vivo:
Comando
curl -X DELETE \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID"
Borra el bucket de GCS:
Comando
gsutil rm -r gs://live-streaming-storage-$LOGNAME
Borra la instancia del servicio de caché perimetral:
Comando
gcloud edge-cache services delete cme-demo
Para confirmar la eliminación, ingresa "Y" cuando se te solicite.
Borra el origen de almacenamiento en caché perimetral:
Comando
gcloud edge-cache origins delete cme-origin
Para confirmar la eliminación, ingresa "Y" cuando se te solicite.
Borra el panel personalizado
Comando
gcloud monitoring dashboards delete $(gcloud monitoring dashboards list --filter="displayName:Media Edge Metrics" --format="value(name)")