UNPKG

@oiij/web-rtc

Version:
205 lines (203 loc) 5.96 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { useWebRTC: () => useWebRTC }); module.exports = __toCommonJS(index_exports); var import_vue = require("vue"); function useWebRTC(options) { const { host = "127.0.0.1", port = 6789, path = "/_web-rtc", protocols = [], ...rtcConfig } = options ?? {}; const controller = new AbortController(); const id = (0, import_vue.ref)(); const connected = (0, import_vue.ref)([]); const status = (0, import_vue.ref)("pending"); const ws = new WebSocket(`ws://${host}:${port}${path}`, protocols); const peer = new RTCPeerConnection(rtcConfig); const iceConnectionState = (0, import_vue.ref)(peer.iceConnectionState); const signalingState = (0, import_vue.ref)(peer.signalingState); const connectionState = (0, import_vue.ref)(peer.connectionState); let onReadyFn = null; function onReady() { if (onReadyFn && typeof onReadyFn === "function") { onReadyFn(); } } let onConnectionFn = null; function onConnection(ev) { if (onConnectionFn && typeof onConnectionFn === "function") { onConnectionFn(ev); } } let onConnectionStreamFn = null; function onConnectionStream(ev) { if (onConnectionStreamFn && typeof onConnectionStreamFn === "function") { onConnectionStreamFn(ev); } } function sendMessage(data) { ws.send(JSON.stringify(data)); } function onIcecandidate(ev) { if (ev.candidate) { sendMessage({ type: "ice-candidate", payload: { candidate: ev.candidate } }); } } async function onMessage(ev) { try { const { type, payload } = JSON.parse(ev.data); const { key, desc, candidate } = payload; switch (type) { case "register": id.value = key; status.value = "ready"; onReady(); break; case "offer": { if (!desc || !key) return; await peer.setRemoteDescription(desc); const answer = await peer.createAnswer(); await peer.setLocalDescription(answer); sendMessage({ type: "answer", payload: { key, desc: answer } }); } break; case "answer": if (!desc || !key) return; await peer.setRemoteDescription(desc); sendMessage({ type: "answer-ok", payload: { key } }); break; case "answer-ok": if (!key) { return; } status.value = "connected"; if (!connected.value.includes(key)) { connected.value.push(key); } break; case "ice-candidate": if (!candidate) return; try { await peer.addIceCandidate(candidate); } catch (error) { console.error(error); } break; default: break; } } catch (error) { console.error(error); } } async function connect(id2, label = "label") { const dataChannel = peer.createDataChannel(label); const offer = await peer.createOffer(); await peer.setLocalDescription(offer); sendMessage({ type: "offer", payload: { key: id2, desc: offer } }); return dataChannel; } async function connectStream(id2, stream) { stream.getTracks().forEach((track) => { peer.addTrack(track, stream); }); const offer = await peer.createOffer(); await peer.setLocalDescription(offer); sendMessage({ type: "offer", payload: { key: id2, desc: offer } }); return peer; } ws.addEventListener("message", onMessage, { signal: controller.signal }); 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(); ws.close(); peer.close(); } (0, import_vue.onUnmounted)(() => { destroy(); }); return { id, connected, status, ws, peer, signalingState, connectionState, onReady: (fn) => { onReadyFn = fn; }, connect, onConnection: (fn) => { onConnectionFn = fn; }, connectStream, onConnectionStream: (fn) => { onConnectionStreamFn = fn; } }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useWebRTC });