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:
- Intra-frame (Espacial): Comprime a imagem individualmente (semelhante ao JPEG), removendo redundâncias dentro do próprio frame.
- 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
- Desliga o Raspberry Pi.
- Levanta a patilha preta do porto “CSI” (Camera Serial Interface).
- 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).
- 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
- Abre o VLC Media Player.
- Vai a Media -> Open Network Stream (ou
Ctrl+N). - Insere o URL:
tcp/h264://192.168.1.50:3333(Substitui pelo IP correto). - 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
| Componente | Funçã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:
- Fonte: O
rpicam-vidgera o vídeo H.264. - Transporte Interno: Usaremos o FFmpeg para empacotar esse vídeo num protocolo padrão (RTSP) e enviá-lo para o servidor local.
- Servidor (MediaMTX): Recebe o RTSP e transmuta-o em tempo real para WebRTC.
- 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:
- Certifica-te que o
./mediamtxestá a correr no Raspberry Pi. - Abre o ficheiro
index.htmlno browser do teu PC. - 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étodo | Latência | Compatibilidade Web | Carga no CPU |
| HTTP (MJPEG) | Baixa | Alta (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