implementation

This commit is contained in:
freddyaboulton
2024-10-10 14:08:59 -07:00
parent 1293061213
commit 3777bfe777
9 changed files with 543 additions and 40 deletions

View File

@@ -0,0 +1,124 @@
<script lang="ts">
import { Empty } from "@gradio/atoms";
import {
BlockLabel,
} from "@gradio/atoms";
import { Music } from "@gradio/icons";
import type { I18nFormatter } from "@gradio/utils";
import { createEventDispatcher } from "svelte";
import { onMount } from "svelte";
import { start, stop } from "./webrtc_utils";
export let value: string | null = null;
export let label: string | undefined = undefined;
export let show_label = true;
export let rtc_configuration: Object | null = null;
export let i18n: I18nFormatter;
export let autoplay: boolean = true;
export let server: {
offer: (body: any) => Promise<any>;
};
let stream_state = "closed";
let audio_player: HTMLAudioElement;
let pc: RTCPeerConnection;
let _webrtc_id = Math.random().toString(36).substring(2);
const dispatch = createEventDispatcher<{
tick: undefined;
error: string
play: undefined;
stop: undefined;
}>();
onMount(() => {
window.setInterval(() => {
if (stream_state == "open") {
dispatch("tick");
}
}, 1000);
}
)
$: if( value === "start_webrtc_stream") {
stream_state = "connecting";
value = _webrtc_id;
const fallback_config = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
pc = new RTCPeerConnection(rtc_configuration);
console.log("config", pc.getConfiguration());
pc.addEventListener("connectionstatechange",
async (event) => {
switch(pc.connectionState) {
case "connected":
console.log("connected");
stream_state = "open";
break;
case "disconnected":
console.log("closed");
stop(pc);
break;
default:
break;
}
}
)
start(null, pc, audio_player, server.offer, _webrtc_id, "audio").then((connection) => {
pc = connection;
}).catch(() => {
console.log("catching")
dispatch("error", "Too many concurrent users. Come back later!");
});
}
</script>
<BlockLabel
{show_label}
Icon={Music}
float={false}
label={label || i18n("audio.audio")}
/>
<audio
class="standard-player"
class:hidden={value === "__webrtc_value__"}
controls
on:load
bind:this={audio_player}
on:ended={() => dispatch("stop")}
on:play={() => dispatch("play")}
/>
{#if value === "__webrtc_value__"}
<Empty size="small">
<Music />
</Empty>
{/if}
<style>
:global(::part(wrapper)) {
margin-bottom: var(--size-2);
}
.standard-player {
width: 100%;
padding: var(--size-2);
}
.hidden {
display: none;
}
</style>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { createEventDispatcher, afterUpdate, tick } from "svelte";
import { createEventDispatcher, onMount} from "svelte";
import {
BlockLabel,
Empty
@@ -29,15 +29,16 @@
}>();
let stream_state = "closed";
window.setInterval(() => {
if (stream_state == "open") {
dispatch("tick");
}
}, 1000);
onMount(() => {
window.setInterval(() => {
if (stream_state == "open") {
dispatch("tick");
}
}, 1000);
}
)
$: console.log("static video value", value);
$: if( value === "start_webrtc_stream") {
value = _webrtc_id;
const fallback_config = {
@@ -48,8 +49,7 @@
]
};
const configuration = rtc_configuration || fallback_config;
console.log("config", configuration);
pc = new RTCPeerConnection(configuration);
pc = new RTCPeerConnection(rtc_configuration);
pc.addEventListener("connectionstatechange",
async (event) => {
switch(pc.connectionState) {

View File

@@ -27,17 +27,25 @@ export function createPeerConnection(pc, node) {
// connect audio / video from server to local
pc.addEventListener("track", (evt) => {
console.log("track event listener");
if (evt.track.kind == "video") {
if (node.srcObject !== evt.streams[0]) {
console.log("streams", evt.streams);
node.srcObject = evt.streams[0];
console.log("node.srcOject", node.srcObject);
if (evt.track.kind === 'audio') {
node.volume = 1.0; // Ensure volume is up
node.muted = false;
node.autoplay = true;
// Attempt to play (needed for some browsers)
node.play().catch(e => console.log("Autoplay failed:", e));
}
}
});
return pc;
}
export async function start(stream, pc, node, server_fn, webrtc_id) {
export async function start(stream, pc: RTCPeerConnection, node, server_fn, webrtc_id, modality: "video" | "audio" = "video") {
pc = createPeerConnection(pc, node);
if (stream) {
stream.getTracks().forEach((track) => {
@@ -48,7 +56,7 @@ export async function start(stream, pc, node, server_fn, webrtc_id) {
});
} else {
console.log("Creating transceiver!");
pc.addTransceiver("video", { direction: "recvonly" });
pc.addTransceiver(modality, { direction: "recvonly" });
}
await negotiate(pc, server_fn, webrtc_id);