Spaces:
Runtime error
Runtime error
| export function LCMLive(webcamVideo, liveImage) { | |
| let websocket: WebSocket; | |
| async function start() { | |
| return new Promise((resolve, reject) => { | |
| const websocketURL = `${window.location.protocol === "https:" ? "wss" : "ws" | |
| }:${window.location.host}/ws`; | |
| const socket = new WebSocket(websocketURL); | |
| socket.onopen = () => { | |
| console.log("Connected to websocket"); | |
| }; | |
| socket.onclose = () => { | |
| console.log("Disconnected from websocket"); | |
| stop(); | |
| resolve({ "status": "disconnected" }); | |
| }; | |
| socket.onerror = (err) => { | |
| console.error(err); | |
| reject(err); | |
| }; | |
| socket.onmessage = (event) => { | |
| const data = JSON.parse(event.data); | |
| switch (data.status) { | |
| case "success": | |
| break; | |
| case "start": | |
| const userId = data.userId; | |
| initVideoStream(userId); | |
| break; | |
| case "timeout": | |
| stop(); | |
| resolve({ "status": "timeout" }); | |
| case "error": | |
| stop(); | |
| reject(data.message); | |
| } | |
| }; | |
| websocket = socket; | |
| }) | |
| } | |
| function switchCamera() { | |
| const constraints = { | |
| audio: false, | |
| video: { width: 1024, height: 1024, deviceId: mediaDevices[webcamsEl.value].deviceId } | |
| }; | |
| navigator.mediaDevices | |
| .getUserMedia(constraints) | |
| .then((mediaStream) => { | |
| webcamVideo.removeEventListener("timeupdate", videoTimeUpdateHandler); | |
| webcamVideo.srcObject = mediaStream; | |
| webcamVideo.onloadedmetadata = () => { | |
| webcamVideo.play(); | |
| webcamVideo.addEventListener("timeupdate", videoTimeUpdateHandler); | |
| }; | |
| }) | |
| .catch((err) => { | |
| console.error(`${err.name}: ${err.message}`); | |
| }); | |
| } | |
| async function videoTimeUpdateHandler() { | |
| const dimension = getValue("input[name=dimension]:checked"); | |
| const [WIDTH, HEIGHT] = JSON.parse(dimension); | |
| const canvas = new OffscreenCanvas(WIDTH, HEIGHT); | |
| const videoW = webcamVideo.videoWidth; | |
| const videoH = webcamVideo.videoHeight; | |
| const aspectRatio = WIDTH / HEIGHT; | |
| const ctx = canvas.getContext("2d"); | |
| ctx.drawImage(webcamVideo, videoW / 2 - videoH * aspectRatio / 2, 0, videoH * aspectRatio, videoH, 0, 0, WIDTH, HEIGHT) | |
| const blob = await canvas.convertToBlob({ type: "image/jpeg", quality: 1 }); | |
| websocket.send(blob); | |
| websocket.send(JSON.stringify({ | |
| "seed": getValue("#seed"), | |
| "prompt": getValue("#prompt"), | |
| "guidance_scale": getValue("#guidance-scale"), | |
| "strength": getValue("#strength"), | |
| "steps": getValue("#steps"), | |
| "lcm_steps": getValue("#lcm_steps"), | |
| "width": WIDTH, | |
| "height": HEIGHT, | |
| "controlnet_scale": getValue("#controlnet_scale"), | |
| "controlnet_start": getValue("#controlnet_start"), | |
| "controlnet_end": getValue("#controlnet_end"), | |
| "canny_low_threshold": getValue("#canny_low_threshold"), | |
| "canny_high_threshold": getValue("#canny_high_threshold"), | |
| "debug_canny": getValue("#debug_canny") | |
| })); | |
| } | |
| let mediaDevices = []; | |
| async function initVideoStream(userId) { | |
| liveImage.src = `/stream/${userId}`; | |
| await navigator.mediaDevices.enumerateDevices() | |
| .then(devices => { | |
| const cameras = devices.filter(device => device.kind === 'videoinput'); | |
| mediaDevices = cameras; | |
| webcamsEl.innerHTML = ""; | |
| cameras.forEach((camera, index) => { | |
| const option = document.createElement("option"); | |
| option.value = index; | |
| option.innerText = camera.label; | |
| webcamsEl.appendChild(option); | |
| option.selected = index === 0; | |
| }); | |
| webcamsEl.addEventListener("change", switchCamera); | |
| }) | |
| .catch(err => { | |
| console.error(err); | |
| }); | |
| const constraints = { | |
| audio: false, | |
| video: { width: 1024, height: 1024, deviceId: mediaDevices[0].deviceId } | |
| }; | |
| navigator.mediaDevices | |
| .getUserMedia(constraints) | |
| .then((mediaStream) => { | |
| webcamVideo.srcObject = mediaStream; | |
| webcamVideo.onloadedmetadata = () => { | |
| webcamVideo.play(); | |
| webcamVideo.addEventListener("timeupdate", videoTimeUpdateHandler); | |
| }; | |
| }) | |
| .catch((err) => { | |
| console.error(`${err.name}: ${err.message}`); | |
| }); | |
| } | |
| async function stop() { | |
| websocket.close(); | |
| navigator.mediaDevices.getUserMedia({ video: true }).then((mediaStream) => { | |
| mediaStream.getTracks().forEach((track) => track.stop()); | |
| }); | |
| webcamVideo.removeEventListener("timeupdate", videoTimeUpdateHandler); | |
| webcamsEl.removeEventListener("change", switchCamera); | |
| webcamVideo.srcObject = null; | |
| } | |
| return { | |
| start, | |
| stop | |
| } | |
| } |