Transmissão ao vivo no Google Cloud com Media CDN e API Live Streaming

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 próximo dos usuários finais, encerrando conexões mais próximas dos clientes, reutilizando conexões para a origem e adotando protocolos e personalizações de rede modernos. Para os usuários (e nossos clientes), isso significa latência menor, mais confiabilidade e custo reduzido, o que leva a melhores vendas, experiência na Web e um aumento líquido na experiência do usuário. Atualmente, poucos sites e plataformas de streaming de vídeo modernos operam sem uma CDN.

O que você vai aprender

Neste laboratório, vamos orientar você pelas etapas para implantar 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 de vídeos) + Video Player (VLC, Google Shaka Player etc. - HLS + MPEG-DASH pronto para uso).

Vamos configurar os componentes da API Live Streaming (entrada, canal) e iniciar um feed ao vivo para a entrada/canal com o FFmpeg, que pode gerar um sinal de teste ao vivo. A API Live Streaming vai transcodificar o feed ao vivo. 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 pelo Media CDN. Também vamos configurar um painel do Cloud Monitoring para visualizar a atividade da Media CDN.

O que você vai criar

Neste laboratório, vamos configurar o ambiente com base na seguinte arquitetura:

de33cb3e75d52549.png

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 em tempo real.
  • Configurar a API Live Stream 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 o Media CDN com o bucket do GCS como origem
  • Configurar o FFmpeg para alimentar o canal ao vivo
  • Transmitir o feed ao vivo transcodificado com um player de vídeo
  • Configurar um painel do Cloud Monitoring para monitorar a atividade do Media CDN (latência, acerto de cache, falha de cache etc.)

Observação: para este laboratório, presumimos que os usuários tenham acesso ao console do Google Cloud e já tenham uma configuração de projeto. Também presumimos que os usuários comecem com um ambiente novo e não tenham nada configurado para esta demonstração.

Todas as ações de configuração serão realizadas na linha de comando do Cloud Shell. É possível verificar os componentes configurados pela linha de comando no console. Vamos encontrar indicadores ao longo do laboratório que apontam para o console do Google Cloud.

2. Antes de começar

O acesso à CDN de mídia é restrito. Para ter acesso ao Media CDN, entre em contato com sua equipe de contas. Ele pode criar uma solicitação de acesso em seu nome. Se você faz parte do Google e quer testar o recurso de transmissão ao vivo com o Media CDN, entre em contato com o gerente de projeto 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:

55efc1aaa7a4d3ad.png

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:

7ffe5cbb04455448.png

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 do Google Cloud

No momento da escrita, 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 do Google Cloud. Antes de continuar, verifique se o Cloud Shell está usando a versão mais recente do SDK.

Como 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

  1. Se a versão do SDK for 408.0.0 ou mais recente, pule para a próxima seção.
  2. 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, precisamos fazer o seguinte:

  1. Configurar as variáveis de ambiente.
  2. Ativar as APIs de serviço necessárias

1. Configurar as 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 de entrada
  • ID do canal

ID do projeto e nome do 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. Devemos encontrar 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 obrigatórias

Precisamos garantir que as seguintes APIs estejam ativadas no 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 este 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. Quatro APIs vão aparecer na saída.

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:

  1. Criar um bucket do Cloud Storage
  2. 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 armazenamento de origem para o serviço do 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 publicamente acessível

Usaremos 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 Stream

Os componentes da cadeia da API Live Streaming são estruturados da seguinte maneira:

96b5d26aedeb89a6.png

Criamos o bucket live-streaming-storage-$LOGNAME do Cloud Storage na seção anterior. Nas próximas duas seções, vamos criar os seguintes recursos:

  • Entrada de transmissão ao vivo:é um endpoint para o qual o codificador envia o stream de entrada. É possível usar o endpoint de entrada para especificar configurações do stream, como resolução, tipo de entrada e corte de vídeo.
  • Canal de transmissão ao vivo:é um recurso que processa o stream de entrada por um endpoint de entrada, transcodifica o stream de entrada em várias versõ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 de backup no mesmo canal.

Vamos criar os seguintes recursos mais tarde no laboratório:

  • Codificador:um programa usado para enviar streams 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 da transmissão ao vivo. Neste laboratório, estamos usando o sinal RTMP ao vivo.

Comando

cat > input.json << EOF
{
  "type": "RTMP_PUSH"
}
EOF

Criar o endpoint de entrada

No momento da elaboração deste laboratório, 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 nos concentrar 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 do exemplo de saída. Ele pode ser encontrado na linha de saída que começa com "name". "operation-1661405972853-5e70a38d6f27f-79100d00-310671b4"
  • Status:precisamos aguardar a mudança do status de "done": false para "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é que "done:true" seja exibido, 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. Opcionalmente, você também pode usar 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 que consiste em uma única renderização de alta definição (1280x720). O canal será associado ao endpoint de entrada e ao bucket de armazenamento criado 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 comando curl a seguir 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. Ele pode ser encontrado na linha de saída que começa com "name".

Verificar o status

Antes de continuar, 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é que "done:true" seja exibido, indicando que o endpoint de entrada foi criado e está pronto.

O "streamingState" no momento é "STOPPED" . Vamos iniciar o canal na próxima seção.

10. Iniciar o canal de transmissão ao vivo

Agora que criamos o canal de transmissão ao vivo, vamos iniciá-lo. Nesta seção, vamos fazer o seguinte:

  1. Iniciar o canal de transmissão ao vivo
  2. Verifique o status do canal. Precisamos garantir que o streamingState esteja "AWAITING INPUT".

1. Iniciar o canal

No Cloud Shell, execute o comando curl a seguir 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é que a mensagem "AWAITING_INPUT" apareça, indicando que o canal está em execução e pronto para receber um sinal.

11. Configurar o Media CDN

Nesta seção, vamos implantar o Media CDN, a infraestrutura do CDN. Vamos criar os seguintes recursos:

  1. Origem do armazenamento em cache de borda
  2. Serviço de armazenamento em cache de borda

1. Criar uma origem do armazenamento em cache de borda

Uma origem de 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 a origem do conteúdo que queremos distribuir está localizada, por exemplo, todos os CSS, Javascripts, HTMLs, 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 um 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 cache próximo dos usuários finais configurada, podemos criar o serviço do cache próximo dos usuários finais.

Crie o arquivo cme-demo.yaml.

A configuração do serviço de armazenamento em cache próximo dos usuários finais é feita 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 linhas a seguir 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 todas as configurações padrão do serviço de armazenamento em cache do Edge. No arquivo acima, há três valores de campo que os usuários podem atualizar:

  • name: o nome da instância do Media CDN. Neste caso: cme-demo
  • hosts: a lista de nomes de domínio que serão resolvidos por esse serviço do Media CDN: demo.cme.com. Vamos usar isso durante a demonstração. Vamos usar o endereço IP da instância do Media CDN.
  • Origin: é a origem do armazenamento em cache de borda que criamos na etapa anterior. Defina como cme-origin: nome da origem do 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ção do serviço de cache do Edge.

Criar o serviço do cache próximo dos usuários finais

Vamos criar um serviço de cache de borda chamado cme-demo na origem do 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

Pode levar alguns minutos para criar o serviço de cache do Edge.

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 do cache próximo dos usuários finais: 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 do cache próximo dos usuários finais

Nesse ponto, é recomendável atualizar a configuração do serviço de cache do Edge para poder usar o IP do serviço para 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/IPs de hosts que o serviço vai aceitar. Neste ponto, especificamos apenas demo.cme.com como host. Para fornecer a resolução de nomes para esse domínio, você pode configurar uma zona 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 como o exemplo abaixo:

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 importar o arquivo YAML novamente. No terminal do Cloud Shell, execute o seguinte comando:

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 vai 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:

  1. Instale o FFmpeg, um software de código aberto sem custo financeiro
  2. 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 transmissões multimídia. No terminal do Cloud Shell, use o seguinte comando para instalar o FFmpeg:

Comando

sudo apt install ffmpeg -y

Quando a instalação for concluída, vamos verificar se o FFmpeg foi instalado corretamente, verificando a versão dele:

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 sinal da 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 para gerar a transmissão ao vivo.

No terminal do Cloud Shell, execute o comando a seguir usando a variável de ambiente URI criada 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. O comando não vai retornar o prompt. O sinal será gerado até que você o pare. Você vai precisar abrir uma nova janela do Cloud Shell para o restante do laboratório.

13. Abrir o Novo Cloud Shell

Nesse ponto, você vai precisar abrir uma nova janela do Cloud Shell para continuar o laboratório, já que o FFmpeg vai ser executado permanentemente até que você pressione <CTRL+C> no comando para interromper a geração de sinal em tempo real.

Clique no sinal de "+" ao lado do nome do terminal atual do Cloud Shell. Uma janela adicional do Cloud Shell será aberta.

b3c7b0be6276c194.png

Execute o restante do laboratório na janela do Cloud Shell que acabou de abrir.

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. Devemos encontrar 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. A saída vai mostrar 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ê verá "streamingState": "STREAMING", indicando que o canal está sendo transmitido e que o sinal ao vivo está sendo transcodificado.

Vamos verificar o conteúdo do bucket, onde um arquivo de manifesto e vários segmentos de vídeo TS devem aparecer. Execute o comando abaixo no Cloud Shell para listar o conteúdo do bucket criado no início do laboratório e usado pela API Live Streaming para gerar o manifesto de 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, concluímos o seguinte:

  • API Live Streaming: o sinal ao vivo é gerado e transcodificado em um bucket usando a API Live Streaming
  • Media CDN: configure o Media CDN com o bucket de armazenamento do Live Streaming como origem.

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 de anycast da Media CDN.

15. Verificar se a instância do serviço de cache próximo dos usuários finais funciona

Nesta seção, vamos verificar se a instância do serviço de cache do Edge funciona conforme o esperado. Para isso, vamos tentar acessar um arquivo da instância do serviço do cache próximo dos usuários finais usando o endereço IP do serviço do cache próximo dos usuários finais. Na primeira vez que um objeto é acessado, ele ainda não está em cache. Devemos observar um cache MISS. Na primeira solicitação, o objeto é lido na origem e armazenado em cache na borda. Todas as tentativas a seguir de acesso ao mesmo arquivo vão retornar um cache HIT, já que o objeto agora está armazenado em cache na borda. Vamos verificar esse comportamento:

Execute o comando curl abaixo no Cloud Shell para acessar o arquivo de manifesto de vídeo transcodificado armazenado na origem do 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 do Edge para resolver o nome. Use demo.cme.com:<IP>, em que IP é o IP da instância do serviço de cache próximo dos usuários finais 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 do cache, já que o objeto ainda não foi armazenado em cache e é lido na origem.

Agora vamos fazer várias solicitações para o arquivo m3u8. Se tudo estiver configurado corretamente, a CDN de mídia vai começar a veicular o conteúdo do cache. O comando abaixo fará 10 solicitações curl e 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 mistura de hit e miss de cache. 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 hit do cache, já que o objeto agora está armazenado em cache na borda. O serviço de borda do Cloud Media 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-$LOGNAME, que recebe o resultado do sinal ao vivo transcodificado para conteúdo HLS pela API Live Streaming.
  • Configuramos a API Live Stream.
  • Iniciamos um indicador 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 que os arquivos transcodificados resultantes (manifesto + segmentos de TS) foram gerados e armazenados no bucket live-streaming-storage-$LOGNAME.
  • Uma origem do cache próximo dos usuários finais chamada cme-origin foi configurada com o bucket live-streaming-storage-$LOGNAME do GCS como origem.
  • Uma instância do cache Edge chamada cme-demo foi configurada com cme-origin como origem.
  • Verificamos o comportamento (cache miss, cache hit) da instância do serviço de armazenamento em cache de borda.

Agora podemos usar um player de vídeo para transmitir o sinal transcodificado ao vivo pelo cache do Media CDN. Para isso, vamos usar o VLC Player. O VLC Player é um player e framework multimídia de código aberto e sem custo financeiro para várias plataformas 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 vai adaptar a qualidade do vídeo reproduzido. No job de transcodificação que fizemos, usamos as predefinições padrão e geramos apenas duas qualidades: SD e HD. Quando começarmos a reproduzir o vídeo no player, ele vai começar a ser reproduzido no formato SD e mudar rapidamente para o formato HD se a conexão de rede for boa o suficiente.

Vamos transmitir o sinal ao vivo transcodificado do HLS (formato de vídeo amplamente compatível com a Apple). O arquivo correspondente é chamado de main.m3u8, que é o manifesto HLS. O manifesto aponta para os segmentos de vídeo do 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.

2a2d19abe728d222.png

Instale o Player no laptop e inicie-o. Vamos usar a versão MacOSX do player nas próximas etapas.

Para reproduzir um vídeo, acesse "File" / "Open Network":

f85565301f7c68dc.png

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 serviço de mídia do Cloud que você implantou.
  • O caminho para o arquivo de vídeo do manifesto: "/". Esse é o caminho usado no bucket live-streaming-storage-$LOGNAME para armazenar os arquivos de sinal ao vivo transcodificados. O caminho é o caminho raiz aqui: "/".
  • O nome do arquivo de vídeo do 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 ser executado em incrementos de 1, e você vai ouvir um bipe contínuo.

É um indicador básico de transmissão ao vivo RTMP gerado pelo FFmpeg, transcodificado para HLS pela API Live Streaming e veiculado pelo cache do Media CDN:

28fc359b49d44ec2.png

Você pode usar qualquer outro player HLS e MPEG DASH, se quiser. Confira alguns que você pode considerar:

  • Player Quicktime: instalado por padrão nos Macs. Aqui também: abra uma conexão de rede para 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. Monitoramento do Media CDN

A equipe de SME criou um modelo de painel de CDN de mídia: 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 "Media Edge Metrics" vai aparecer. Clique nele para conferir as métricas:

d0821d84a88a928d.png

18. Limpar o ambiente do laboratório

Parabéns por concluir o laboratório. Nesta seção, vamos excluir todos os recursos criados durante o laboratório.

Interromper o sinal 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"

Excluir 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 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/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.

Excluir a origem do armazenamento em cache próximo dos usuários finais:

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)")