mirror of
https://github.com/SrIzan10/helium.git
synced 2026-06-06 00:56:58 +00:00
feat: peer stuff
This commit is contained in:
@@ -6,35 +6,103 @@ import {
|
||||
SelectSeparator,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select'
|
||||
import { Plus } from 'lucide-vue-next';
|
||||
const router = useRouter()
|
||||
const selectedValue = ref('')
|
||||
} from "@/components/ui/select";
|
||||
import { Plus } from "lucide-vue-next";
|
||||
import type { ApiResponse, PresetUser } from "~/lib/types/PresetGetResponse";
|
||||
import { useStreamerStore } from "~/state/streamer";
|
||||
|
||||
const router = useRouter();
|
||||
const selectedValue = ref("");
|
||||
const presets = ref<PresetUser[]>([]);
|
||||
const loading = ref(true);
|
||||
const streamerStore = useStreamerStore();
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const response = await $fetch<ApiResponse>("/api/presets");
|
||||
if (response.success) {
|
||||
presets.value = response.data;
|
||||
|
||||
const defaultPreset = presets.value.find((p) => p.isDefault);
|
||||
if (defaultPreset) {
|
||||
selectedValue.value = defaultPreset.presetId;
|
||||
// Load the default preset's ice servers
|
||||
loadPresetIceServers(defaultPreset.presetId);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch presets:", error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
async function loadPresetIceServers(presetId: string) {
|
||||
try {
|
||||
const response = await $fetch(`/api/presets/${presetId}`);
|
||||
const preset = response?.data || response;
|
||||
if (preset && preset.iceServers) {
|
||||
// Parse ice servers if it's a string
|
||||
let iceServers = preset.iceServers;
|
||||
if (typeof iceServers === "string") {
|
||||
iceServers = JSON.parse(iceServers);
|
||||
}
|
||||
// Set the ice servers on the streamer store
|
||||
streamerStore.setIceServers(iceServers);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load preset ice servers:", error);
|
||||
}
|
||||
}
|
||||
|
||||
watch(selectedValue, (newValue) => {
|
||||
if (newValue === 'create-new') {
|
||||
router.push('/presets/new')
|
||||
if (newValue === "create-new") {
|
||||
router.push("/presets/new");
|
||||
selectedValue.value = "";
|
||||
} else if (newValue) {
|
||||
// Load ice servers for the selected preset
|
||||
loadPresetIceServers(newValue);
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Select v-model="selectedValue">
|
||||
<Select v-model="selectedValue" :disabled="loading">
|
||||
<SelectTrigger class="w-[180px]">
|
||||
<SelectValue placeholder="Select a preset" />
|
||||
<SelectValue
|
||||
:placeholder="loading ? 'Loading presets...' : 'Select a preset'"
|
||||
/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="default">
|
||||
Default
|
||||
</SelectItem>
|
||||
<SelectSeparator />
|
||||
<div
|
||||
v-if="presets.length === 0 && !loading"
|
||||
class="px-2 py-1.5 text-sm text-muted-foreground"
|
||||
>
|
||||
No presets available
|
||||
</div>
|
||||
|
||||
<div v-else-if="!loading">
|
||||
<div v-for="preset in presets" :key="preset.presetId">
|
||||
<SelectItem :value="preset.presetId">
|
||||
<span :class="{ 'font-semibold': preset.isDefault }">
|
||||
{{ preset.preset.name }}
|
||||
</span>
|
||||
<span
|
||||
v-if="preset.isDefault"
|
||||
class="ml-2 text-xs text-muted-foreground"
|
||||
>(default)</span
|
||||
>
|
||||
</SelectItem>
|
||||
</div>
|
||||
<SelectSeparator />
|
||||
</div>
|
||||
|
||||
<SelectItem value="create-new">
|
||||
<div class="font-bold flex gap-2 items-center">
|
||||
<Plus class="size-4" />
|
||||
Create New Preset
|
||||
</div>
|
||||
</SelectItem>
|
||||
<!-- add database provided presets here -->
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
|
||||
@@ -13,7 +13,7 @@ interface Preset {
|
||||
shareable: boolean;
|
||||
createdAt: string;
|
||||
}
|
||||
interface PresetUser {
|
||||
export interface PresetUser {
|
||||
id: string;
|
||||
presetId: string;
|
||||
userId: string;
|
||||
|
||||
@@ -45,38 +45,7 @@ const { send } = useWebSocket(wsUrl, {
|
||||
const message = JSON.parse(ev.data);
|
||||
if (message.event === "offer") {
|
||||
viewerStore.setConnectionStatus("creating rtc peer connections...");
|
||||
const peerConnection = new RTCPeerConnection({
|
||||
iceServers: [
|
||||
{ urls: "stun:stun.l.google.com:19302" },
|
||||
{ urls: "stun:stun1.l.google.com:19302" },
|
||||
{
|
||||
urls: "turn:5.161.207.54:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:5.161.49.183:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:135.181.147.65:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:5.78.83.26:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:5.223.48.157:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
],
|
||||
iceTransportPolicy: "relay",
|
||||
});
|
||||
const peerConnection = new RTCPeerConnection();
|
||||
viewerStore.setPeerConnection(peerConnection);
|
||||
|
||||
peerConnection.ontrack = (event) => {
|
||||
@@ -175,4 +144,3 @@ watch(codeRef, (newCode) => {
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -36,35 +36,7 @@ const { send } = useWebSocket(wsUrl, {
|
||||
|
||||
if (message.event === "viewer-joined") {
|
||||
const peerConnection = new RTCPeerConnection({
|
||||
iceServers: [
|
||||
{ urls: "stun:stun.l.google.com:19302" },
|
||||
{ urls: "stun:stun1.l.google.com:19302" },
|
||||
{
|
||||
urls: "turn:5.161.207.54:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:5.161.49.183:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:135.181.147.65:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:5.78.83.26:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
{
|
||||
urls: "turn:5.223.48.157:3478",
|
||||
username: "username",
|
||||
credential: "password",
|
||||
},
|
||||
],
|
||||
iceServers: streamerStore.iceServers,
|
||||
iceTransportPolicy: "relay",
|
||||
});
|
||||
streamerStore.addPeerConnection(message.viewerId, peerConnection);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { defineStore} from 'pinia';
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
export const useStreamerStore = defineStore('streamer', {
|
||||
export const useStreamerStore = defineStore("streamer", {
|
||||
state: () => ({
|
||||
code: '',
|
||||
code: "",
|
||||
peerConnections: {} as Record<string, RTCPeerConnection>,
|
||||
iceServers: [] as RTCIceServer[],
|
||||
}),
|
||||
actions: {
|
||||
setCode(code: string) {
|
||||
@@ -12,5 +13,9 @@ export const useStreamerStore = defineStore('streamer', {
|
||||
addPeerConnection(id: string, pc: RTCPeerConnection) {
|
||||
this.peerConnections[id] = pc;
|
||||
},
|
||||
setIceServers(iceServers: RTCIceServer[]) {
|
||||
this.iceServers = iceServers;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user