mirror of
https://github.com/HumanAIGC-Engineering/gradio-webrtc.git
synced 2026-02-05 18:09:23 +08:00
11
frontend/.prettierrc
Normal file
11
frontend/.prettierrc
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.svelte",
|
||||
"options": {
|
||||
"parser": "svelte"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -46,10 +46,7 @@
|
||||
msg?.type === "warning" ||
|
||||
msg?.type === "error"
|
||||
) {
|
||||
gradio.dispatch(
|
||||
msg?.type === "error" ? "error" : "warning",
|
||||
msg.message,
|
||||
);
|
||||
gradio.dispatch(msg?.type === "error" ? "error" : "warning", msg.message);
|
||||
} else if (msg?.type === "fetch_output") {
|
||||
gradio.dispatch("state_change");
|
||||
} else if (msg?.type === "send_input") {
|
||||
|
||||
15
frontend/package-lock.json
generated
15
frontend/package-lock.json
generated
@@ -25,7 +25,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gradio/preview": "0.12.0",
|
||||
"prettier": "3.3.3"
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-svelte": "^3.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^4.0.0"
|
||||
@@ -4118,6 +4119,7 @@
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
|
||||
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
@@ -4128,6 +4130,17 @@
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-plugin-svelte": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.3.3.tgz",
|
||||
"integrity": "sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"prettier": "^3.0.0",
|
||||
"svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prismjs": {
|
||||
"version": "1.29.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gradio/preview": "0.12.0",
|
||||
"prettier": "3.3.3"
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-svelte": "^3.3.3"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
VolumeHigh,
|
||||
Microphone,
|
||||
} from "@gradio/icons";
|
||||
import MicrophoneMuted from "./MicrophoneMuted.svelte";
|
||||
|
||||
import { start, stop } from "./webrtc_utils";
|
||||
import { get_devices, set_available_devices } from "./stream_utils";
|
||||
@@ -79,6 +80,7 @@
|
||||
let selected_device: MediaDeviceInfo | null = null;
|
||||
let mic_accessed = false;
|
||||
let is_muted = false;
|
||||
let is_mic_muted = false;
|
||||
|
||||
const audio_source_callback = () => {
|
||||
if (mode === "send") return stream;
|
||||
@@ -257,9 +259,8 @@
|
||||
audio: { deviceId: { exact: device_id }, ...track_constraints },
|
||||
});
|
||||
selected_device =
|
||||
available_audio_devices.find(
|
||||
(device) => device.deviceId === device_id,
|
||||
) || null;
|
||||
available_audio_devices.find((device) => device.deviceId === device_id) ||
|
||||
null;
|
||||
options_open = false;
|
||||
};
|
||||
|
||||
@@ -270,6 +271,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMuteMicrophone(): void {
|
||||
if (stream && stream.getAudioTracks().length > 0) {
|
||||
const audioTrack = stream.getAudioTracks()[0];
|
||||
audioTrack.enabled = !audioTrack.enabled;
|
||||
is_mic_muted = !audioTrack.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
$: if (stopword_recognized) {
|
||||
notification_sound.play();
|
||||
}
|
||||
@@ -338,10 +347,7 @@
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="icon color-primary"
|
||||
title="start recording"
|
||||
>
|
||||
<div class="icon color-primary" title="start recording">
|
||||
<Circle />
|
||||
</div>
|
||||
{/if}
|
||||
@@ -383,6 +389,24 @@
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
{#if stream_state === "open" && mode.includes("send")}
|
||||
<button
|
||||
class="mute-button"
|
||||
on:click={toggleMuteMicrophone}
|
||||
aria-label={is_mic_muted ? "unmute mic" : "mute mic"}
|
||||
>
|
||||
<div
|
||||
class="icon"
|
||||
style={`fill: ${icon_button_color}; stroke: ${icon_button_color}; color: ${icon_button_color};`}
|
||||
>
|
||||
{#if is_mic_muted}
|
||||
<MicrophoneMuted />
|
||||
{:else}
|
||||
<Microphone />
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
{#if options_open && selected_device}
|
||||
<select
|
||||
class="select-wrap"
|
||||
@@ -402,8 +426,7 @@
|
||||
{#each available_audio_devices as device}
|
||||
<option
|
||||
value={device.deviceId}
|
||||
selected={selected_device.deviceId ===
|
||||
device.deviceId}
|
||||
selected={selected_device.deviceId === device.deviceId}
|
||||
>
|
||||
{device.label}
|
||||
</option>
|
||||
|
||||
20
frontend/shared/MicrophoneMuted.svelte
Normal file
20
frontend/shared/MicrophoneMuted.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="feather feather-mic"
|
||||
><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" /><path
|
||||
d="M19 10v2a7 7 0 0 1-14 0v-2"
|
||||
/><line x1="12" y1="19" x2="12" y2="23" /><line
|
||||
x1="8"
|
||||
y1="23"
|
||||
x2="16"
|
||||
y2="23"
|
||||
/><line x1="1" y1="1" x2="23" y2="23" /></svg
|
||||
>
|
||||
|
After Width: | Height: | Size: 489 B |
@@ -84,10 +84,7 @@
|
||||
.catch(() => {
|
||||
clearTimeout(timeoutId);
|
||||
console.info("catching");
|
||||
dispatch(
|
||||
"error",
|
||||
"Too many concurrent users. Come back later!",
|
||||
);
|
||||
dispatch("error", "Too many concurrent users. Come back later!");
|
||||
});
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -70,10 +70,7 @@
|
||||
})
|
||||
.catch(() => {
|
||||
clearTimeout(timeoutId);
|
||||
dispatch(
|
||||
"error",
|
||||
"Too many concurrent users. Come back later!",
|
||||
);
|
||||
dispatch("error", "Too many concurrent users. Come back later!");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
export let pulse_color: string = "var(--color-accent)";
|
||||
export let button_labels: { start: string; stop: string; waiting: string };
|
||||
|
||||
export const modify_stream: (
|
||||
export const modify_stream: (state: "open" | "closed" | "waiting") => void = (
|
||||
state: "open" | "closed" | "waiting",
|
||||
) => void = (state: "open" | "closed" | "waiting") => {
|
||||
) => {
|
||||
if (state === "closed") {
|
||||
_time_limit = null;
|
||||
stream_state = "closed";
|
||||
@@ -92,12 +92,7 @@
|
||||
|
||||
async function access_webcam(): Promise<void> {
|
||||
try {
|
||||
get_video_stream(
|
||||
include_audio,
|
||||
video_source,
|
||||
null,
|
||||
track_constraints,
|
||||
)
|
||||
get_video_stream(include_audio, video_source, null, track_constraints)
|
||||
.then(async (local_stream) => {
|
||||
webcam_accessed = true;
|
||||
available_video_devices = await get_devices();
|
||||
@@ -112,16 +107,12 @@
|
||||
.map((track) => track.getSettings()?.deviceId)[0];
|
||||
|
||||
selected_device = used_devices
|
||||
? devices.find(
|
||||
(device) => device.deviceId === used_devices,
|
||||
) || available_video_devices[0]
|
||||
? devices.find((device) => device.deviceId === used_devices) ||
|
||||
available_video_devices[0]
|
||||
: available_video_devices[0];
|
||||
});
|
||||
|
||||
if (
|
||||
!navigator.mediaDevices ||
|
||||
!navigator.mediaDevices.getUserMedia
|
||||
) {
|
||||
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||
dispatch("error", i18n("image.no_webcam_support"));
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -321,8 +312,7 @@
|
||||
{#each available_video_devices as device}
|
||||
<option
|
||||
value={device.deviceId}
|
||||
selected={selected_device.deviceId ===
|
||||
device.deviceId}
|
||||
selected={selected_device.deviceId === device.deviceId}
|
||||
>
|
||||
{device.label}
|
||||
</option>
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
export let icon = Webcam;
|
||||
$: text = icon === Webcam ? "Click to Access Webcam" : "Click to Access Microphone";
|
||||
$: text =
|
||||
icon === Webcam ? "Click to Access Webcam" : "Click to Access Microphone";
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
click: undefined;
|
||||
|
||||
@@ -51,10 +51,10 @@ export async function start(
|
||||
server_fn,
|
||||
webrtc_id,
|
||||
modality: "video" | "audio" = "video",
|
||||
on_change_cb: (msg: "change" | "tick") => void = () => { },
|
||||
on_change_cb: (msg: "change" | "tick") => void = () => {},
|
||||
rtp_params = {},
|
||||
additional_message_cb: (msg: object) => void = () => { },
|
||||
reject_cb: (msg: object) => void = () => { },
|
||||
additional_message_cb: (msg: object) => void = () => {},
|
||||
reject_cb: (msg: object) => void = () => {},
|
||||
) {
|
||||
pc = createPeerConnection(pc, node);
|
||||
const data_channel = pc.createDataChannel("text");
|
||||
@@ -105,7 +105,11 @@ export async function start(
|
||||
return pc;
|
||||
}
|
||||
|
||||
function make_offer(server_fn: any, body, reject_cb: (msg: object) => void = () => { }): Promise<object> {
|
||||
function make_offer(
|
||||
server_fn: any,
|
||||
body,
|
||||
reject_cb: (msg: object) => void = () => {},
|
||||
): Promise<object> {
|
||||
return new Promise((resolve, reject) => {
|
||||
server_fn(body).then((data) => {
|
||||
console.debug("data", data);
|
||||
@@ -123,7 +127,7 @@ async function negotiate(
|
||||
pc: RTCPeerConnection,
|
||||
server_fn: any,
|
||||
webrtc_id: string,
|
||||
reject_cb: (msg: object) => void = () => { },
|
||||
reject_cb: (msg: object) => void = () => {},
|
||||
): Promise<void> {
|
||||
return pc
|
||||
.createOffer()
|
||||
@@ -150,11 +154,15 @@ async function negotiate(
|
||||
})
|
||||
.then(() => {
|
||||
var offer = pc.localDescription;
|
||||
return make_offer(server_fn, {
|
||||
return make_offer(
|
||||
server_fn,
|
||||
{
|
||||
sdp: offer.sdp,
|
||||
type: offer.type,
|
||||
webrtc_id: webrtc_id,
|
||||
}, reject_cb);
|
||||
},
|
||||
reject_cb,
|
||||
);
|
||||
})
|
||||
.then((response) => {
|
||||
return response;
|
||||
|
||||
Reference in New Issue
Block a user