Spaces:
Running
on
A100
Running
on
A100
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 | |
} | |
} |