Streaming de Video com o Raspberry Pi

Transformando o Raspberry Pi num Encoder de Vídeo H.264: Do Conceito ao Streaming

O Raspberry Pi é muito mais do que um microcomputador para emulação de jogos ou automação residencial. Devido à sua arquitetura eficiente e periféricos dedicados, ele é uma ferramenta excelente para o processamento de vídeo digital.

Neste artigo, vamos explorar como transformar um Raspberry Pi e uma Pi Camera num Encoder H.264 capaz de capturar imagem, comprimi-la em tempo real e transmiti-la (stream) para um PC remoto através da rede.

1. Base Teórica: O que acontece “nos bastidores”?

Antes de ligarmos os cabos, é fundamental entender três conceitos chave: Codificação (Encoding), O Codec H.264 e a Aceleração por Hardware.

O Desafio do Vídeo “Raw”

Uma câmara digital captura uma sequência de imagens (frames). Se tentássemos enviar estas imagens sem compressão pela rede, a largura de banda necessária seria enorme.

Por exemplo, um vídeo 1080p a 30fps em formato RGB necessita de aproximadamente:

1920 x 1080 pixels x 3 bytes (cor) x 30 fps = 186 MB/s

Isto equivale a cerca de 1.5 Gbps, o que saturaria instantaneamente uma rede Wi-Fi comum e até muitas redes Ethernet. A compressão é essencial!

O Codec H.264 (AVC)

O H.264 (Advanced Video Coding) é o padrão da indústria para compressão de vídeo. Ele reduz o tamanho do ficheiro drasticamente usando dois tipos de compressão:

  1. Intra-frame (Espacial): Comprime a imagem individualmente (semelhante ao JPEG), removendo redundâncias dentro do próprio frame.
  2. Inter-frame (Temporal): Esta é a magia! O encoder analisa o que mudou entre o frame atual e o anterior. Se o fundo é estático e apenas uma pessoa se move, o H.264 guarda apenas a informação do movimento (“vetores de movimento”) e não a imagem toda novamente.

Aceleração por Hardware no Raspberry Pi

Codificar H.264 matematicamente é muito pesado para um CPU (Processador) de uso geral.

  • Raspberry Pis 3 e 4: Possuem módulos de hardware específicos na GPU (VideoCore) dedicados exclusivamente a codificar H.264. Isto liberta o CPU para outras tarefas.
  • Raspberry Pi 5: Removeu-se o encoder de hardware H.264 (mantendo apenas o descodificador). No Pi 5, a codificação é feita por software (CPU), mas como o CPU é mais potente, ele aguenta a carga sem problemas.
  • Pi Zero 2 W: Também possui o encoder de hardware.

Neste guia, utilizaremos a stack moderna de câmaras do Raspberry Pi (libcamera / rpicam-apps), que gere automaticamente o uso do hardware.

2. Requisitos de Hardware

Para seguir este tutorial, necessitas de:

  • Raspberry Pi: Modelos 3B+, 4B ou Zero 2 W são ideais (pelo encoder de hardware). O Pi 5 também funciona perfeitamente via software.
  • Raspberry Pi Camera Module: V2 (8MP), V3 (Wide ou Normal), ou a HQ Camera.
  • Cabo Ribbon da Câmara: Certifica-te que tens o cabo correto (o Pi Zero usa um cabo mais estreito que o Pi 4).
  • PC Cliente: Um computador (Windows, Mac ou Linux) com o VLC Media Player ou FFplay (parte do FFmpeg) instalado.
  • Rede: Ligação Wi-Fi ou Ethernet (Ethernet é preferível para menor latência).

3. Preparação do Sistema

Vamos assumir que tens o Raspberry Pi OS (Bookworm ou Bullseye) instalado. As versões “Legacy” (Buster) usam comandos antigos (raspivid) que não abordaremos aqui, pois estão obsoletos.

Passo 1: Ligação do Hardware

  1. Desliga o Raspberry Pi.
  2. Levanta a patilha preta do porto “CSI” (Camera Serial Interface).
  3. Insere o cabo da câmara com os contactos metálicos virados para o lado oposto da patilha (nos Pi 3/4, contactos virados para a porta HDMI; no Pi Zero, virados para a placa).
  4. Liga o Pi.

Passo 2: Atualização e Configuração

Abre o terminal no Raspberry Pi (ou via SSH) e executa:

sudo apt update && sudo apt full-upgrade -y

No Raspberry Pi OS moderno, a câmara é detetada automaticamente. Podes verificar se o sistema reconhece a câmara com o comando:

rpicam-hello --list-cameras

(Nota: Em versões anteriores do OS, este comando pode chamar-se libcamera-hello --list-cameras).

Se vires a descrição da tua câmara, estás pronto para prosseguir.


4. O Encoder: Criando o Stream

O nosso objetivo é: Capturar -> Codificar em H.264 -> Enviar para a Rede (TCP).

Usaremos a ferramenta rpicam-vid. Esta ferramenta é poderosa porque permite fazer “pipe” (canalizar) a saída de vídeo diretamente para o stdout (saída padrão) e daí para a rede.

O Comando do Servidor (Raspberry Pi)

Vamos usar o protocolo TCP para simplicidade e garantia de entrega de pacotes. Executa o seguinte comando no terminal do Pi:

rpicam-vid -t 0 --inline --width 1280 --height 720 --framerate 30 --listen -o tcp://0.0.0.0:3333

Explicação do comando:

  • rpicam-vid: A aplicação de vídeo oficial.
  • -t 0: Tempo de gravação infinito (0 = para sempre).
  • --inline: Crucial para streaming. Insere cabeçalhos SPS/PPS em cada I-frame. Sem isto, quem se ligar ao stream a meio não conseguirá descodificar o vídeo até o próximo cabeçalho.
  • --width 1280 --height 720: Define a resolução (720p é um bom equilíbrio entre qualidade e latência).
  • --framerate 30: Define 30 frames por segundo.
  • --listen: Diz ao Pi para agir como servidor e esperar por uma conexão.
  • -o tcp://0.0.0.0:3333: Envia a saída (output) para a porta TCP 3333 em todos os interfaces de rede disponíveis.

Após executares o comando, o terminal ficará “parado”, à espera de uma conexão do PC.


5. O Cliente: Acedendo ao Stream (PC Remoto)

Agora, vai ao teu computador pessoal. Precisas de saber o Endereço IP do teu Raspberry Pi (usa hostname -I no Pi para descobrir, ex: 192.168.1.50).

Tens duas opções principais para ver o vídeo:

Opção A: Usando VLC (Interface Gráfica) – Mais Fácil

  1. Abre o VLC Media Player.
  2. Vai a Media -> Open Network Stream (ou Ctrl+N).
  3. Insere o URL: tcp/h264://192.168.1.50:3333 (Substitui pelo IP correto).
  4. Clica em Play.

Nota: O VLC pode ter um “buffer” (atraso) de 1 a 2 segundos por predefinição para garantir suavidade.

Opção B: Usando FFplay (Linha de Comandos) – Menor Latência

Se tiveres o FFmpeg instalado no teu PC, o ffplay oferece uma latência muito menor (perto do tempo real).

Abre o terminal/cmd no teu PC e corre:

ffplay -fflags nobuffer -flags low_delay -framedrop tcp://192.168.1.50:3333
  • -fflags nobuffer: Diz ao player para não acumular dados antes de mostrar.
  • -flags low_delay: Otimiza para baixa latência.

6. Otimização Avançada: Baixa Latência com UDP

O método TCP acima é fiável (não há “glitches” na imagem), mas se a rede falhar, o vídeo atrasa-se para recuperar os dados perdidos. Se o teu objetivo for controlar um robot ou drone (FPV), precisas de UDP. O UDP não verifica se os pacotes chegaram; ele apenas “dispara”. É mais rápido, mas pode haver falhas visuais.

No Raspberry Pi (Servidor):

Vamos usar o netcat (ou socat) para enviar os dados brutos via UDP, pois o rpicam-vid lida melhor com TCP nativamente, ou usamos o GStreamer. Mas para manter simples, vamos manter o rpicam-vid e enviar para o endereço do PC.

Nota: No método UDP simples, o Pi tem de saber o IP do PC para onde enviar.

rpicam-vid -t 0 --inline -o - | nc -u 192.168.1.XX 5000

(Substitui 192.168.1.XX pelo IP do teu PC).

No PC (Cliente – FFplay):

ffplay -f h264 udp://0.0.0.0:5000

Resumo Técnico

ComponenteFunção no Projeto
Sensor (IMX219/etc)Captura fotões e converte em sinal Bayer (Raw).
ISP (Image Signal Processor)Converte Bayer em YUV, ajusta cores, balanço de brancos.
Encoder (H.264)Comprime o YUV usando vetores de movimento (Inter-frame).
Transporte (TCP/IP)Encapsula o H.264 em pacotes de rede.
Cliente (PC)Recebe pacotes, remonta o stream H.264 e descodifica para visualização.

7. Encapsulamento Web (WebRTC)

A visualização via browser é o “Santo Graal” da usabilidade, pois permite ver o stream no telemóvel, tablet ou PC sem instalar nada.

No entanto, há um desafio técnico importante: Browsers (Chrome, Safari, Firefox) não entendem nativamente o protocolo “Raw H.264 over TCP” que criámos na secção anterior. Eles esperam protocolos Web (HLS, WebRTC) ou contentores específicos (MP4 fragmentado).

Para resolver isto, vamos usar uma ferramenta fantástica e leve chamada MediaMTX (antigo rtsp-simple-server). Ele atuará como uma “ponte”: recebe o vídeo do Raspberry Pi e converte-o instantaneamente para WebRTC, que oferece latência ultra-baixa (sub-segundo) diretamente no browser.

Nesta fase, o nosso objetivo é tornar o stream acessível através de um endereço web (ex: http://192.168.1.50:8889/cam), que possas abrir em qualquer dispositivo na mesma rede.

A Arquitetura da Solução Web

Não vamos enviar o vídeo diretamente da câmara para o browser. Precisamos de um Middleware:

  1. Fonte: O rpicam-vid gera o vídeo H.264.
  2. Transporte Interno: Usaremos o FFmpeg para empacotar esse vídeo num protocolo padrão (RTSP) e enviá-lo para o servidor local.
  3. Servidor (MediaMTX): Recebe o RTSP e transmuta-o em tempo real para WebRTC.
  4. Cliente (Browser): Acede a uma página HTML que consome o WebRTC.

Instalação das Ferramentas (Hands-On)

No terminal do Raspberry Pi, vamos primeiro instalar o FFmpeg, que será o nosso “carteiro” de vídeo:

sudo apt install ffmpeg -y

Agora, vamos baixar e instalar o MediaMTX. Verifica a página de releases do GitHub do projeto para a versão mais recente, mas para um Raspberry Pi (3, 4 ou 5) a correr um sistema de 64-bits, os comandos são geralmente estes:

# Baixar o servidor (verifica se precisas de arm64 ou armv7 consoante o teu OS)
wget https://github.com/bluenviron/mediamtx/releases/download/v1.6.0/mediamtx_v1.6.0_linux_arm64v8.tar.gz

# Extrair o ficheiro
tar -xvzf mediamtx_v1.6.0_linux_arm64v8.tar.gz

# Agora tens um executável chamado "mediamtx" e um ficheiro "mediamtx.yml"

Configuração do Servidor

O MediaMTX é extremamente versátil porque permite executar scripts automaticamente quando alguém pede o stream. Vamos editá-lo para que ele ligue a câmara sozinho.

Abre o ficheiro de configuração:

nano mediamtx.yml

Desce até ao final do ficheiro onde diz paths: e adiciona a seguinte configuração (apaga ou comenta os exemplos que lá estiverem):

paths:
  cam:
    # O comando runOnInit corre assim que o servidor arranca
    runOnInit: rpicam-vid -t 0 --inline --width 1280 --height 720 --framerate 30 -o - | ffmpeg -re -i - -c:v copy -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH
    runOnInitRestart: yes

O que estamos a fazer aqui?

  • Criámos um caminho chamado /cam.
  • Dizemos ao servidor: “Assim que iniciares, corre este comando”.
  • O comando liga a câmara (rpicam-vid), envia o vídeo para a saída padrão (-o -) e o FFmpeg pega nisso e reenvia para o próprio servidor via RTSP.
  • -c:v copy: Isto é vital. Diz ao FFmpeg para não recodificar o vídeo. Ele apenas copia os dados H.264 já comprimidos pelo hardware do Pi. Isto mantém o CPU do Pi quase a 0% de uso.

Guarda o ficheiro (Ctrl+O, Enter) e sai (Ctrl+X).

Executar o Servidor

Agora basta correr o executável:

./mediamtx

Verás logs a indicar que o servidor iniciou e que a câmara foi ativada.

Criar a Página Web (O Cliente)

O MediaMTX já fornece uma página de visualização básica, mas vamos construir uma página nossa, criando o nosso próprio ficheiro HTML simples para incorporar o vídeo.

No teu PC (ou no próprio Pi, se tiveres um servidor web como Apache/Nginx), cria um ficheiro chamado index.html:

<!DOCTYPE html>
<html lang="pt">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>RPi Stream Monitor</title>
    <style>
        body { font-family: sans-serif; background: #222; color: white; text-align: center; }
        .video-container {
            margin: 20px auto;
            max-width: 1280px;
            border: 5px solid #444;
            border-radius: 8px;
            overflow: hidden;
        }
        iframe {
            width: 100%;
            height: 720px;
            border: none;
        }
    </style>
</head>
<body>
    <h1>Raspberry Pi Cam - Live Feed</h1>
    <div class="video-container">
        <iframe src="http://192.168.1.50:8889/cam"></iframe>
    </div>
    <p>Protocolo: WebRTC (Baixa Latência)</p>
</body>
</html>

Como testar:

  1. Certifica-te que o ./mediamtx está a correr no Raspberry Pi.
  2. Abre o ficheiro index.html no browser do teu PC.
  3. Deverás ver o vídeo com uma latência incrivelmente baixa (geralmente menos de 0.5 segundos).

Comparação Final de Protocolos

Para referência futura, eis porque escolhemos esta abordagem WebRTC via MediaMTX:

MétodoLatênciaCompatibilidade WebCarga no CPU
HTTP (MJPEG)BaixaAlta (Nativa)Alta (ficheiros enormes)
HLS (M3U8)Alta (3-10s)Alta (Nativa iOS/Android)Baixa
WebRTC (MediaMTX)Muito Baixa (<0.5s)Alta (Via JS/Iframe)Baixa

Pedro Coelho

Dez-2025

Deixe um comentário