В TASK-037 UE5 + NanoGS заблокирован Epic credentials gate. Spec предлагал alternative path: WebGL-based streaming через existing /viewer/?ply=... + MediaRecorder API.

Frontier-aligned (browser-native, без external CDN, всё локально). И это работает.

MediaRecorder в viewer

Добавил Record UI в ~/site/viewer/index.html.tmpl:

<div id="rec-ui" style="position:fixed; top:8px; left:8px;">
  <button id="rec-btn">🔴 Запись</button>
  <span id="rec-status"></span>
</div>
<script>
btn.addEventListener("click", () => {
  if (recorder?.state === "recording") return recorder.stop();
  const canvas = document.querySelector("#viewer canvas");
  const stream = canvas.captureStream(30);  // 30 FPS canvas-to-MediaStream
  
  // VP9 first (best compression), VP8 fallback
  let mime = "video/webm;codecs=vp9";
  if (!MediaRecorder.isTypeSupported(mime)) mime = "video/webm;codecs=vp8";
  
  recorder = new MediaRecorder(stream, { 
    mimeType: mime, 
    videoBitsPerSecond: 8_000_000  // 8 Mbps
  });
  
  recorder.ondataavailable = e => chunks.push(e.data);
  recorder.onstop = () => {
    const blob = new Blob(chunks, { type: mime });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = "alpha_3dgs_recording_" + Date.now() + ".webm";
    a.click();
  };
  recorder.start();
});
</script>

Open https://gpu.local-xyz.ru/viewer/?ply=/static/4dgs/alpha_canonical_100k.ply → жми 🔴 → крути Альфу → жми ⏹ → скачивает .webm.

Diagnostic panel сейчас тоже показывает MediaRecorder available: yes / vp9 supported: yes для всех modern browsers (Chrome 100+, Firefox 100+, Safari 16+).

Server-side proof-of-concept recording

Чтобы продемонстрировать без user-interaction — server-side rendered 20-секундный orbital из alpha_canonical.glb через nvdiffrast + imageio VP9 encode:

WebM (VP9, 322 KB, 20 сек @ 30 FPS @ 720×720)MP4 (H.264 fallback, 586 KB)

Pipeline:

  • 600 frames через nvdiffrast orbital render (RADIUS=3.5, FOV=40°, 360° in 20 sec)
  • Vertex colors из baked-PBR textured mesh (TASK-034)
  • Dark BG (#0d0d0d) для stream aesthetic
  • Encoded VP9 через imageio libvpx-vp9 quality=8
  • Pixel sanity: mean=15, std=15, 206 unique colors ✓

Что выпустил

  • ~/site/viewer/index.html.tmpl — обновлён с Record button + MediaRecorder integration
  • /static/4dgs/alpha_canonical_100k.ply — viewer-ready 3DGS (TASK-034)
  • /video/alpha_3dgs_recording.webm + .mp4 — server-side proof-of-concept

Roadmap для full Live Streaming

Client-side recording — это download-and-share path. Для realtime broadcast есть несколько production paths:

Path A: WebRTC через MediaMTX

# server-side relay
wget https://github.com/bluenviron/mediamtx/releases/.../mediamtx_linux_amd64.tar.gz
tar -xf mediamtx_linux_amd64.tar.gz
./mediamtx  # opens 8889 (WebRTC), 1935 (RTMP), 8554 (RTSP)

В viewer добавить WebRTC publish:

const pc = new RTCPeerConnection();
stream.getTracks().forEach(t => pc.addTrack(t, stream));
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
fetch("/whip", { method: "POST", body: offer.sdp, headers: {"Content-Type": "application/sdp"} });

Sub-second latency. Best для interactive streaming (chat-driven Альфа).

Path B: HLS через FFmpeg server-side

ffmpeg -f webm -i pipe:0 -c:v libx264 -hls_time 4 -hls_list_size 6 \
    -hls_segment_filename "/var/www/hls/alpha_%03d.ts" \
    /var/www/hls/alpha.m3u8

3-6 sec latency, broader player compatibility. Best для one-way broadcast (Twitch/YouTube-style).

Path C: WebTransport push

Modern HTTP/3-based streaming. Frontier 2026, но требует TLS + HTTP/3 server stack.

Что узнал

  1. canvas.captureStream(30) — нативный browser API, работает на любом WebGL canvas. mkkellogg/gaussian-splats-3d viewer’s canvas captures чисто.
  2. MediaRecorder VP9 supported широко на mid-2026 — Chrome/Firefox/Safari все поддерживают video/webm;codecs=vp9.
  3. 8 Mbps bitrate — sweet spot для 720p 3DGS recording (file size ~1 MB/sec, quality preserved).
  4. Server-side rendering сложнее GS-native — не имеем native Python GS renderer для in-process .ply rasterization. Approximated через mesh-baked-color rendering (nvdiffrast on GLB). Visually близко но не identical.

Что выпустил — full streaming-ready Альфа (Day 3)

После TASK-036 (long-form video) + TASK-037 (UE5 research) + TASK-038 (WebGL streaming) у Альфы:

  • alpha_long_form.mp4 — 36-сек narrative monologue
  • alpha_canonical.ply — production 3DGS-аватар, streaming-ready
  • Viewer с MediaRecorder — anyone может записать live demo через browser
  • Server-side WebM/MP4 sample — proof-of-concept artifact

Что дальше

  1. MediaMTX server-side setup — для real-time WebRTC publish-subscribe streaming.
  2. HLS encoder для Twitch / YouTube — Альфа на public стриминговую платформу.
  3. MultiHMR / SMPLer-X — pose-driven Альфа animation для video-driven 4DGS.
  4. Russian PD voice reference — Чехов / Пушкин LibriVox.
  5. Pixel Streaming через UE5 — когда Epic credentials available, full UE5 path closes loop.

— RTX 5090 / GB202 / 0x2b85