1. Introducción
Las redes de distribución de contenidos (CDN) mejoran el rendimiento de los usuarios almacenando en caché el contenido al que se accede con frecuencia más cerca de los usuarios finales, cerrando las conexiones más cerca de los clientes, reutilizando las conexiones con el origen y adoptando protocolos y personalizaciones de red modernos. Para los usuarios (y nuestros clientes), esto significa una latencia más baja, más confiabilidad y un costo reducido, lo que genera mejores ventas, una experiencia web mejorada y un aumento neto en la experiencia del usuario. En la actualidad, muy pocos sitios modernos y plataformas de transmisión de video funcionan sin una CDN.
Qué aprenderás
En este lab, se nos guiará a través de 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 transmisión en vivo (entrada y canal) y comenzaremos un feed en vivo en la entrada o el canal con FFmpeg (FFmpeg puede generar una señal de prueba en vivo). La API de transmisión en vivo 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 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:
Como parte del lab, configuraremos los siguientes componentes y realizaremos las siguientes tareas:
- Crea un bucket de Google Cloud Storage (GCS) para almacenar los videos transcodificados en vivo
- Configura la API de transmisión en vivo para transcodificar el video a varios formatos: HLS + MPEG DASH, SD y HD
- Configura los componentes de transmisión en vivo: Entrada/Canal
- Inicia el canal de transmisión en vivo
- Configura Media CDN con el bucket de GCS como origen
- Configura FFmpeg para que alimente 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. Veremos punteros a lo largo del lab que dirigirán a 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 PM de Media CDN para solicitar acceso a esta plataforma.
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 escribir este artículo, 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 esté usando 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 salida
Google Cloud SDK 408.0.0
Próximos pasos
- Si la versión del SDK es
408.0.0
o posterior, ve a la siguiente sección. - Si la versión del SDK es inferior a
408.0.0
, ejecuta el siguiente comando para actualizarlo.
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 los 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 Cloudshell. Para verificarlo, usaremos el comando env
.
Comando
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME'
Ejemplo de salida
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 configurar las variables de entorno.
Comando
source ~/env_variables.txt
Verifica que las variables estén configuradas
Verifiquemos que se hayan configurado todas las variables de entorno necesarias. 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 salida
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é de borde 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 crear una lista de todas las APIs habilitadas. Deberíamos ver 4 APIs en el resultado.
Comando
gcloud services list | grep -E 'networkservices|certificatemanager|livestream|edgecache'
Ejemplo de salida
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 iam
de gsutil
para que los archivos estén disponibles para el público:
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 transmisión en vivo tienen la siguiente arquitectura:
Creamos el bucket de Cloud Storage live-streaming-storage-$LOGNAME
en la sección anterior. En las siguientes dos secciones, crearemos los siguientes recursos:
- Entrada de transmisión en vivo: Un extremo de entrada es un extremo al que el codificador envía tu flujo de entrada. Puedes usar el extremo de entrada para especificar parámetros de configuración para 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, la transcodifica en varias versiones y publica transmisiones en vivo de salida en ciertos formatos en la ubicación especificada. Puedes incluir un flujo de entrada principal y uno de respaldo en el mismo canal.
Más adelante en el lab, crearemos los siguientes recursos:
- Codificación: Un codificador es un programa que se usa para enviar flujos 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 la señal 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 transmisión en vivo. 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 salida
{ "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: En el resultado, copia y toma nota del ID de operación. 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": false
a"done": true
.
Consulta 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 salida
{ "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.
Guarda el URI
Más adelante en el lab, usaremos el URI
del resultado anterior. En este momento, establezcamos una variable de entorno para URI
.
Comando
export URI=<uri>
Reemplaza <uri>
por el URI que anotaste anteriormente. 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 con el 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 renderización de 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 salida
{ "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"
.
Consulta 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 salida
"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 el "streamingState"
en este momento 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 transmisiones en vivo, comencemos a usarlo. En esta sección, haremos lo siguiente:
- Inicia el canal de transmisiones en vivo
- Verifica el estado del canal. Debemos asegurarnos de que
streamingState
sea"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 salida
{ "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 salida
"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 una señal.
11. Configura Media CDN
En esta sección, implementaremos Media CDN, la infraestructura de CDN. Crearemos los siguientes recursos:
- Origen de la caché perimetral
- Servicio de almacenamiento en caché perimetral
1. Crea un origen de 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 donde se encuentra la fuente del contenido que queremos distribuir, p.ej., todo el CSS, JavaScript, HTML, imágenes, etc. En este lab, crearemos un origen que se asigne al bucket de Cloud Storage que creamos al principio del lab. Llamaremos al origen de almacenamiento en caché perimetral cme-origin
. El origen de una CDN es donde se almacena todo el contenido de origen antes de distribuirlo 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. Cómo crear un servicio de almacenamiento en caché perimetral
Ahora que tenemos configurado 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 almacenamiento en 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 (aquí:cme-demo
)hosts:
La lista de nombres de dominio que resolverá este servicio de Media CDN:demo.cme.com
. La usaremos durante esta 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. Establece el valor 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é de Edge.
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 caché de Edge puede tardar unos minutos.
Ejemplo de salida
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 almacenamiento en caché perimetral, aquí 34.104.36.157
. La usaremos para actualizar el archivo cme-demo.yaml
y, luego, para transmitir el video transcodificado.
Actualiza el servicio de almacenamiento en caché perimetral
En este punto, es recomendable actualizar la configuración del servicio de almacenamiento en caché perimetral para poder usar la IP del servicio y transmitir el video más adelante. El archivo YAML del servicio de almacenamiento en caché perimetral nos permite enumerar todos los nombres de host o IPs de los que el servicio de almacenamiento en caché perimetral aceptará solicitudes. En este punto, solo especificamos demo.cme.com
como host. Para proporcionar la resolución de nombres de 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 debemos 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 la señal de entrada
Ahora que configuramos todos los servicios necesarios, generemos la señal de entrada de la transmisión en vivo. En esta sección, haremos lo siguiente:
- Instala FFmpeg, un software de código abierto y 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 paquete de bibliotecas y programas para controlar transmisiones y archivos multimedia, de audio y video. En la terminal de Cloud Shell, usa el siguiente comando para instalar FFmpeg:
Comando
sudo apt install ffmpeg -y
Cuando termine la instalación, verifiquemos que FFmpeg se haya instalado correctamente comprobando su versión:
Comando
ffmpeg -version
Ejemplo de salida
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 el indicador de transmisión en vivo en la entrada o el canal.
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 de 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 mostrará el mensaje. El indicador se generará hasta que lo detengas. Deberás abrir una ventana nueva de Cloud Shell para el resto del lab.
13. Cómo abrir 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 detenerlo y, de esta manera, 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 acabas de abrir.
Configura las variables de entorno
Dado que esta es una nueva instancia de CloudShell, debemos volver a configurar las variables de entorno. Usaremos el comando source
para configurar las variables de entorno.
Comando
source ~/env_variables.txt
Verifica que las variables estén configuradas
Verifiquemos que se hayan configurado todas las variables de entorno necesarias. 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 salida
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 se esté transcodificando la señal en vivo
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 la señal en vivo se está transcodificando.
También verifiquemos el contenido del bucket, en el que deberíamos ver un archivo de manifiesto y varios segmentos de video TS. Ejecuta el siguiente comando en Cloud Shell para crear una lista del contenido del bucket que creamos al comienzo del lab y que usa la API de transmisión continua para generar el manifiesto de señal en vivo transcodificado y los segmentos de video TS:
Comando
gcloud storage ls --recursive gs://live-streaming-storage-$LOGNAME/**
Ejemplo de salida
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 HLS:
main.m3u8
- Los segmentos de video TS correspondientes: una serie de archivos numerados
segment-000000000X.ts
En este punto, ya terminamos con lo siguiente:
- API de transmisión en vivo: La señal en vivo se genera y transcodifica en un bucket a través de la API de transmisión en vivo.
- Media CDN: Se configuró Media CDN con el bucket de almacenamiento de transmisión en vivo como su origen.
En las siguientes secciones, validaremos el servicio de caché de borde y, luego, transmitiremos el video transcodificado con la dirección IP de anycast de la CDN de Media.
15. Verifica que la instancia del servicio de almacenamiento en caché perimetral funcione
En esta sección, verificaremos que la instancia del servicio de caché de Edge funcione según lo esperado. Para ello, intentaremos acceder a un archivo de 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 perímetro. Todos los siguientes intentos de acceso al mismo archivo mostrarán una caché HIT
, ya que el objeto ahora está almacenado en caché en el perímetro. Verifiquemos este comportamiento:
Ejecuta el siguiente comando curl
en Cloud Shell para acceder al archivo de manifiesto de video transcodificado que se almacena en el origen de la caché de Edge:
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 almacenamiento en caché perimetral que acabamos de crear.
Busca el encabezado x-cache-status
en el resultado.
Ejemplo de salida
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 falta 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, la CDN de Media 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 hit
y miss
de la caché. Si ves hits de caché en el resultado, significa que Media CDN funciona como se espera.
Ejemplo de salida
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 la caché, ya que el objeto ahora está almacenado en caché en el perímetro. El servicio de Cloud Media Edge funciona como se espera.
16. Cómo transmitir un video de señal en vivo transcodificado con VLC
Esta es la parte en la que conectamos los puntos y vinculamos todos los pasos en los que hemos estado trabajando hasta ahora:
- Creamos un bucket llamado
live-streaming-storage-$LOGNAME
que recibe el resultado de la señal en vivo transcodificada a contenido HLS por la API de transmisión en vivo. - Configuramos la API de transmisión en vivo.
- Comenzamos un indicador en vivo de RTMP con FFmpeg que alimenta la entrada o el canal de la API de transmisión en vivo.
- Verificamos que el canal recibiera la señal en vivo y que estuviera en modo
streaming
. - Verificamos que los archivos transcodificados resultantes (manifiesto + segmentos TS) se generaron y almacenaron en el bucket
live-streaming-storage-$LOGNAME
. - Se configuró un origen del almacenamiento en caché perimetral llamado
cme-origin
con el bucket de GCSlive-streaming-storage-$LOGNAME
como origen. - Se configuró una instancia de Edge Cache llamada
cme-demo
concme-origin
como su origen. - Verificamos el comportamiento (falta de caché, acierto de caché) de la instancia del servicio de almacenamiento en caché perimetral.
Ahora estamos en un punto en el que podemos usar un reproductor de video para transmitir el indicador en vivo transcodificado a través de la caché de Media CDN. Para ello, usaremos el reproductor VLC. El reproductor VLC es un framework y reproductor 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). Usa 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 reproduce. 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 cambia rápidamente al formato HD si tu conexión de red es lo suficientemente buena.
Transmitiremos la señal en vivo transcodificada en HLS (formato de video de Apple ampliamente compatible). El archivo correspondiente se llama main.m3u8
, que es el manifiesto HLS. El manifiesto apunta a los segmentos de video 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, MacOSX, Linux, Android y iOS.
Instala el reproductor en tu laptop y ejecútalo. En los próximos pasos, usaremos la versión para MacOSX del reproductor.
Para reproducir un video, ve a "File" / "Open Network":
Configura el dispositivo con lo siguiente:
- URL: http://<Replace_With_Edge_Cache_IP>/main.m3u8. Esta es la URL del video que queremos transmitir. Ten en cuenta que:
- La IP de la instancia de Media CDN:
34.105.35.246
Reemplaza la IP del servicio de Cloud Media que implementaste. - La ruta de acceso al archivo de video del manifiesto: "
/
". Esta es la ruta que usamos en el bucketlive-streaming-storage-$LOGNAME
para almacenar los archivos de señal en vivo transcodificados. La ruta de acceso es la raíz: “/”. - Es el nombre del archivo de video del manifiesto: el archivo de manifiesto HLS,
main.m3u8
.
y 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 escuchar un pitido continuo.
Es una señal en vivo de prueba básica de RTMP que genera FFmpeg, que la API de transmisión en vivo transcodifica a HLS y se entrega a través de la caché de Media CDN:
Si lo deseas, puedes usar cualquier otro reproductor HLS y MPEG DASH. Estos son algunos que te recomendamos:
- Reproductor QuickTime: Se instala de forma predeterminada en 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 almacenamiento en caché perimetral.
17. Cómo supervisar 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 > Supervisión > Paneles. Deberías ver un panel llamado "Métricas de Edge de contenido multimedia". 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.
Detener 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.
Cómo borrar el panel personalizado
Comando
gcloud monitoring dashboards delete $(gcloud monitoring dashboards list --filter="displayName:Media Edge Metrics" --format="value(name)")