1. Introdução
As redes de fornecimento de conteúdo (CDNs) melhoram a performance do usuário armazenando em cache o conteúdo acessado com frequência mais perto dos usuários finais, encerrando as conexões mais perto dos clientes, reutilizando as conexões com a origem e adotando protocolos e personalizações de rede modernos. Para os usuários (e nossos clientes), isso significa menor latência, mais confiabilidade e custo reduzido, o que leva a um aumento nas vendas, na experiência da Web e um aumento líquido na experiência do usuário. Hoje em dia, poucos sites modernos e plataformas de streaming de vídeo operam sem uma CDN.
O que você vai aprender
Este laboratório vai orientar você pelas etapas de implantação de um ambiente de fluxo de trabalho de transmissão ao vivo com Media CDN (CDN) + API Cloud Media Live Streaming (transcodificação de vídeo ao vivo) + Cloud Storage (armazenamento para os vídeos) + Player de vídeo (VLC, Google Shaka Player etc. - player pronto para HLS + MPEG-DASH).
Vamos configurar os componentes da API Live Streaming (entrada e canal) e iniciar um feed publicado para a entrada/canal com o FFmpeg, que pode gerar um sinal de teste em tempo real. A API Live Streaming vai transcodificar o feed publicado. O manifesto e os segmentos de vídeo transcodificados serão armazenados em um bucket do Cloud Storage. Em seguida, vamos configurar o Media CDN com o bucket do Cloud Storage de vídeo ao vivo como origem. Por fim, o VLC Player será usado para reproduzir conteúdo ao vivo armazenado em cache pela Media CDN. Também vamos configurar um painel do Cloud Monitoring para visualizar a atividade da CDN de mídia.
O que você vai criar
Neste laboratório, vamos configurar o ambiente com base na seguinte arquitetura:

Vamos configurar os seguintes componentes e realizar as seguintes tarefas como parte do laboratório:
- Crie um bucket do Google Cloud Storage (GCS) para armazenar os vídeos transcodificados ao vivo.
- Configure a API Live Streaming para transcodificar o vídeo em vários formatos: HLS + MPEG DASH, SD e HD
- Configurar os componentes de transmissão ao vivo: entrada/canal
- Iniciar o canal de transmissão ao vivo
- Configurar a Media CDN com o bucket do GCS como origem
- Configurar o FFmpeg para alimentar o canal ao vivo
- Transmitir o feed publicado transcodificado com um player de vídeo
- Configure um painel do Cloud Monitoring para monitorar a atividade do Media CDN (latência, ocorrência em cache, ausência no cache etc.).
Observação: para este laboratório, presumimos que os usuários têm acesso ao console do Google Cloud e já têm um projeto configurado. Também presumimos que os usuários começam com um ambiente novo e não têm nada configurado para esta demonstração.
Todas as ações de configuração serão feitas pela linha de comando no Cloud Shell. É possível verificar os componentes configurados pela linha de comando no console. Ao longo do laboratório, você vai encontrar indicadores que apontam para o console do Google Cloud.
2. Antes de começar
O acesso à CDN de mídia é restrito. Para ter acesso à Media CDN, entre em contato com a equipe de conta. Ela pode criar uma solicitação de acesso em seu nome. Se você faz parte do Google e quer testar a transmissão ao vivo com o Media CDN, entre em contato com o gerente de produtos do Media CDN para solicitar acesso.
3. Configuração e requisitos
Inicie o Cloud Shell
Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
No Console do Google Cloud, clique no ícone do Cloud Shell na barra de ferramentas superior à direita:

O provisionamento e a conexão com o ambiente levarão apenas alguns instantes para serem concluídos: Quando o processamento for concluído, você verá algo como:

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Neste codelab, todo o trabalho pode ser feito com um navegador. Você não precisa instalar nada.
4. Versão do SDK Google Cloud
No momento da redação deste artigo, 408.0.0 é a versão mais recente do SDK do Google Cloud. Todos os comandos deste laboratório foram testados usando a versão mais recente do SDK Google Cloud. Antes de continuar, verifique se o Cloud Shell está usando a versão mais recente do SDK.
Verificar a versão do SDK
Vamos usar o comando gcloud version para verificar a versão do SDK.
Comando
gcloud version | grep "Google Cloud SDK"
Exemplo de saída
Google Cloud SDK 408.0.0
Próximas etapas
- Se a versão do SDK for
408.0.0ou mais recente, avance para a próxima seção. - Se a versão do SDK for inferior a
408.0.0, execute o comando listado abaixo para atualizar o SDK.
sudo apt-get update && sudo apt-get install google-cloud-sdk
5. Pré-requisitos
Antes de começar a configurar os recursos do GCP, faça o seguinte:
- Configurar as variáveis de ambiente.
- Ativar as APIs de serviço necessárias
1. Configurar variáveis de ambiente
Neste laboratório, vamos executar comandos gcloud e curl com algumas variáveis. Precisamos configurar as seguintes variáveis de ambiente.
- ID do projeto
- Número do projeto
- Nome do usuário
- Região
- ID da entrada
- ID do canal
ID do projeto e nome de usuário
Essas variáveis de ambiente geralmente são pré-configuradas no Cloud Shell. Vamos usar o comando env para verificar.
Comando
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME'
Exemplo de saída
DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME>
Criar o arquivo env_variables
Use o comando cat para criar o arquivo env_variables.txt. O comando abaixo vai criar o arquivo env_variables.txt no diretório inicial do usuário.
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
Configurar as variáveis de ambiente
Vamos usar o comando source para definir as variáveis de ambiente.
Comando
source ~/env_variables.txt
Verificar se as variáveis estão definidas
Vamos verificar se todas as variáveis de ambiente necessárias estão definidas. Vamos ver um total de seis variáveis de ambiente na saída.
Comando
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
Exemplo de saída
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. Ativar as APIs de serviço necessárias
Precisamos garantir que as seguintes APIs estejam ativadas no nosso projeto.
- API Network Services
- API Certificate Manager
- API Livestream
- API Media CDN Edge Cache
Ativar a API Network Services
Para ativar a API Network Services, execute o seguinte comando:
Comando
gcloud services enable networkservices.googleapis.com
Ativar a API Certificate Manager
Para ativar a API Certificate Manager, execute o seguinte comando:
Comando
gcloud services enable certificatemanager.googleapis.com
Ativar a API Live Stream
Para ativar a API Live Stream, execute o seguinte comando:
Comando
gcloud services enable livestream.googleapis.com
Ativar a API Media CDN Edge Cache
Para ativar a API Media CDN Edge Cache, execute o seguinte comando:
Comando
gcloud services enable edgecache.googleapis.com
Verificar se as APIs estão ativadas
Execute o comando gcloud services list para listar todas as APIs ativadas. A saída vai mostrar quatro APIs.
Comando
gcloud services list | grep -E 'networkservices|certificatemanager|livestream|edgecache'
Exemplo de saída
NAME: certificatemanager.googleapis.com NAME: livestream.googleapis.com NAME: networkservices.googleapis.com NAME: edgecache.googleapis.com
6. Criar o bucket do Cloud Storage
Nesta seção, vamos fazer o seguinte:
- Criar um bucket do Cloud Storage
- Torne o bucket acessível publicamente
Mais adiante no laboratório, vamos usar esse bucket para armazenar os arquivos de vídeo transcodificados. Esse bucket também vai atuar como um armazenamento de origem para o serviço Media CDN.
1. Criar o bucket
Vamos usar o comando gsutil mb para criar o bucket:
Comando
gsutil mb gs://live-streaming-storage-$LOGNAME
2. Tornar o bucket acessível publicamente
Vamos usar o comando gsutil iam para disponibilizar os arquivos publicamente:
Comando
gsutil iam ch allUsers:objectViewer gs://live-streaming-storage-$LOGNAME
7. Como configurar o ambiente da API Live Streaming
Os componentes da cadeia da API Live Streaming são arquitetados da seguinte maneira:

Criamos o bucket do Cloud Storage live-streaming-storage-$LOGNAME na seção anterior. Nas próximas duas seções, vamos criar os seguintes recursos:
- Entrada de transmissão ao vivo:um endpoint de entrada é um endpoint para o qual o codificador envia o fluxo de entrada. É possível usar o endpoint de entrada para especificar configurações da sua transmissão, como resolução, tipo de entrada e corte de vídeo.
- Canal de transmissão ao vivo:um canal é um recurso que ingere o stream de entrada por um endpoint de entrada, transcodifica o stream de entrada em várias renderizações e publica transmissões ao vivo de saída em determinados formatos no local especificado. É possível incluir um stream de entrada principal e um de backup no mesmo canal.
Vamos criar os seguintes recursos mais tarde no laboratório:
- Codificador:um programa usado para enviar fluxos de entrada. Neste laboratório, vamos usar o FFmpeg.
8. Criar e configurar o endpoint de entrada
Criar o arquivo input.json
Vamos criar um arquivo input.json para especificar o tipo de sinal de transmissão ao vivo. Neste laboratório, usamos o sinal de transmissão ao vivo RTMP.
Comando
cat > input.json << EOF
{
"type": "RTMP_PUSH"
}
EOF
Criar o endpoint de entrada
No momento em que este laboratório foi escrito, não há suporte do gcloud para a API Live Stream. Vamos usar o comando curl para fazer as chamadas de 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"
Exemplo de saída
{
"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
}
A saída tem muitas informações úteis, mas, no momento, precisamos focar em dois campos:
- ID da operação:na saída, copie e anote o ID da operação. Confira abaixo o ID da operação no exemplo de saída. Isso pode ser encontrado na linha de saída que começa com
"name"."operation-1661405972853-5e70a38d6f27f-79100d00-310671b4" - Status:aguarde a mudança do status de
"done": falsepara"done": true.
Verificar o status
Antes de prosseguir, precisamos verificar se o endpoint de entrada foi criado e está pronto.
No comando abaixo, substitua <OPERATION> pelo ID da operação que acabamos de receber acima. Neste exemplo, é "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"
Exemplo de saída
{
"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"
}
}
Execute o comando novamente até ver "done:true", indicando que o endpoint de entrada foi criado e está pronto.
Salvar o URI
Vamos usar o URI da saída anterior mais adiante no laboratório. Agora, vamos definir uma variável de ambiente para o URI.
Comando
export URI=<uri>
Substitua <uri> pelo URI que você anotou acima. Se quiser, use o método GET para recuperar o 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. Criar e configurar o canal de transmissão ao vivo
Vamos criar o canal de transmissão ao vivo associado ao endpoint de entrada que criamos na seção anterior. O exemplo a seguir cria um canal que gera uma transmissão ao vivo HLS com uma única renderização de alta definição (1280x720). O canal será associado ao endpoint de entrada e ao bucket de armazenamento que criamos anteriormente.
Criar o arquivo channel.json
No terminal do Cloud Shell, digite o seguinte comando para criar um arquivo "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
Criar o canal
Execute o seguinte comando curl para criar o 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"
Exemplo de saída
{
"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
}
Anote e copie o ID da operação. Vamos precisar dele em uma das próximas etapas. Isso pode ser encontrado na linha de saída que começa com "name".
Verificar o status
Antes de prosseguir, precisamos verificar se o canal foi criado e está pronto.
No comando abaixo, substitua <OPERATION> pelo ID da operação que acabamos de receber acima. Neste exemplo, é 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"
Exemplo de saída
"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"
}
}
}
Execute o comando novamente até ver "done:true", indicando que o endpoint de entrada foi criado e está pronto.
No momento, o "streamingState" é "STOPPED". Vamos iniciar o canal na próxima seção.
10. Iniciar o canal de transmissão ao vivo
Agora que criamos nosso canal de transmissão ao vivo, vamos iniciá-lo. Nesta seção, vamos fazer o seguinte:
- Iniciar o canal de transmissão ao vivo
- Verifique o status do canal para garantir que o
streamingStateseja"AWAITING INPUT".
1. Iniciar o canal
No Cloud Shell, execute o seguinte comando curl para iniciar o 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"
Exemplo de saída
{
"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. Verificar o status do canal
Execute o comando curl a seguir para conferir o status do 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"
Exemplo de saída
"streamingState": "AWAITING_INPUT",
Execute o comando novamente até ver "AWAITING_INPUT", indicando que o canal está em execução e pronto para receber um sinal.
11. Configurar o Media CDN
Nesta seção, vamos implantar a Media CDN, a infraestrutura de CDN. Vamos criar os seguintes recursos:
- Origem do armazenamento em cache de borda
- Serviço de armazenamento em cache de borda
1. Criar uma origem do armazenamento em cache de borda
Uma origem do armazenamento em cache de borda representa um local de conteúdo, como um bucket do Cloud Storage, um local de armazenamento de terceiros ou um balanceador de carga. Em termos de CDN, a origem (ou servidor de origem) é o local onde está a fonte do conteúdo que queremos distribuir, por exemplo, todos os CSS, JavaScripts, HTML, imagens etc. Para este laboratório, vamos criar uma origem que mapeia para o bucket do Cloud Storage criado no início do laboratório. Vamos chamar a origem do armazenamento em cache de borda de cme-origin. A origem de uma CDN é onde todo o conteúdo de origem é armazenado antes de ser distribuído para os servidores de cache de borda.
Vamos usar o comando gcloud edge-cache origins create para criar a origem. A execução do comando leva alguns minutos.
Comando
gcloud edge-cache origins create cme-origin \ --origin-address="gs://live-streaming-storage-$LOGNAME"
Exemplo de resposta
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. Criar um serviço de armazenamento em cache de borda
Agora que temos uma origem do armazenamento em cache de borda configurada, podemos criar o serviço de cache próximo dos usuários finais.
Crie o arquivo cme-demo.yaml.
As configurações do serviço de cache de borda são feitas por um arquivo YAML. No Cloud Shell, crie um arquivo local chamado cme-demo.yaml. Use vi, nano ou qualquer outro editor e cole as seguintes linhas no arquivo 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
Vamos deixar todos os padrões de configurações de serviço do Edge Cache Service. No arquivo acima, há três valores de campo que os usuários podem querer atualizar:
name: o nome da instância do Media CDN. Aqui:cme-demohosts:a lista de nomes de domínio que serão resolvidos por este serviço do Media CDN. Aqui:demo.cme.com. Vamos usar isso durante esta demonstração. Vamos usar o endereço IP da instância do Media CDN.Origin:: é a origem do armazenamento em cache de borda que acabamos de criar na etapa anterior. Defina comocme-origin, o nome da origem da CDN de mídia.
Para mais informações sobre as diferentes variáveis que podem ser usadas no arquivo YAML, consulte o guia de configurações de serviço do Edge Cache Service.
Criar o serviço de cache próximo dos usuários finais
Vamos criar um serviço de cache de borda chamado cme-demo na origem do armazenamento em cache de borda cme-origin com o host demo.cme.com. Para criar o serviço, execute o seguinte comando no Cloud Shell:
Comando
gcloud edge-cache services import cme-demo \
--source=cme-demo.yaml
A criação do serviço de cache de borda pode levar alguns minutos.
Exemplo de saída
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'
Anote e copie o ipv4Addresses da instância do serviço de cache próximo dos usuários finais. Aqui, 34.104.36.157. Vamos usá-lo para atualizar o arquivo cme-demo.yaml e, mais tarde, para transmitir o vídeo transcodificado.
Atualizar o serviço de armazenamento em cache de borda
Neste ponto, é recomendável atualizar as configurações de serviço do Edge Cache Service para usar o IP do serviço e transmitir o vídeo mais tarde. O arquivo YAML do serviço de armazenamento em cache próximo dos usuários finais permite listar todos os nomes de hosts/IPs de que o serviço aceitará solicitações. Neste momento, especificamos apenas demo.cme.com como host. Para fornecer resolução de nome para esse domínio, configure uma zona de DNS. No entanto, uma solução mais fácil seria adicionar o endereço IP à lista de hosts no arquivo yaml. Edite o arquivo YAML novamente para que ele fique assim:
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 refletir as mudanças, basta reimportar o arquivo YAML. No terminal do Cloud Shell, execute o comando a seguir:
Comando
gcloud edge-cache services import cme-demo \
--source=cme-demo.yaml
Verifique a saída do comando e confira se o IP aparece na lista de hosts.
Nesse ponto, a instância do serviço de cache de borda aceitará solicitações com "demo.cme.com" ou o endereço IP como host.
12. Gerar o indicador de entrada
Agora que configuramos todos os serviços necessários, vamos gerar o sinal de entrada da transmissão ao vivo. Nesta seção, vamos fazer o seguinte:
- Instale o FFmpeg, um software livre de código aberto
- Enviar um sinal de teste em tempo real para a entrada/canal
1. Instalar o FFmpeg
O FFmpeg é um projeto de software sem custo financeiro e de código aberto que consiste em um conjunto de bibliotecas e programas para processar vídeos, áudios e outros arquivos e streams multimídia. No terminal do Cloud Shell, use o comando a seguir para instalar o FFmpeg:
Comando
sudo apt install ffmpeg -y
Quando a instalação for concluída, verifique se o FFmpeg foi instalado corretamente conferindo a versão:
Comando
ffmpeg -version
Exemplo de saída
ffmpeg version 4.3.4-0+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 10 (Debian 10.2.1-6) ...
O FFmpeg foi instalado corretamente.
2. Inicie o Live Stream Signal to the Input/Channel (Sinal de transmissão ao vivo para a entrada/canal).
Agora que o FFmpeg está instalado, vamos enviar um stream de entrada de teste para o endpoint de entrada e gerar a transmissão ao vivo.
No terminal do Cloud Shell, execute o comando a seguir usando a variável de ambiente URI que criamos na seção "Criar e configurar o endpoint de entrada".
Comando
ffmpeg -re -f lavfi -i "testsrc=size=1280x720 [out0]; sine=frequency=500 [out1]" \ -acodec aac -vcodec h264 -f flv $URI
O FFmpeg vai enviar o sinal de teste ao vivo. O comando não vai retornar o aviso. O indicador será gerado até que você o interrompa. Você precisará abrir uma nova janela do Cloud Shell para o restante do laboratório.
13. Abrir o novo Cloud Shell
Neste ponto, você precisará abrir uma nova janela do Cloud Shell para continuar o laboratório, já que o FFmpeg será executado permanentemente até que você pressione <CTRL+C> para interromper o comando e, assim, interromper a geração de sinal ao vivo.
Clique no sinal de "+" ao lado do nome do terminal atual do Cloud Shell. Isso vai abrir outra janela do Cloud Shell.

Execute o restante do laboratório na janela do Cloud Shell que acabou de ser aberta.
Configurar as variáveis de ambiente
Como este é um novo Cloud Shell, precisamos definir as variáveis de ambiente novamente. Vamos usar o comando source para definir as variáveis de ambiente.
Comando
source ~/env_variables.txt
Verificar se as variáveis estão definidas
Vamos verificar se todas as variáveis de ambiente necessárias estão definidas. Vamos ver um total de seis variáveis de ambiente na saída.
Comando
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
Exemplo de saída
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. Verificar se o sinal ao vivo está sendo transcodificado
Vamos executar um curl para descrever o canal. Na saída, vamos ver que o streamingState mudou de "AWAITING_INPUT" para "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"
Na resposta do arquivo JSON de saída, você vai encontrar "streamingState": "STREAMING", indicando que o canal está transmitindo e o sinal ao vivo está sendo transcodificado.
Vamos também verificar o conteúdo do bucket, onde um arquivo de manifesto e vários segmentos de vídeo TS devem aparecer. Execute o comando a seguir no Cloud Shell para listar o conteúdo do bucket que criamos no início do laboratório e que é usado pela API Live Streaming para gerar o manifesto do sinal ao vivo transcodificado e os segmentos de vídeo TS:
Comando
gcloud storage ls --recursive gs://live-streaming-storage-$LOGNAME/**
Exemplo de saída
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 ...
Você verá:
- o arquivo de manifesto HLS:
main.m3u8 - Os segmentos de vídeo TS correspondentes: uma série de arquivos numerados
segment-000000000X.ts
Neste ponto, já concluímos o seguinte:
- API Live Streaming: o sinal ao vivo é gerado e transcodificado em um bucket pela API Live Streaming.
- Media CDN: configuramos o Media CDN com o bucket de armazenamento do Live Streaming como origem do Media CDN.
Nas próximas seções, vamos validar o serviço de cache de borda e transmitir o vídeo transcodificado usando o endereço IP anycast da Media CDN.
15. Verificar se a instância do serviço de cache de borda funciona
Nesta seção, vamos verificar se a instância do serviço de cache de borda funciona conforme o esperado. Para isso, vamos tentar acessar um arquivo da instância do serviço de cache próximo dos usuários finais usando o endereço IP do serviço de cache próximo dos usuários finais. Na primeira vez que um objeto é acessado, ele ainda não está em cache. Vamos observar um cache MISS. Na primeira solicitação, o objeto é lido da origem e armazenado em cache na borda. Todas as tentativas a seguir de acessar o mesmo arquivo vão retornar um cache HIT, já que o objeto agora está em cache na borda. Vamos verificar esse comportamento:
Execute o seguinte comando curl no Cloud Shell para acessar o arquivo de manifesto de vídeo transcodificado armazenado na origem do armazenamento em cache de borda:
Comando
curl -svo /dev/null --resolve demo.cme.com:80:<Replace_With_Edge_Cache_IP> \ "http://demo.cme.com/main.m3u8"
Observe a resolução em que usamos o endereço IP da instância do serviço de cache de borda para resolver o nome dela. Use demo.cme.com:<IP>, em que IP é o IP da instância do serviço de armazenamento em cache de borda que acabamos de criar.
Procure o cabeçalho x-cache-status na saída.
Exemplo de saída
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
Observe a falha de cache, já que o objeto ainda não foi armazenado em cache e é lido da origem.
Agora vamos fazer várias solicitações para o arquivo m3u8. Se tudo estiver configurado corretamente, a Media CDN vai começar a veicular o conteúdo do cache. O comando abaixo fará 10 solicitações curl e vai imprimir apenas o cabeçalho 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
A saída precisa ser uma combinação de cache hit e miss. Se você encontrar acertos de cache na saída, o Media CDN está funcionando conforme o esperado.
Exemplo de saída
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
Observe o acerto de cache, já que o objeto agora está armazenado em cache na borda. O serviço Cloud Media Edge está funcionando conforme o esperado.
16. Fazer streaming de vídeo de sinal ao vivo transcodificado com o VLC
Esta é a parte em que conectamos os pontos e vinculamos todas as etapas em que trabalhamos até agora:
- Criamos um bucket chamado
live-streaming-storage-$LOGNAMEque recebe o resultado do sinal ao vivo transcodificado para conteúdo HLS pela API Live Streaming. - Configuramos a API Live Streaming.
- Iniciamos um sinal RTMP ao vivo com o FFmpeg que alimenta a entrada/canal da API Live Streaming.
- Verificamos que o sinal ao vivo foi enviado ao canal e que ele estava no modo
streaming. - Verificamos se os arquivos transcodificados resultantes (manifesto + segmentos TS) foram gerados e armazenados no bucket
live-streaming-storage-$LOGNAME. - Uma origem do armazenamento em cache de borda chamada
cme-originfoi configurada com o bucket do GCSlive-streaming-storage-$LOGNAMEcomo origem. - Uma instância do Edge Cache chamada
cme-demofoi configurada comcme-origincomo origem. - Verificamos o comportamento (ausência no cache, ocorrência em cache) da instância do serviço de armazenamento em cache de borda.
Agora podemos usar um player de vídeo para transmitir o sinal ao vivo transcodificado pelo cache da Media CDN. Para isso, vamos usar o VLC Player. O VLC Player é um player e framework multimídia multiplataforma sem custo financeiro e de código aberto que reproduz a maioria dos arquivos multimídia. Ele reproduz formatos de mídia adaptáveis, como DASH e HLS. Ele usa o princípio do streaming adaptável. De acordo com a qualidade da sua conexão de rede e a largura de banda disponível, o player adapta a qualidade do vídeo reproduzido. No job de transcodificação que acabamos de fazer, usamos as predefinições padrão e geramos "apenas" duas qualidades: SD e HD. Quando o vídeo começar a ser reproduzido no player, ele vai começar no formato SD e mudar rapidamente para HD se a conexão de rede for boa o suficiente.
Vamos transmitir o sinal ao vivo transcodificado em HLS, um formato de vídeo da Apple amplamente aceito. O arquivo correspondente é chamado de main.m3u8, que é o manifesto HLS. O manifesto aponta para os segmentos de vídeo TS.
Para usar o VLC Player, acesse https://www.videolan.org/vlc/ e faça o download de uma versão do player para o sistema operacional do seu laptop. O VLC está disponível para Windows, MacOSX, Linux, Android e iOS.

Instale e inicie o Player no seu laptop. Vamos usar a versão MacOSX do player nas próximas etapas.
Para reproduzir um vídeo, acesse "Arquivo" / "Abrir rede":

Configure com:
- URL: http://<Replace_With_Edge_Cache_IP>/main.m3u8. Esse é o URL do vídeo que queremos transmitir. Aviso:
- O IP da instância do Media CDN:
34.105.35.246. Substitua pelo IP do Cloud Media Service implantado. - O caminho para o arquivo de vídeo de manifesto: "
/". Esse é o caminho que usamos no bucketlive-streaming-storage-$LOGNAMEpara armazenar os arquivos de sinal ao vivo transcodificados. O caminho é o caminho raiz aqui: "/". - O nome do arquivo de vídeo de manifesto: o arquivo de manifesto HLS,
main.m3u8.
e clique em "Abrir". O vídeo ao vivo transcodificado vai começar a ser reproduzido. O vídeo vai ficar parecido com a captura de tela abaixo. O contador na tela vai aumentar em incrementos de 1, e você vai ouvir um bipe contínuo.
É um sinal básico de teste ao vivo RTMP gerado pelo FFmpeg, transcodificado para HLS pela API Live Streaming e veiculado pelo cache do Media CDN:

Você pode usar qualquer outro player HLS e MPEG DASH, se quiser. Confira algumas opções:
- Quicktime Player: instalado por padrão em Macs. Faça o mesmo: abra uma conexão de rede com http://34.104.36.157/main.m3u8. Substitua o endereço IP pelo da sua instância do serviço de cache do Edge.
17. Monitorar o Media CDN
A equipe de PMEs criou um modelo de painel do Media CDN: https://gist.github.com/elithrar/1c511d00f5cd3736fb2a3897867209c1.
Para instalar, execute os seguintes comandos na janela do Cloud Shell:
Faça o download do arquivo YAML:
curl https://gist.githubusercontent.com/elithrar/1c511d00f5cd3736fb2a3897867209c1/raw/3cb70855304f29e5c06b8d63063196354db0dec3/media-edge-20210208-dashboard --output media-edge-20210208-dashboard.yaml
Crie o painel do Cloud Monitoring:
gcloud monitoring dashboards create --config-from-file media-edge-20210208-dashboard.yaml
A configuração pode levar alguns minutos. Acesse o console do Google Cloud e clique nas três barras > Operações > Monitoramento > Painéis. Um painel chamado "Métricas do Media Edge" vai aparecer. Clique nele para ver as métricas:

18. Limpar o ambiente do laboratório
Parabéns por concluir o laboratório. Nesta seção, vamos excluir todos os recursos criados ao longo do laboratório.
Parar o indicador do FFmpeg:
Pressione <CTRL+C> no terminal do Cloud Shell em que o FFmpeg está sendo executado.
Parar o canal de transmissão ao 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"
Exclua o canal de transmissão ao 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"
Exclua o endpoint de entrada da transmissão ao 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"
Exclua o bucket do GCS:
Comando
gsutil rm -r gs://live-streaming-storage-$LOGNAME
Exclua a instância do serviço de armazenamento em cache próximo dos usuários finais:
Comando
gcloud edge-cache services delete cme-demo
Confirme a exclusão digitando "Y" quando solicitado.
Exclua a origem do armazenamento em cache de borda:
Comando
gcloud edge-cache origins delete cme-origin
Confirme a exclusão digitando "Y" quando solicitado.
Excluir o painel personalizado
Comando
gcloud monitoring dashboards delete $(gcloud monitoring dashboards list --filter="displayName:Media Edge Metrics" --format="value(name)")