☞ Esquema de Arquitectura
┌──────────────────────────────────────────────────────────────────┐
│ RASPBERRY PI 3B · SOLAR NET HUB │
│ BCM2837 · Cortex-A53 · VideoCore IV │
│ │
│ ┌──────────┐ V4L2 ┌─────────────────────┐ │
│ │ 🎥 CAM │────────▷│ µStreamer :8080 │ │
│ │ CSI/USB │ │ ┌───────────────────┐│ │
│ └──────────┘ │ │MJPEG (cero proxy) ││ │
│ │ │GET /stream ││ │
│ │ │GET /snapshot ││ │
│ │ └───────────────────┘│ │
│ └──────────┬──────────┘ │
│ │ localhost │
│ ┌──────────┐ ALSA ┌─────────┼──────────┐ │
│ │ 🎤 MIC │────────▷│ murmurd │ :64738 │ │
│ └──────────┘ │ (Mumble,│ya activo) │ │
│ │ audio │bidirecc. │ │
│ └─────────┼──────────┘ │
│ │ localhost │
│ ┌──────────────────────────────┴────────────────────────────┐ │
│ │ OASIS :3000 (Node.js · SSB · cero JS en browser) │ │
│ │ │ │
│ │ GET /video ──▷ proxy µStreamer MJPEG │ │
│ │ GET /audio ──▷ bridge Mumble Opus→OGG (ffmpeg) │ │
│ │ │ │
│ │ HTML: <img src="/video"> + <audio src="/audio"> │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ node-datachannel (P2P DataChannels) │ │ │
│ │ │ texto · archivos · señalización │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌────────────┐ ┌─────────────┐ ┌──────────────┐
│ 📺 BROWSER │ │ 🔊 MUMBLE │ │ 📡 PEER P2P │
│ (SIN JS) │ │ (cliente │ │ node-data- │
│ <img>MJPEG │ │ nativo) │ │ channel │
│ <audio>OGG │ │ RTT ~20ms │ │ texto/files │
└────────────┘ └─────────────┘ └──────────────┘
☞ Setup Técnico
1. INSTALAR µSTREAMER
sudo apt install ustreamer
2. INICIAR µSTREAMER (según cámara)
sudo modprobe bcm2835-v4l2
libcamerify ustreamer \
--host 127.0.0.1 \
--port 8080 \
--encoder=m2m-image \
--workers=3
ustreamer \
--host 127.0.0.1 \
--port 8080 \
--device=/dev/video0 \
--workers=3 \
--drop-same-frames=20
3. MUMBLE (ya corriendo)
ffmpeg -i mumble://localhost:64738 \
-c:a libvorbis -f ogg pipe:1 | \
node oasis-audio-bridge.js
4. HTML EN OASIS (cero JS)
<img src="/video" alt="stream">
<audio src="/audio" controls autoplay></audio>
5. PROXY EN OASIS (Node.js)
app.get('/video', (req, res) => {
const upstream = http.get(
'http://127.0.0.1:8080/stream',
(mjpeg) => {
res.writeHead(200, mjpeg.headers);
mjpeg.pipe(res);
}
);
req.on('close', () => upstream.destroy());
});