/** * Shared capture helpers for live-encode / clip-studio demos. */ (function (global) { 'use strict'; function startCapture(kind) { if (kind === 'camera') { return navigator.mediaDevices.getUserMedia({ video: { width: { ideal: 1280 }, height: { ideal: 720 } }, audio: false, }); } return navigator.mediaDevices.getDisplayMedia({ video: { frameRate: { ideal: 30 } }, audio: false, }); } /** * Pump video element frames onto a canvas at target FPS, calling onFrame(canvas). * Returns { stop, canvas, setFps }. */ function startFramePump(videoEl, opts) { opts = opts || {}; var fps = opts.fps || 10; var maxW = opts.maxWidth || 640; var maxH = opts.maxHeight || 360; var canvas = opts.canvas || document.createElement('canvas'); var ctx = canvas.getContext('2d', { alpha: false }); var running = true; var timer = null; var lastPush = 0; var inflight = false; function sizeCanvas() { var vw = videoEl.videoWidth || maxW; var vh = videoEl.videoHeight || maxH; var scale = Math.min(maxW / vw, maxH / vh, 1); canvas.width = Math.max(2, Math.round(vw * scale / 2) * 2); canvas.height = Math.max(2, Math.round(vh * scale / 2) * 2); } function tick() { if (!running) return; var interval = 1000 / fps; var now = performance.now(); if (now - lastPush >= interval && !inflight && videoEl.readyState >= 2 && videoEl.videoWidth) { lastPush = now; if (!canvas.width || !canvas.height) sizeCanvas(); try { ctx.drawImage(videoEl, 0, 0, canvas.width, canvas.height); } catch (_) {} if (typeof opts.onFrame === 'function') { inflight = true; Promise.resolve(opts.onFrame(canvas)) .catch(function () {}) .finally(function () { inflight = false; }); } } timer = requestAnimationFrame(tick); } function kickPlay() { try { videoEl.muted = true; videoEl.playsInline = true; videoEl.autoplay = true; var p = videoEl.play(); if (p && typeof p.catch === 'function') p.catch(function () {}); } catch (_) {} } videoEl.addEventListener('loadedmetadata', function () { sizeCanvas(); kickPlay(); }); if (videoEl.videoWidth) sizeCanvas(); kickPlay(); timer = requestAnimationFrame(tick); return { canvas: canvas, stop: function () { running = false; if (timer) cancelAnimationFrame(timer); timer = null; }, setFps: function (n) { fps = Math.max(1, Math.min(30, Number(n) || fps)); }, setMaxSize: function (w, h) { maxW = w; maxH = h; sizeCanvas(); }, }; } global.BridgeSwarmLiveCapture = { startCapture: startCapture, startFramePump: startFramePump, }; })(typeof window !== 'undefined' ? window : globalThis);