@oiij/use
Version:
Som Composable Functions for Vue 3
142 lines (140 loc) • 3.87 kB
JavaScript
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 };