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 conexiones con el origen y mediante la adopción de personalizaciones y protocolos de red modernos. Para los usuarios (y nuestros clientes), esto significa una menor latencia, más confiabilidad y menos costos, lo que produce mejores ventas, experiencia web y un aumento neto en la experiencia del usuario. En la actualidad, muy pocos sitios y plataformas de transmisión de video por Internet modernos funcionan sin una CDN.
Qué aprenderás
Este lab 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) + Cloud Media Live Streaming API (transcodificación de video en vivo) + Cloud Storage (almacenamiento para los videos) + Reproductor de video (VLC, Google Shaka Player, etc., HLS + MPEG-DASH compatible con el reproductor).
Configuraremos los componentes de la API de Live Streaming - Input, Channel e iniciaremos 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 video en vivo de Cloud Storage como origen. Por último, se usará VLC Player 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 basado en la siguiente arquitectura:
Configuraremos los siguientes componentes y realizaremos las siguientes tareas como parte del lab:
- Crear 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
- Cómo configurar FFmpeg para proporcionar información al 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, acierto de caché, error de caché, etcétera).
Nota: Para este lab, suponemos que los usuarios tienen acceso a la consola de Google Cloud y ya tienen una configuración de proyecto. 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 comprobar los componentes configurados a través de la línea de comandos en la consola. A lo largo del lab, veremos punteros que apuntará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. Ellos pueden crear una solicitud de acceso en tu nombre. Si formas parte de Google y deseas probar la transmisión en vivo con Media CDN, comunícate con el PM 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
Al 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 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, pasa a la siguiente sección. - Si la versión del SDK es anterior a
408.0.0
, ejecuta el comando que se muestra a continuación 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
Durante 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
Estas variables de entorno generalmente están preconfiguradas en Cloud Shell. Usaremos el comando env
para verificarlo.
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 estén configuradas 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 Media CDN Edge Cache
Habilita la API de servicios de red
Para habilitar la API de Network Services, ejecuta el siguiente comando:
Comando
gcloud services enable networkservices.googleapis.com
Habilitar 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 mostrar 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. Permita que el bucket sea accesible de forma pública
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. Configura el entorno de la API de Live Streaming
Los componentes de la cadena de API de Live Streaming tienen la siguiente arquitectura:
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 aquel al que el codificador envía la transmisión de entrada. Puedes usar el extremo de entrada para especificar parámetros de configuración de tu transmisión, como la resolución, 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 en vivo a través de un extremo de entrada, la transcodifica en varios formatos 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 respaldo en el mismo canal.
Crearemos los siguientes recursos más adelante en el lab:
- 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 indicador de transmisión en vivo. En este lab, usaremos la señal en vivo RTMP.
Comando
cat > input.json << EOF { "type": "RTMP_PUSH" } EOF
Crea el extremo de entrada
Al momento de escribir este lab, no hay asistencia de 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 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 anota el ID de operación. A continuación, se muestra el ID de operación del ejemplo del resultado. Se puede encontrar 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
Cómo consultar 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 ver. 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"
, lo que indica que el extremo de entrada se creó y está listo.
Guarda el URI
Usaremos el URI
del resultado anterior más adelante en el lab. En este momento, vamos a configurar una variable de entorno para URI
.
Comando
export URI=<uri>
Reemplaza <uri>
por el URI que acabas de anotar. 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. Crear 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 de HLS que consta de una única representación en alta definición (1280 × 720). El canal se asociará con el extremo de entrada y con 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 }
Toma nota y copia el ID de operación. Lo necesitaremos en uno de los próximos pasos. Se puede encontrar en la línea de salida que comienza con "name"
.
Cómo consultar el estado
Antes de continuar, debemos verificar que el canal se haya creado correctamente y que esté listo.
En el siguiente comando, reemplaza <OPERATION>
por el ID de la operación que acabamos de ver. 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"
, lo que indica que el extremo de entrada se creó y está listo.
Ten en cuenta que, en este momento, la "streamingState"
es "STOPPED"
. el canal comenzará en la siguiente sección.
10. Inicia el canal de transmisión en vivo
Ahora que creamos nuestro canal de transmisiones en vivo, comencemos el canal. En esta sección, haremos lo siguiente:
- Inicia el canal de transmisión en vivo
- Verifica el estado del canal. Debemos asegurarnos de que
streamingState
sea"AWAITING INPUT"
.
1. Empieza 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 está activo y listo para recibir una señal.
11. Configurar 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 almacenamiento en caché perimetral
1. Crea un origen de almacenamiento en caché perimetral
Un origen de almacenamiento en 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., todos los elementos de CSS, JavaScript, HTML, imágenes, etc. En este lab, crearemos un origen que se asigne al bucket de Cloud Storage que creamos al comienzo del lab. Llamaremos al origen de almacenamiento en caché perimetral cme-origin
. En el origen de una CDN, se almacena todo el contenido de origen antes de distribuirlo a los servidores de caché perimetral.
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 almacenamiento en caché perimetral
Ahora que tenemos configurado un origen de 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 valores predeterminados de la configuración del servicio de almacenamiento en caché perimetral. En el archivo anterior, hay 3 valores de campo que los usuarios podrían querer actualizar:
name
: Es el nombre de la instancia de Media CDN, aquí:cme-demo
.hosts:
es la lista de nombres de dominio que resolverá este servicio de Media CDN, aquí:demo.cme.com
. Lo usaremos durante esta demostración. Usaremos la dirección IP de la instancia de Media CDN.Origin:
es el origen de 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 almacenamiento en caché perimetral.
Crea el servicio de almacenamiento en caché perimetral
Crearemos un servicio de almacenamiento en caché perimetral llamado cme-demo
, en el origen de 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 almacenamiento en caché perimetral 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'
Observa y copia el ipv4Addresses
de la instancia del servicio de almacenamiento en caché perimetral, aquí 34.104.36.157
. Lo usaremos para actualizar el archivo cme-demo.yaml
y, luego, transmitir el video transcodificado.
Actualiza el servicio de almacenamiento en caché perimetral
En este punto, es una buena idea 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 o IP de hosts de los que el servicio de almacenamiento en caché perimetral aceptará las solicitudes. En este punto, solo especificamos demo.cme.com
como host. Para proporcionar una resolución de nombres a este dominio, configura una zona del DNS en la nube. Sin embargo, una solución más fácil sería agregar la dirección IP a la lista de hosts en el archivo yaml
. Vuelve a editar el archivo YAML y edítalo para que se vea de la siguiente manera:
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
Verifica el resultado del comando y comprueba 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 indicador de entrada
Ahora que configuramos todos los servicios requeridos, generemos el indicador de entrada de la transmisión en vivo. En esta sección, haremos lo siguiente:
- Instala FFmpeg, un software gratuito de código abierto
- Enviar una señal en vivo de prueba a la entrada o el canal
1. Instalar FFmpeg
FFmpeg es un proyecto de software gratuito y de código abierto que consta de un conjunto de bibliotecas y programas para controlar transmisiones y archivos de video, audio y 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, verificaremos la versión de FFmpeg que se instaló correctamente:
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 la señal de transmisión en vivo para 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 del URI que creamos en “Crea y configura el extremo de entrada”. sección.
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 en vivo de la prueba. El comando no mostrará el mensaje. La señal se generará hasta que la detengas. Deberás abrir una nueva ventana de Cloud Shell durante el resto del lab.
13. Abrir un nuevo 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>. el comando para detenerla y, así, detener la generación de la señal activa.
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 acaba de abrir.
Configura las variables de entorno
Como se trata de un nuevo Cloud Shell, debemos configurar las variables de entorno nuevamente. Usaremos el comando source
para configurar las variables de entorno.
Comando
source ~/env_variables.txt
Verifica que las variables estén configuradas
Verifiquemos que estén configuradas 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 una curl
para describir el canal. Deberíamos ver en el resultado 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"
, que indica que el canal está transmitiendo y que se está transcodificando la señal en vivo.
También verifiquemos el contenido del bucket en el que deberíamos ver un archivo de manifiesto y varios segmentos de video de TS. Ejecuta el siguiente comando en Cloud Shell para enumerar el contenido del bucket que creamos al comienzo 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 de 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 de HLS:
main.m3u8
- Los segmentos de video de 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 se 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 el origen de Media CDN.
En las próximas secciones, validaremos el servicio de almacenamiento en caché perimetral y, luego, transmitiremos el video transcodificado con la dirección IP anycast de Media CDN.
15. Verifica que la instancia del servicio de almacenamiento en caché perimetral funcione
En esta sección, verificaremos que la instancia del servicio de almacenamiento en caché perimetral funcione como se espera. Para ello, intentaremos acceder a un archivo desde la instancia del servicio de almacenamiento en caché perimetral con la dirección IP de este servicio. La primera vez que se accede a un objeto, aún no se almacena en caché. Deberíamos observar un MISS
de caché. En la primera solicitud, el objeto se lee desde el origen y se almacena en caché en el perímetro. Todos los siguientes intentos para acceder al mismo archivo mostrarán una HIT
de caché, ya que el objeto ahora se almacena en caché en el perímetro. Comprobemos 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 almacenamiento en 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. Usa demo.cme.com:<IP>
, en el que la 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 que la caché falta, ya que el objeto aún no se almacenó en caché y se lee desde el origen.
Ahora haremos 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 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 caché. Si ves aciertos de caché en el resultado, significa que Media CDN funciona como se esperaba.
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 hit de la caché, ya que el objeto ahora está almacenado en caché en el perímetro. El servicio de Cloud Medie Edge funciona según lo previsto.
16. Transmite videos de señales en vivo transcodificadas con VLC
Esta es la parte en la que unimos 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 al contenido HLS por la API de transmisión en vivo. - Configuramos la API de Live Streaming.
- Iniciamos una señal en vivo RTMP con FFmpeg que alimenta la entrada/canal de la API de Live Streaming.
- Verificamos que la señal en vivo se envió al canal y verificamos que este esté en modo
streaming
. - Verificamos que los archivos transcodificados resultantes (manifiesto + segmentos de TS) se generaron y se almacenaron en el bucket
live-streaming-storage-$LOGNAME
. - Se configuró un origen de almacenamiento en caché perimetral llamado
cme-origin
con el bucket de GCSlive-streaming-storage-$LOGNAME
como origen. - Se configuró una instancia de almacenamiento en caché perimetral llamada
cme-demo
concme-origin
como su origen. - Verificamos el comportamiento (error 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 la señal en vivo transcodificada a través de la caché de Media CDN. Para ello, usaremos el reproductor VLC. VLC Player es un reproductor multimedia y un framework de código abierto, gratuito y multiplataforma que reproduce la mayoría de los archivos multimedia. Reproduce formatos multimedia adaptables (como DASH y HLS). Usa el principio de transmisión adaptable: El reproductor adaptará la calidad de video de reproducción según la calidad de tu conexión de red y el ancho de banda disponible. Con el trabajo de transcodificación que acabamos de hacer, usamos los ajustes predeterminados y generamos dos cualidades "únicamente": SD y HD. Cuando empecemos a reproducir el video en el reproductor, deberías ver que empieza 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 HLS (formato de video ampliamente compatible de Apple). El archivo correspondiente se llama main.m3u8
, que es el manifiesto de HLS. El manifiesto dirige a los segmentos de video de TS.
Para usar el reproductor VLC, visita 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, iOS y Android.
Instala el reproductor en tu laptop e inícialo. En los próximos pasos, usaremos la versión MacOSX del reproductor.
Para reproducir un video, ve a "Archivo" /"Red abierta":
Configúralo 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
. Reemplázala por la IP del servicio multimedia de Cloud que implementaste. - La ruta de acceso al archivo de video de manifiesto: "
/
". Esta es la ruta que usamos en el bucketlive-streaming-storage-$LOGNAME
para almacenar los archivos de indicadores en vivo transcodificados. La ruta es la ruta raíz aquí: “/”. - El nombre del archivo de video de manifiesto: el archivo de manifiesto de HLS,
main.m3u8
.
Y haz clic en “Abrir”. Deberías ver que el video en vivo transcodificado comienza a reproducirse. El video se verá como la siguiente captura de pantalla. El contador en pantalla se reproducirá en incrementos de 1, y deberías poder escuchar un pitido continuo.
Es una señal en vivo de prueba RTMP básica generada por FFmpeg, transcodificada a HLS por la API de transmisión en vivo y entregada 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 debes tener en cuenta:
- Reproductor Quicktime: instalado de forma predeterminada en Mac. Lo mismo ocurre 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 de servicio de almacenamiento en caché perimetral).
17. Supervisa Media CDN
El equipo de SME creó una plantilla de panel de Media CDN: https://gist.github.com/elithrar/1c511d00f5cd3736fb2a3897867209c1.
Para instalarla, 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 para 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 de control. Deberías ver un panel llamado "Media Edge Metrics". Haz clic en él para ver 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 la señal 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"
Sigue estos pasos para borrar 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 almacenamiento en caché perimetral:
Comando
gcloud edge-cache services delete cme-demo
Ingresa “Y” para confirmar la eliminación. Cuando se te solicite,
Borra el origen del almacenamiento en caché perimetral:
Comando
gcloud edge-cache origins delete cme-origin
Ingresa “Y” para confirmar la eliminación. 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)")