UNPKG

@oiij/use

Version:

Som Composable Functions for Vue 3

142 lines (140 loc) 3.87 kB
import { useWebSocket } from "./use-web-socket.js"; import { createEventHook } from "@vueuse/core"; import { onUnmounted, ref } from "vue"; //#region src/composables/use-web-rtc.ts function useWebRTC(url, options) { const { protocols = [],...rtcConfig } = options ?? {}; const onReadyEvent = createEventHook(); const onConnectionEvent = createEventHook(); const onConnectionStreamEvent = createEventHook(); const controller = new AbortController(); const id = ref(); const connected = ref([]); const status = ref("pending"); const peer = new RTCPeerConnection(rtcConfig); const iceConnectionState = ref(peer.iceConnectionState); const signalingState = ref(peer.signalingState); const connectionState = ref(peer.connectionState); const { registerHandler, send } = useWebSocket(url, { protocols, parseMessage: true }); function onReady() { onReadyEvent.trigger(); } function onConnection(ev) { onConnectionEvent.trigger(ev); } function onConnectionStream(ev) { onConnectionStreamEvent.trigger(ev); } function onIcecandidate(ev) { if (ev.candidate) send({ type: "ice-candidate", payload: { candidate: ev.candidate } }); } registerHandler("register", ({ payload }) => { const { key } = payload; id.value = key; status.value = "ready"; onReady(); }); registerHandler("offer", async ({ payload }) => { const { key, desc } = payload; await peer.setRemoteDescription(desc); const answer = await peer.createAnswer(); await peer.setLocalDescription(answer); send({ type: "answer", payload: { key, desc: answer } }); }); registerHandler("answer", async ({ payload }) => { const { key, desc } = payload; await peer.setRemoteDescription(desc); if (!connected.value.includes(key)) connected.value.push(key); send({ type: "answer-ok", payload: { key } }); }); registerHandler("answer-ok", ({ payload }) => { const { key } = payload; status.value = "connected"; if (!connected.value.includes(key)) connected.value.push(key); }); registerHandler("ice-candidate", async ({ payload }) => { const { candidate } = payload; try { await peer.addIceCandidate(candidate); } catch (error) { console.error(error); } }); async function connect(id$1, label = "label") { const dataChannel = peer.createDataChannel(label); const offer = await peer.createOffer(); await peer.setLocalDescription(offer); send({ type: "offer", payload: { key: id$1, desc: offer } }); return dataChannel; } async function connectStream(id$1, stream) { stream.getTracks().forEach((track) => { peer.addTrack(track, stream); }); const offer = await peer.createOffer(); await peer.setLocalDescription(offer); send({ type: "offer", payload: { key: id$1, desc: offer } }); return peer; } peer.addEventListener("icecandidate", onIcecandidate, { signal: controller.signal }); peer.addEventListener("iceconnectionstatechange", () => { iceConnectionState.value = peer.iceConnectionState; }, { signal: controller.signal }); peer.addEventListener("signalingstatechange", () => { signalingState.value = peer.signalingState; }, { signal: controller.signal }); peer.addEventListener("connectionstatechange", () => { connectionState.value = peer.connectionState; }, { signal: controller.signal }); peer.addEventListener("datachannel", onConnection, { signal: controller.signal }); peer.addEventListener("track", onConnectionStream, { signal: controller.signal }); function destroy() { controller.abort(); peer.close(); } onUnmounted(() => { destroy(); }); return { id, connected, status, peer, signalingState, connectionState, connect, connectStream, onReady: onReadyEvent.on, onConnection: onConnectionEvent.on, onConnectionStream: onConnectionStreamEvent.on }; } //#endregion export { useWebRTC };