@wetspace/wetrtc 2.1.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/core/constant.d.ts +6 -0
- package/es/core/hook.d.ts +6 -15
- package/es/core/index.d.ts +25 -45
- package/es/index.d.ts +2 -2
- package/es/index.js +1 -1
- package/es/libs/index.d.ts +14 -4
- package/lib/core/constant.d.ts +6 -0
- package/lib/core/hook.d.ts +6 -15
- package/lib/core/index.d.ts +25 -45
- package/lib/index.d.ts +2 -2
- package/lib/index.js +1 -1
- package/lib/libs/index.d.ts +14 -4
- package/package.json +2 -5
package/es/core/hook.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { WetRTCPlayer } from './index';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ConnectionState } from './index';
|
|
3
3
|
import type { MutableRefObject } from 'react';
|
|
4
|
+
import type { ErrorMsgType } from '../libs';
|
|
5
|
+
import { WetCreateConnectOneOption } from './constant';
|
|
4
6
|
interface UseWebRtcRetrun {
|
|
5
|
-
connect: (
|
|
7
|
+
connect: (sdp?: RTCSessionDescriptionInit) => Promise<void>;
|
|
6
8
|
disconnect: () => void;
|
|
7
9
|
play: (type: 'remote' | 'local', player: WetRTCPlayer, outType?: 'video' | 'audio') => void;
|
|
8
10
|
answerAction: (sdp: RTCSessionDescriptionInit) => void;
|
|
@@ -13,24 +15,13 @@ interface UseWebRtcRetrun {
|
|
|
13
15
|
audiooutput: boolean;
|
|
14
16
|
videoinput: boolean;
|
|
15
17
|
};
|
|
16
|
-
useAbleRef: MutableRefObject<{
|
|
17
|
-
audioinput: boolean;
|
|
18
|
-
audiooutput: boolean;
|
|
19
|
-
videoinput: boolean;
|
|
20
|
-
}>;
|
|
21
18
|
}
|
|
22
19
|
interface UseWebRtcParams {
|
|
23
20
|
name?: string | number | MutableRefObject<string | number>;
|
|
24
21
|
senderSdp: (sdp: RTCSessionDescriptionInit) => void;
|
|
25
22
|
senderIce?: (ice: RTCIceCandidate) => void;
|
|
26
|
-
connectionConfig?:
|
|
27
|
-
|
|
28
|
-
constraints?: MediaStreamConstraints;
|
|
29
|
-
};
|
|
30
|
-
onError?: (err: {
|
|
31
|
-
code: string;
|
|
32
|
-
message: string;
|
|
33
|
-
}) => void;
|
|
23
|
+
connectionConfig?: Partial<WetCreateConnectOneOption>;
|
|
24
|
+
onError?: (err: ErrorMsgType) => void;
|
|
34
25
|
isLisenByts?: boolean;
|
|
35
26
|
}
|
|
36
27
|
declare function useWetRTC(options: Omit<UseWebRtcParams, 'isLisenByts'> & {
|
package/es/core/index.d.ts
CHANGED
|
@@ -1,59 +1,39 @@
|
|
|
1
|
+
import type { WetCreateConnectOneOption } from './constant';
|
|
1
2
|
export declare type WetRTCPlayer = HTMLVideoElement | HTMLAudioElement | null | undefined;
|
|
2
3
|
export declare type ConnectionState = 'new' | 'connected' | 'disconnected' | 'closed' | 'failed';
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
state: ConnectionState;
|
|
6
|
-
uuid: string;
|
|
7
|
-
name: string;
|
|
8
|
-
streams: MediaStream | null;
|
|
9
|
-
transDirect: 'recvonly' | 'sendonly' | 'sendrecv';
|
|
10
|
-
closeBytsListen: (() => void) | null;
|
|
11
|
-
}
|
|
12
|
-
export interface WetRTCItemType {
|
|
13
|
-
connect: (sdp?: RTCSessionDescriptionInit | undefined, stateChange?: ((state: ConnectionState) => void) | undefined) => Promise<RTCSessionDescriptionInit | null>;
|
|
14
|
-
play?: (player: WetRTCPlayer, type?: 'video' | 'audio') => void;
|
|
15
|
-
setRemoteSdp: (sdp: RTCSessionDescriptionInit) => void;
|
|
16
|
-
addIceCandidate: (sdp: RTCIceCandidate) => void;
|
|
17
|
-
self: WetRTCConnectctItem;
|
|
18
|
-
addListenByts: (callFn: (...params: any) => any) => () => void;
|
|
19
|
-
}
|
|
20
|
-
export interface WetCreateConnectOneOption {
|
|
21
|
-
configuration?: RTCConfiguration;
|
|
22
|
-
uuid?: string;
|
|
23
|
-
name?: string;
|
|
24
|
-
transDirect?: 'recvonly' | 'sendonly' | 'sendrecv';
|
|
25
|
-
iceCb?: (candidate: RTCIceCandidate) => void;
|
|
26
|
-
}
|
|
4
|
+
export declare type ErrorFn = ((...p: any) => void) | null;
|
|
5
|
+
export declare type EventType = 'error' | 'state' | 'byts' | 'ice';
|
|
27
6
|
export declare class WetRTC {
|
|
28
|
-
|
|
29
|
-
|
|
7
|
+
constructor(options?: Partial<WetCreateConnectOneOption>);
|
|
8
|
+
state: ConnectionState;
|
|
9
|
+
isUseAbles: {
|
|
10
|
+
audiooutput: boolean;
|
|
11
|
+
audioinput: boolean;
|
|
12
|
+
videoinput: boolean;
|
|
13
|
+
};
|
|
30
14
|
private streamControl;
|
|
31
|
-
private
|
|
32
|
-
|
|
15
|
+
private runError;
|
|
16
|
+
private runByt;
|
|
17
|
+
private EventMap;
|
|
18
|
+
private RTCPeerIns;
|
|
19
|
+
private removeListenFn;
|
|
20
|
+
private WetOption;
|
|
33
21
|
getUseAbleDevices(): Promise<MediaDeviceInfo[] | null>;
|
|
22
|
+
addEventListener(type: EventType, fn: (...p: any) => any): void;
|
|
23
|
+
removeEventListener(type: EventType, fn: (...p: any) => any): void;
|
|
34
24
|
private captureStream;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
createConnectOne(option: Omit<WetCreateConnectOneOption, 'transDirect'> & {
|
|
38
|
-
transDirect: 'sendonly';
|
|
39
|
-
}): Omit<WetRTCItemType, 'play'>;
|
|
40
|
-
createConnectOne(option: Omit<WetCreateConnectOneOption, 'transDirect'> & {
|
|
41
|
-
transDirect?: 'recvonly' | 'sendrecv';
|
|
42
|
-
}): WetRTCItemType;
|
|
43
|
-
/**
|
|
44
|
-
* 获取特定的连接
|
|
45
|
-
*/
|
|
46
|
-
getConnectById(uuid: string): WetRTCConnectctItem | undefined;
|
|
47
|
-
/**
|
|
48
|
-
* 关闭流的
|
|
49
|
-
*/
|
|
50
|
-
private closeStream;
|
|
25
|
+
connect(sdp?: RTCSessionDescriptionInit): Promise<RTCSessionDescriptionInit | null>;
|
|
26
|
+
private closePeerInsTracks;
|
|
51
27
|
/**
|
|
52
28
|
* 关闭连接
|
|
53
29
|
*/
|
|
54
|
-
disconnect(
|
|
30
|
+
disconnect(): void;
|
|
55
31
|
/**
|
|
56
32
|
* 关闭所有的流
|
|
57
33
|
*/
|
|
58
34
|
close(): void;
|
|
35
|
+
setRemoteSdp(_sdp: RTCSessionDescriptionInit): Promise<void>;
|
|
36
|
+
addIceCandidate(_sdp: RTCIceCandidate): Promise<void>;
|
|
37
|
+
playRemote(player: WetRTCPlayer, type?: 'video' | 'audio'): Promise<void>;
|
|
38
|
+
playLocal(player: WetRTCPlayer, type?: 'video' | 'audio'): Promise<void>;
|
|
59
39
|
}
|
package/es/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getUseAbleDevices, getMediaStream, concatStream, filterStream, getRtcPeerTracks } from './libs';
|
|
1
|
+
import { getUseAbleDevices, getMediaStream, concatStream, filterStream, getRtcPeerTracks, stopStreamTrack } from './libs';
|
|
2
2
|
import { streamToRecord } from './libs/record';
|
|
3
3
|
import { WetRTC } from './core/index';
|
|
4
4
|
import { useWetRTC } from './core/hook';
|
|
5
|
-
export { getUseAbleDevices, getMediaStream, concatStream, filterStream, streamToRecord, getRtcPeerTracks, useWetRTC, };
|
|
5
|
+
export { getUseAbleDevices, getMediaStream, concatStream, filterStream, streamToRecord, getRtcPeerTracks, useWetRTC, stopStreamTrack, };
|
|
6
6
|
export default WetRTC;
|
package/es/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{v4}from"uuid";import{useState,useRef,useEffect,useCallback}from"react";function __awaiter(e,o,a,c){return new(a=a||Promise)(function(n,t){function s(e){try{i(c.next(e))}catch(e){t(e)}}function r(e){try{i(c.throw(e))}catch(e){t(e)}}function i(e){var t;e.done?n(e.value):((t=e.value)instanceof a?t:new a(function(e){e(t)})).then(s,r)}i((c=c.apply(e,o||[])).next())})}const getUseAbleDevices=()=>__awaiter(void 0,void 0,void 0,function*(){return navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?yield navigator.mediaDevices.enumerateDevices():(console.error("navigator.mediaDevices.enumerateDevices"),null)}),getMediaStream=(e="display")=>{const s="display"===e?"getDisplayMedia":"getUserMedia";return n=>__awaiter(void 0,void 0,void 0,function*(){if(navigator.mediaDevices[s]){var e=n||{video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,enableBackground:!1,suppressLocalAudioPlayback:!0}};const t=yield navigator.mediaDevices[s](e);return{streams:t,close(){t.getTracks().forEach(e=>{e.stop()})}}}return console.error("不支持mediaDevices"),null})},concatStream=e=>{let t=[];return e.forEach(e=>{t=[...t,...e.getTracks()]}),new MediaStream(t)},filterStream=(e,t)=>{let n=[];return e.forEach(e=>{n=[...n,...e.getTracks().filter(e=>t?e.kind===t:e)]}),new MediaStream(n)},getRtcPeerTracks=(e,t)=>{const n={receivers(){const t=[];return e.getReceivers().forEach(e=>{e.track&&t.push(e.track)}),t},senders(){const t=[];return e.getSenders().forEach(e=>{e.track&&t.push(e.track)}),t}};return t?n[t]():[...n.receivers(),...n.senders()]},SaveFileToLocal=(e,t)=>{e=URL.createObjectURL(e);const n=document.createElement("a");n.href=e,n.target="_blank",n.style.display="none",document.body.appendChild(n),n.download=t,n.click(),URL.revokeObjectURL(e),document.body.removeChild(n)},streamToRecord=(e,t={audioBitsPerSecond:128e3,videoBitsPerSecond:25e5,mimeType:"video/webm"})=>{const n=t.mimeType?t.mimeType.split("/"):["webm"];let s=(new Date).getTime().toString();const r=MediaRecorder.isTypeSupported(t.mimeType||"");if(!r)throw new Error(t.mimeType+"类型不支持");const i=new MediaRecorder(e,t);i.addEventListener("dataavailable",e=>{SaveFileToLocal(e.data,s+"."+n[(null===n||void 0===n?void 0:n.length)-1])});const o=()=>{r&&i.stop()};return{start:()=>{r&&i.start()},pause:()=>{r&&i.pause()},save:e=>{r&&(s=e||(new Date).getTime().toString(),o())},stop:o,resume:()=>{r&&i.resume()}}},DefaultConfiguration={iceServers:[{urls:"stun:stun.l.google.com:19302"}]};class WetRTC{constructor(e){this.rtcConnectMap=new Map,this.constraints={video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,suppressLocalAudioPlayback:!0}},this.streamControl=null,this.isUseAbles={audiooutput:!1,audioinput:!1,videoinput:!1},e&&(this.constraints=e),getUseAbleDevices().then(e=>{if(e){const t=e.map(e=>e.kind);this.isUseAbles.audioinput=t.includes("audioinput"),this.isUseAbles.videoinput=t.includes("videoinput"),this.isUseAbles.audiooutput=t.includes("audiooutput")}else this.isUseAbles.audioinput=!0,this.isUseAbles.videoinput=!0,this.isUseAbles.audiooutput=!0})}getUseAbleDevices(){return __awaiter(this,void 0,void 0,function*(){return yield getUseAbleDevices()})}captureStream(){return __awaiter(this,void 0,void 0,function*(){var e;return this.isUseAbles.audioinput||this.isUseAbles.videoinput?((e=yield getMediaStream("user")({video:!!this.isUseAbles.videoinput&&this.constraints.audio,audio:!!this.isUseAbles.audioinput&&this.constraints.audio}))&&(this.streamControl=e),e):null})}closeCaptureStream(){var e;null!==(e=this.streamControl)&&void 0!==e&&e.close(),this.streamControl=null}playLocalStream(e,t){this.streamControl&&e&&(e.setAttribute("autoPlay",""),e.setAttribute("playsInline",""),e.srcObject=filterStream([this.streamControl.streams],t))}createConnectOne(e){let o="new";const{configuration:t,uuid:n,name:s,transDirect:r,iceCb:a}=e||{};e=t||DefaultConfiguration;const c=r||"sendrecv",u=n||v4(),d=new RTCPeerConnection(e),l={RTCPeerIns:d,state:"new",name:s||u,uuid:"",streams:null,transDirect:c,closeBytsListen:null};return{connect:(r,i)=>__awaiter(this,void 0,void 0,function*(){var e;if(["sendrecv","sendonly"].includes(c)&&!this.streamControl&&!(yield this.captureStream()))return null;if(l.uuid=u,this.rtcConnectMap.set(u,l),d.addEventListener("track",e=>{e.streams&&e.streams[0]&&(l.streams=e.streams[0])}),Object.defineProperty(l,"state",{get(){return o},set(e){o=e,i&&i(e)}}),d.addEventListener("icecandidate",e=>{e.candidate&&a&&a(e.candidate)}),d.addEventListener("connectionstatechange",e=>{e=e.target;l.state=e.connectionState}),["sendrecv","sendonly"].includes(c)){const t=null===(e=this.streamControl)||void 0===e?void 0:e.streams;null!==t&&void 0!==t&&t.getTracks().forEach(e=>{d.addTrack(e,t)})}else try{d.addTransceiver("video",{direction:"recvonly"}),d.addTransceiver("audio",{direction:"recvonly"})}catch(e){const n=document.createElement("canvas"),s=n.captureStream();null!==s&&void 0!==s&&s.getTracks().forEach(e=>{d.addTrack(e,s)})}return r?(yield d.setRemoteDescription(r),e=yield d.createAnswer(),yield d.setLocalDescription(e),e):(e=yield d.createOffer(),yield d.setLocalDescription(e),e)}),play:"sendonly"===c?void 0:(e,t)=>{var n;l.uuid&&(n=d.getReceivers().map(e=>e.track),n=new MediaStream(n),null!=e&&e.setAttribute("autoplay",""),null!=e&&e.setAttribute("playsinline",""),e&&(e.srcObject=filterStream([n],t)))},self:l,setRemoteSdp:e=>__awaiter(this,void 0,void 0,function*(){if(e)try{yield d.setRemoteDescription(e),console.error("缺失sdp信息错误")}catch(e){l.state="failed"}else console.error("缺失sdp信息"),l.state="failed"}),addListenByts:s=>{let r=null;s(0);const e=setInterval(()=>{d.getStats().then(e=>{const t={bytesReceived:0};var n;e.forEach(e=>{"transport"===e.type&&(t.bytesReceived+=e.bytesReceived)}),r=(r&&(e=r.bytesReceived,n=t.bytesReceived,s(Number(((n-e)/1024).toFixed(2)))),Object.assign({},t))})},1e3);return l.closeBytsListen=()=>{s(0),clearInterval(e),l.closeBytsListen=null},l.closeBytsListen},addIceCandidate:e=>{d.addIceCandidate(e)}}}getConnectById(e){return this.rtcConnectMap.get(e)}closeStream(e){if(e&&e.RTCPeerIns){const t={recvonly:()=>getRtcPeerTracks(e.RTCPeerIns,"receivers"),sendonly:()=>getRtcPeerTracks(e.RTCPeerIns,"senders"),sendrecv:()=>getRtcPeerTracks(e.RTCPeerIns)},n=t[e.transDirect]();n.forEach(e=>{null!=e&&e.stop()}),e.streams=null}}disconnect(e){if(e){if(this.rtcConnectMap.has(e)){const t=this.getConnectById(e);null!==t&&void 0!==t&&t.closeBytsListen&&null!==t&&void 0!==t&&t.closeBytsListen(),t.state="closed",this.closeStream(t),null!==t&&void 0!==t&&t.RTCPeerIns.close(),this.rtcConnectMap.delete(e)}}else this.rtcConnectMap.forEach(e=>{e.closeBytsListen&&e.closeBytsListen(),e.state="closed",this.closeStream(e),e.RTCPeerIns.close()}),this.rtcConnectMap.clear()}close(){this.disconnect(),this.closeCaptureStream()}}function useWetRTC(e){const{connectionConfig:s,name:r,isLisenByts:t}=e,[d,l]=useState(0),i=useRef(""),o=useRef(e.senderSdp),v=useRef(e.senderIce),a=useRef(e.onError),c=(o.current=e.senderSdp,v.current=e.senderIce,a.current=e.onError,useRef(null)),u=useRef(null),[p,m]=useState({audioinput:!1,audiooutput:!1,videoinput:!1}),f=useRef({audioinput:!1,audiooutput:!1,videoinput:!1}),[n,y]=useState("new");useEffect(()=>{c.current=new WetRTC(s&&(null===s||void 0===s?void 0:s.constraints)),c.current.getUseAbleDevices().then(e=>{const t={audioinput:!0,audiooutput:!0,videoinput:!0};if(e){const n=e.map(e=>e.kind);t.audioinput=n.includes("audioinput"),t.audiooutput=n.includes("audiooutput"),t.videoinput=n.includes("videoinput"),f.current=Object.assign({},t)}m(()=>t)})},[]),useEffect(()=>{var e;"connected"===n&&t&&null!==(e=u.current)&&void 0!==e&&e.addListenByts(e=>{l(e)})},[n,t]);return{connect:useCallback((t="sendrecv",n)=>__awaiter(this,void 0,void 0,function*(){var e;r?i.current="object"==typeof r?r.current:r:i.current=i.current||v4(),c.current&&i.current&&(u.current=c.current.createConnectOne({uuid:i.current+"",transDirect:t,iceCb:v.current,configuration:s&&s.configuration}),(e=yield u.current.connect(n,e=>{y(()=>e)}))?o.current(e):(console.error("sdp获取失败,连接错误"),a.current&&a.current({code:"error",message:"sdp获取失败,连接错误"})))}),[r&&"object"==typeof r?r.current:r]),disconnect:()=>{var e;null!==(e=c.current)&&void 0!==e&&e.close()},play:(e,t,n)=>{"local"===e?null!==(e=c.current)&&void 0!==e&&e.playLocalStream(t,n):u.current&&u.current.play&&u.current.play(t,n)},answerAction:e=>{var t;null!==(t=u.current)&&void 0!==t&&t.setRemoteSdp(e)},byts:d,connectState:n,useAblesState:p,useAbleRef:f}}export{concatStream,WetRTC as default,filterStream,getMediaStream,getRtcPeerTracks,getUseAbleDevices,streamToRecord,useWetRTC};
|
|
1
|
+
import{useState,useRef,useEffect,useCallback}from"react";function __awaiter(e,o,a,c){return new(a=a||Promise)(function(n,t){function r(e){try{s(c.next(e))}catch(e){t(e)}}function i(e){try{s(c.throw(e))}catch(e){t(e)}}function s(e){var t;e.done?n(e.value):((t=e.value)instanceof a?t:new a(function(e){e(t)})).then(r,i)}s((c=c.apply(e,o||[])).next())})}const getUseAbleDevices=()=>__awaiter(void 0,void 0,void 0,function*(){return navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?yield navigator.mediaDevices.enumerateDevices():(console.error("navigator.mediaDevices.enumerateDevices"),null)}),getMediaStream=(e="display",r)=>{const i="display"===e?"getDisplayMedia":"getUserMedia";return n=>__awaiter(void 0,void 0,void 0,function*(){let e=null;if(navigator.mediaDevices[i]){var t=Object.assign({video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,enableBackground:!1,suppressLocalAudioPlayback:!0}},n);try{e=yield navigator.mediaDevices[i](t)}catch(e){r&&r({name:e.name||"Error",message:e.message||"内部错误"})}}else r&&r({name:"CompatibleError",message:"不支持navigator.mediaDevices"});return e})},stopStreamTrack=e=>{e&&e.getTracks().forEach(e=>{e.stop()})},concatStream=e=>{let t=[];return e.forEach(e=>{t=[...t,...e.getTracks()]}),new MediaStream(t)},filterStream=(e,t)=>{let n=[];return e.forEach(e=>{n=[...n,...e.getTracks().filter(e=>t?e.kind===t:e)]}),new MediaStream(n)},getRtcPeerTracks=(e,t)=>{const n={receivers(){const t=[];return e.getReceivers().forEach(e=>{e.track&&t.push(e.track)}),t},senders(){const t=[];return e.getSenders().forEach(e=>{e.track&&t.push(e.track)}),t}};return t?n[t]():[...n.receivers(),...n.senders()]},listenerEvent=(e,t)=>(e.addEventListener("track",t.track),e.addEventListener("icecandidate",t.icecandidate),e.addEventListener("connectionstatechange",t.connectionstatechange),()=>{e.removeEventListener("track",t.track),e.removeEventListener("icecandidate",t.icecandidate),e.removeEventListener("connectionstatechange",t.connectionstatechange)}),SaveFileToLocal=(e,t)=>{e=URL.createObjectURL(e);const n=document.createElement("a");n.href=e,n.target="_blank",n.style.display="none",document.body.appendChild(n),n.download=t,n.click(),URL.revokeObjectURL(e),document.body.removeChild(n)},streamToRecord=(e,t={audioBitsPerSecond:128e3,videoBitsPerSecond:25e5,mimeType:"video/webm"})=>{const n=t.mimeType?t.mimeType.split("/"):["webm"];let r=(new Date).getTime().toString();const i=MediaRecorder.isTypeSupported(t.mimeType||"");if(!i)throw new Error(t.mimeType+"类型不支持");const s=new MediaRecorder(e,t);s.addEventListener("dataavailable",e=>{SaveFileToLocal(e.data,r+"."+n[(null===n||void 0===n?void 0:n.length)-1])});const o=()=>{i&&s.stop()};return{start:()=>{i&&s.start()},pause:()=>{i&&s.pause()},save:e=>{i&&(r=e||(new Date).getTime().toString(),o())},stop:o,resume:()=>{i&&s.resume()}}},DEFAULT_WetOption={transDirect:"sendrecv",configuration:{iceServers:[{urls:"stun:stun.l.google.com:19302"}]},constraints:{video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,suppressLocalAudioPlayback:!0}}};class WetRTC{constructor(e){this.state="new",this.isUseAbles={audiooutput:!1,audioinput:!1,videoinput:!1},this.streamControl={close:e=>{const t={remote:()=>{stopStreamTrack(this.streamControl.remoteStreams),this.streamControl.remoteStreams=null},local:()=>{stopStreamTrack(this.streamControl.localStreams),this.streamControl.localStreams=null}};e?t[e]():(t.local(),t.remote())}},this.runByt={time:null,close:()=>{this.runByt.time&&clearInterval(this.runByt.time)},run:()=>{const i=this.EventMap.get("byts");let s=null;i&&0<i.length&&(null!==i&&void 0!==i&&i.forEach(e=>{e(0)}),this.runByt.time=setInterval(()=>{var e;null!==(e=this.RTCPeerIns)&&void 0!==e&&e.getStats().then(e=>{const t={bytesReceived:0};if(e.forEach(e=>{"transport"===e.type&&(t.bytesReceived+=e.bytesReceived)}),s){const n=s.bytesReceived,r=t.bytesReceived;null!==i&&void 0!==i&&i.forEach(e=>{e(Number(((r-n)/1024).toFixed(2)))}),s=Object.assign({},t)}else s=Object.assign({},t)})},1e3))}},this.EventMap=new Map([]),this.RTCPeerIns=null,this.removeListenFn=()=>{},this.WetOption=Object.assign({},DEFAULT_WetOption),this.WetOption=Object.assign(Object.assign({},this.WetOption),e)}runError(t){const e=this.EventMap.get("error");null!==e&&void 0!==e&&e.forEach(e=>{e(t)})}getUseAbleDevices(){return __awaiter(this,void 0,void 0,function*(){return yield getUseAbleDevices()})}addEventListener(e,t){const n=this.EventMap.get(e);n?n.find(e=>e===t)||(n.push(t),this.EventMap.set(e,n)):this.EventMap.set(e,[t])}removeEventListener(e,t){const n=this.EventMap.get(e);var r;n&&(r=n.filter(e=>e!==t),this.EventMap.set(e,r))}captureStream(){return __awaiter(this,void 0,void 0,function*(){const e=yield getUseAbleDevices();if(e){const n=e.map(e=>e.kind);this.isUseAbles.audioinput=n.includes("audioinput"),this.isUseAbles.videoinput=n.includes("videoinput"),this.isUseAbles.audiooutput=n.includes("audiooutput")}else this.isUseAbles.audioinput=!0,this.isUseAbles.videoinput=!0,this.isUseAbles.audiooutput=!0;var t;return this.isUseAbles.audioinput||this.isUseAbles.videoinput?((t=yield getMediaStream("user",e=>{this.runError(e)})({video:!!this.isUseAbles.videoinput&&this.WetOption.constraints.video,audio:!!this.isUseAbles.audioinput&&this.WetOption.constraints.audio}))&&(this.streamControl.localStreams=t),t):(this.runError({name:"StreamError",message:"音频输入设备,视频输入设备均不可用"}),null)})}connect(o){var a;return __awaiter(this,void 0,void 0,function*(){if(["sendrecv","sendonly"].includes(this.WetOption.transDirect)&&(!this.streamControl.localStreams&&!(yield this.captureStream())))return null;let n="new",r=this;Object.defineProperty(this,"state",{get(){return n},set(e){"connected"===(n=e)?r.runByt.run():["disconnected","closed","failed"].includes(e)&&r.runByt.close();const t=r.EventMap.get("state");null!==t&&void 0!==t&&t.forEach(e=>{e(n)})}});var e;if(this.state="new",this.RTCPeerIns=new RTCPeerConnection(this.WetOption.configuration),this.removeListenFn=listenerEvent(this.RTCPeerIns,{track:e=>{e.streams&&e.streams[0]&&(this.streamControl.remoteStreams=e.streams[0])},icecandidate:t=>{if(t.candidate){const e=r.EventMap.get("ice");null!==e&&void 0!==e&&e.forEach(e=>{e(t.candidate)})}},connectionstatechange:e=>{e=e.target;this.state=e.connectionState}}),["sendrecv","sendonly"].includes(this.WetOption.transDirect)){const i=null===(a=this.streamControl)||void 0===a?void 0:a.localStreams;null!==i&&void 0!==i&&i.getTracks().forEach(e=>{var t;null!==(t=this.RTCPeerIns)&&void 0!==t&&t.addTrack(e,i)})}else try{this.RTCPeerIns.addTransceiver("video",{direction:"recvonly"}),this.RTCPeerIns.addTransceiver("audio",{direction:"recvonly"})}catch(e){const t=document.createElement("canvas"),s=t.captureStream();null!==s&&void 0!==s&&s.getTracks().forEach(e=>{var t;null!==(t=this.RTCPeerIns)&&void 0!==t&&t.addTrack(e,s)})}return o?(yield this.setRemoteSdp(o),e=yield this.RTCPeerIns.createAnswer(),yield this.RTCPeerIns.setLocalDescription(e),e):(e=yield this.RTCPeerIns.createOffer(),yield this.RTCPeerIns.setLocalDescription(e),e)})}closePeerInsTracks(){if(this.RTCPeerIns){const e={recvonly:()=>getRtcPeerTracks(this.RTCPeerIns,"receivers"),sendonly:()=>getRtcPeerTracks(this.RTCPeerIns,"senders"),sendrecv:()=>getRtcPeerTracks(this.RTCPeerIns)},t=e[this.WetOption.transDirect]();t.forEach(e=>{null!=e&&e.stop()})}}disconnect(){this.state="closed",this.removeListenFn(),this.closePeerInsTracks()}close(){this.disconnect(),this.streamControl.close()}setRemoteSdp(e){var t;return __awaiter(this,void 0,void 0,function*(){if(!e)return this.runError({name:"OperationError",message:"缺失sdp信息"}),void(this.state="failed");try{yield null===(t=this.RTCPeerIns)||void 0===t?void 0:t.setRemoteDescription(e)}catch(e){this.state="failed",this.runError({name:e.name||"Error",message:e.message||"内部错误"})}})}addIceCandidate(e){var t;return __awaiter(this,void 0,void 0,function*(){if(!e)return this.runError({name:"OperationError",message:"缺失IceSdp信息"}),void(this.state="failed");try{yield null===(t=this.RTCPeerIns)||void 0===t?void 0:t.addIceCandidate(e)}catch(e){this.state="failed",this.runError({name:e.name||"Error",message:e.message||"内部错误"})}})}playRemote(t,n){return __awaiter(this,void 0,void 0,function*(){var e;this.RTCPeerIns&&(e=this.RTCPeerIns.getReceivers().map(e=>e.track),e=new MediaStream(e),null!=t&&t.setAttribute("autoplay",""),null!=t&&t.setAttribute("playsinline",""),t&&(t.srcObject=filterStream([e],n)))})}playLocal(t,n){return __awaiter(this,void 0,void 0,function*(){this.streamControl.localStreams||(yield this.captureStream());var e=this.streamControl.localStreams;null!=t&&t.setAttribute("autoplay",""),null!=t&&t.setAttribute("playsinline",""),t&&(t.srcObject=filterStream([e],n))})}}let getRandomValues;const rnds8=new Uint8Array(16);function rng(){if(!getRandomValues&&!(getRandomValues="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return getRandomValues(rnds8)}const byteToHex=[];for(let e=0;e<256;++e)byteToHex.push((e+256).toString(16).slice(1));function unsafeStringify(e,t=0){return(byteToHex[e[t+0]]+byteToHex[e[t+1]]+byteToHex[e[t+2]]+byteToHex[e[t+3]]+"-"+byteToHex[e[t+4]]+byteToHex[e[t+5]]+"-"+byteToHex[e[t+6]]+byteToHex[e[t+7]]+"-"+byteToHex[e[t+8]]+byteToHex[e[t+9]]+"-"+byteToHex[e[t+10]]+byteToHex[e[t+11]]+byteToHex[e[t+12]]+byteToHex[e[t+13]]+byteToHex[e[t+14]]+byteToHex[e[t+15]]).toLowerCase()}const randomUUID="undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto);var native={randomUUID:randomUUID};function v4(e,t,n){if(native.randomUUID&&!t&&!e)return native.randomUUID();const r=(e=e||{}).random||(e.rng||rng)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(let e=0;e<16;++e)t[n+e]=r[e];return t}return unsafeStringify(r)}function useWetRTC(e){const{connectionConfig:t,name:n,isLisenByts:r}=e,[u,l]=useState(0),i=useRef(""),s=useRef(e.senderSdp),o=useRef(e.senderIce),a=useRef(e.onError),c=(s.current=e.senderSdp,o.current=e.senderIce,a.current=e.onError,useRef(null)),[v,m]=useState({audioinput:!1,audiooutput:!1,videoinput:!1}),p=useRef({audioinput:!1,audiooutput:!1,videoinput:!1}),[d,h]=useState("new");useEffect(()=>{c.current=new WetRTC(t),c.current.addEventListener("error",e=>{a.current&&a.current(e)}),c.current.addEventListener("state",e=>{h(e)}),c.current.addEventListener("ice",e=>{o.current&&o.current(e)}),c.current.getUseAbleDevices().then(e=>{const t={audioinput:!0,audiooutput:!0,videoinput:!0};if(e){const n=e.map(e=>e.kind);t.audioinput=n.includes("audioinput"),t.audiooutput=n.includes("audiooutput"),t.videoinput=n.includes("videoinput"),p.current=Object.assign({},t)}m(()=>t)})},[]),useEffect(()=>{var e;"connected"===d&&r&&null!==(e=c.current)&&void 0!==e&&e.addEventListener("byts",e=>{l(e)})},[d,r]);return{connect:useCallback(t=>__awaiter(this,void 0,void 0,function*(){var e;n?i.current="object"==typeof n?n.current:n:i.current=i.current||v4(),c.current&&i.current&&((e=yield c.current.connect(t))&&s.current(e))}),[n&&"object"==typeof n?n.current:n]),disconnect:()=>{var e;null!==(e=c.current)&&void 0!==e&&e.close()},play:(e,t,n)=>{"local"===e?null!==(e=c.current)&&void 0!==e&&e.playLocal(t,n):null!==(e=c.current)&&void 0!==e&&e.playRemote(t,n)},answerAction:e=>{var t;null!==(t=c.current)&&void 0!==t&&t.setRemoteSdp(e)},byts:u,connectState:d,useAblesState:v}}export{concatStream,WetRTC as default,filterStream,getMediaStream,getRtcPeerTracks,getUseAbleDevices,stopStreamTrack,streamToRecord,useWetRTC};
|
package/es/libs/index.d.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* 获取可用设备
|
|
3
3
|
* @returns Promise
|
|
4
4
|
*/
|
|
5
|
+
export interface ErrorMsgType {
|
|
6
|
+
name: string;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
5
9
|
export declare const getUseAbleDevices: () => Promise<MediaDeviceInfo[] | null>;
|
|
6
10
|
/**
|
|
7
11
|
* 获取支持的约束
|
|
@@ -11,10 +15,11 @@ export declare const getSupportedConsitains: () => MediaTrackSupportedConstraint
|
|
|
11
15
|
* 选择分享流(本地视频流) / 捕获用户许可的输入信号流
|
|
12
16
|
* @returns Promise
|
|
13
17
|
*/
|
|
14
|
-
export declare const getMediaStream: (type?: 'user' | 'display') => (constraints?: MediaStreamConstraints | undefined) => Promise<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
export declare const getMediaStream: (type?: 'user' | 'display', onError?: ((params: ErrorMsgType) => void) | undefined) => (constraints?: MediaStreamConstraints | undefined) => Promise<MediaStream | null>;
|
|
19
|
+
/**
|
|
20
|
+
* 关闭流和轨道追踪
|
|
21
|
+
*/
|
|
22
|
+
export declare const stopStreamTrack: (streams?: MediaStream | null | undefined) => void;
|
|
18
23
|
/**
|
|
19
24
|
* 将多个stream 整合为一个stream
|
|
20
25
|
* @param options
|
|
@@ -29,3 +34,8 @@ export declare const concatStream: (options: MediaStream[]) => MediaStream;
|
|
|
29
34
|
*/
|
|
30
35
|
export declare const filterStream: (options: MediaStream[], type?: "audio" | "video" | undefined) => MediaStream;
|
|
31
36
|
export declare const getRtcPeerTracks: (peerConnection: RTCPeerConnection, type?: "receivers" | "senders" | undefined) => MediaStreamTrack[];
|
|
37
|
+
export declare const listenerEvent: (RTCPeerIns: RTCPeerConnection, option: {
|
|
38
|
+
track: (e: RTCTrackEvent) => void;
|
|
39
|
+
icecandidate: (e: RTCPeerConnectionIceEvent) => void;
|
|
40
|
+
connectionstatechange: (e: Event) => void;
|
|
41
|
+
}) => () => void;
|
package/lib/core/hook.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { WetRTCPlayer } from './index';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ConnectionState } from './index';
|
|
3
3
|
import type { MutableRefObject } from 'react';
|
|
4
|
+
import type { ErrorMsgType } from '../libs';
|
|
5
|
+
import { WetCreateConnectOneOption } from './constant';
|
|
4
6
|
interface UseWebRtcRetrun {
|
|
5
|
-
connect: (
|
|
7
|
+
connect: (sdp?: RTCSessionDescriptionInit) => Promise<void>;
|
|
6
8
|
disconnect: () => void;
|
|
7
9
|
play: (type: 'remote' | 'local', player: WetRTCPlayer, outType?: 'video' | 'audio') => void;
|
|
8
10
|
answerAction: (sdp: RTCSessionDescriptionInit) => void;
|
|
@@ -13,24 +15,13 @@ interface UseWebRtcRetrun {
|
|
|
13
15
|
audiooutput: boolean;
|
|
14
16
|
videoinput: boolean;
|
|
15
17
|
};
|
|
16
|
-
useAbleRef: MutableRefObject<{
|
|
17
|
-
audioinput: boolean;
|
|
18
|
-
audiooutput: boolean;
|
|
19
|
-
videoinput: boolean;
|
|
20
|
-
}>;
|
|
21
18
|
}
|
|
22
19
|
interface UseWebRtcParams {
|
|
23
20
|
name?: string | number | MutableRefObject<string | number>;
|
|
24
21
|
senderSdp: (sdp: RTCSessionDescriptionInit) => void;
|
|
25
22
|
senderIce?: (ice: RTCIceCandidate) => void;
|
|
26
|
-
connectionConfig?:
|
|
27
|
-
|
|
28
|
-
constraints?: MediaStreamConstraints;
|
|
29
|
-
};
|
|
30
|
-
onError?: (err: {
|
|
31
|
-
code: string;
|
|
32
|
-
message: string;
|
|
33
|
-
}) => void;
|
|
23
|
+
connectionConfig?: Partial<WetCreateConnectOneOption>;
|
|
24
|
+
onError?: (err: ErrorMsgType) => void;
|
|
34
25
|
isLisenByts?: boolean;
|
|
35
26
|
}
|
|
36
27
|
declare function useWetRTC(options: Omit<UseWebRtcParams, 'isLisenByts'> & {
|
package/lib/core/index.d.ts
CHANGED
|
@@ -1,59 +1,39 @@
|
|
|
1
|
+
import type { WetCreateConnectOneOption } from './constant';
|
|
1
2
|
export declare type WetRTCPlayer = HTMLVideoElement | HTMLAudioElement | null | undefined;
|
|
2
3
|
export declare type ConnectionState = 'new' | 'connected' | 'disconnected' | 'closed' | 'failed';
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
state: ConnectionState;
|
|
6
|
-
uuid: string;
|
|
7
|
-
name: string;
|
|
8
|
-
streams: MediaStream | null;
|
|
9
|
-
transDirect: 'recvonly' | 'sendonly' | 'sendrecv';
|
|
10
|
-
closeBytsListen: (() => void) | null;
|
|
11
|
-
}
|
|
12
|
-
export interface WetRTCItemType {
|
|
13
|
-
connect: (sdp?: RTCSessionDescriptionInit | undefined, stateChange?: ((state: ConnectionState) => void) | undefined) => Promise<RTCSessionDescriptionInit | null>;
|
|
14
|
-
play?: (player: WetRTCPlayer, type?: 'video' | 'audio') => void;
|
|
15
|
-
setRemoteSdp: (sdp: RTCSessionDescriptionInit) => void;
|
|
16
|
-
addIceCandidate: (sdp: RTCIceCandidate) => void;
|
|
17
|
-
self: WetRTCConnectctItem;
|
|
18
|
-
addListenByts: (callFn: (...params: any) => any) => () => void;
|
|
19
|
-
}
|
|
20
|
-
export interface WetCreateConnectOneOption {
|
|
21
|
-
configuration?: RTCConfiguration;
|
|
22
|
-
uuid?: string;
|
|
23
|
-
name?: string;
|
|
24
|
-
transDirect?: 'recvonly' | 'sendonly' | 'sendrecv';
|
|
25
|
-
iceCb?: (candidate: RTCIceCandidate) => void;
|
|
26
|
-
}
|
|
4
|
+
export declare type ErrorFn = ((...p: any) => void) | null;
|
|
5
|
+
export declare type EventType = 'error' | 'state' | 'byts' | 'ice';
|
|
27
6
|
export declare class WetRTC {
|
|
28
|
-
|
|
29
|
-
|
|
7
|
+
constructor(options?: Partial<WetCreateConnectOneOption>);
|
|
8
|
+
state: ConnectionState;
|
|
9
|
+
isUseAbles: {
|
|
10
|
+
audiooutput: boolean;
|
|
11
|
+
audioinput: boolean;
|
|
12
|
+
videoinput: boolean;
|
|
13
|
+
};
|
|
30
14
|
private streamControl;
|
|
31
|
-
private
|
|
32
|
-
|
|
15
|
+
private runError;
|
|
16
|
+
private runByt;
|
|
17
|
+
private EventMap;
|
|
18
|
+
private RTCPeerIns;
|
|
19
|
+
private removeListenFn;
|
|
20
|
+
private WetOption;
|
|
33
21
|
getUseAbleDevices(): Promise<MediaDeviceInfo[] | null>;
|
|
22
|
+
addEventListener(type: EventType, fn: (...p: any) => any): void;
|
|
23
|
+
removeEventListener(type: EventType, fn: (...p: any) => any): void;
|
|
34
24
|
private captureStream;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
createConnectOne(option: Omit<WetCreateConnectOneOption, 'transDirect'> & {
|
|
38
|
-
transDirect: 'sendonly';
|
|
39
|
-
}): Omit<WetRTCItemType, 'play'>;
|
|
40
|
-
createConnectOne(option: Omit<WetCreateConnectOneOption, 'transDirect'> & {
|
|
41
|
-
transDirect?: 'recvonly' | 'sendrecv';
|
|
42
|
-
}): WetRTCItemType;
|
|
43
|
-
/**
|
|
44
|
-
* 获取特定的连接
|
|
45
|
-
*/
|
|
46
|
-
getConnectById(uuid: string): WetRTCConnectctItem | undefined;
|
|
47
|
-
/**
|
|
48
|
-
* 关闭流的
|
|
49
|
-
*/
|
|
50
|
-
private closeStream;
|
|
25
|
+
connect(sdp?: RTCSessionDescriptionInit): Promise<RTCSessionDescriptionInit | null>;
|
|
26
|
+
private closePeerInsTracks;
|
|
51
27
|
/**
|
|
52
28
|
* 关闭连接
|
|
53
29
|
*/
|
|
54
|
-
disconnect(
|
|
30
|
+
disconnect(): void;
|
|
55
31
|
/**
|
|
56
32
|
* 关闭所有的流
|
|
57
33
|
*/
|
|
58
34
|
close(): void;
|
|
35
|
+
setRemoteSdp(_sdp: RTCSessionDescriptionInit): Promise<void>;
|
|
36
|
+
addIceCandidate(_sdp: RTCIceCandidate): Promise<void>;
|
|
37
|
+
playRemote(player: WetRTCPlayer, type?: 'video' | 'audio'): Promise<void>;
|
|
38
|
+
playLocal(player: WetRTCPlayer, type?: 'video' | 'audio'): Promise<void>;
|
|
59
39
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getUseAbleDevices, getMediaStream, concatStream, filterStream, getRtcPeerTracks } from './libs';
|
|
1
|
+
import { getUseAbleDevices, getMediaStream, concatStream, filterStream, getRtcPeerTracks, stopStreamTrack } from './libs';
|
|
2
2
|
import { streamToRecord } from './libs/record';
|
|
3
3
|
import { WetRTC } from './core/index';
|
|
4
4
|
import { useWetRTC } from './core/hook';
|
|
5
|
-
export { getUseAbleDevices, getMediaStream, concatStream, filterStream, streamToRecord, getRtcPeerTracks, useWetRTC, };
|
|
5
|
+
export { getUseAbleDevices, getMediaStream, concatStream, filterStream, streamToRecord, getRtcPeerTracks, useWetRTC, stopStreamTrack, };
|
|
6
6
|
export default WetRTC;
|
package/lib/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("uuid"),require("react")):"function"==typeof define&&define.amd?define(["exports","uuid","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).index={},e.uuid,e.react)}(this,function(e,h,b){"use strict";function g(e,o,c,a){return new(c=c||Promise)(function(n,t){function s(e){try{r(a.next(e))}catch(e){t(e)}}function i(e){try{r(a.throw(e))}catch(e){t(e)}}function r(e){var t;e.done?n(e.value):((t=e.value)instanceof c?t:new c(function(e){e(t)})).then(s,i)}r((a=a.apply(e,o||[])).next())})}const t=()=>g(void 0,void 0,void 0,function*(){return navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?yield navigator.mediaDevices.enumerateDevices():(console.error("navigator.mediaDevices.enumerateDevices"),null)}),n=(e="display")=>{const s="display"===e?"getDisplayMedia":"getUserMedia";return n=>g(void 0,void 0,void 0,function*(){if(navigator.mediaDevices[s]){var e=n||{video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,enableBackground:!1,suppressLocalAudioPlayback:!0}};const t=yield navigator.mediaDevices[s](e);return{streams:t,close(){t.getTracks().forEach(e=>{e.stop()})}}}return console.error("不支持mediaDevices"),null})};const r=(e,t)=>{let n=[];return e.forEach(e=>{n=[...n,...e.getTracks().filter(e=>t?e.kind===t:e)]}),new MediaStream(n)},s=(e,t)=>{const n={receivers(){const t=[];return e.getReceivers().forEach(e=>{e.track&&t.push(e.track)}),t},senders(){const t=[];return e.getSenders().forEach(e=>{e.track&&t.push(e.track)}),t}};return t?n[t]():[...n.receivers(),...n.senders()]};const v={iceServers:[{urls:"stun:stun.l.google.com:19302"}]};class C{constructor(e){this.rtcConnectMap=new Map,this.constraints={video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,suppressLocalAudioPlayback:!0}},this.streamControl=null,this.isUseAbles={audiooutput:!1,audioinput:!1,videoinput:!1},e&&(this.constraints=e),t().then(e=>{if(e){const t=e.map(e=>e.kind);this.isUseAbles.audioinput=t.includes("audioinput"),this.isUseAbles.videoinput=t.includes("videoinput"),this.isUseAbles.audiooutput=t.includes("audiooutput")}else this.isUseAbles.audioinput=!0,this.isUseAbles.videoinput=!0,this.isUseAbles.audiooutput=!0})}getUseAbleDevices(){return g(this,void 0,void 0,function*(){return yield t()})}captureStream(){return g(this,void 0,void 0,function*(){var e;return this.isUseAbles.audioinput||this.isUseAbles.videoinput?((e=yield n("user")({video:!!this.isUseAbles.videoinput&&this.constraints.audio,audio:!!this.isUseAbles.audioinput&&this.constraints.audio}))&&(this.streamControl=e),e):null})}closeCaptureStream(){var e;null!==(e=this.streamControl)&&void 0!==e&&e.close(),this.streamControl=null}playLocalStream(e,t){this.streamControl&&e&&(e.setAttribute("autoPlay",""),e.setAttribute("playsInline",""),e.srcObject=r([this.streamControl.streams],t))}createConnectOne(e){let o="new";const{configuration:t,uuid:n,name:s,transDirect:i,iceCb:c}=e||{};e=t||v;const a=i||"sendrecv",u=n||h.v4(),d=new RTCPeerConnection(e),l={RTCPeerIns:d,state:"new",name:s||u,uuid:"",streams:null,transDirect:a,closeBytsListen:null};return{connect:(i,r)=>g(this,void 0,void 0,function*(){var e;if(["sendrecv","sendonly"].includes(a)&&!this.streamControl&&!(yield this.captureStream()))return null;if(l.uuid=u,this.rtcConnectMap.set(u,l),d.addEventListener("track",e=>{e.streams&&e.streams[0]&&(l.streams=e.streams[0])}),Object.defineProperty(l,"state",{get(){return o},set(e){o=e,r&&r(e)}}),d.addEventListener("icecandidate",e=>{e.candidate&&c&&c(e.candidate)}),d.addEventListener("connectionstatechange",e=>{e=e.target;l.state=e.connectionState}),["sendrecv","sendonly"].includes(a)){const t=null===(e=this.streamControl)||void 0===e?void 0:e.streams;null!==t&&void 0!==t&&t.getTracks().forEach(e=>{d.addTrack(e,t)})}else try{d.addTransceiver("video",{direction:"recvonly"}),d.addTransceiver("audio",{direction:"recvonly"})}catch(e){const n=document.createElement("canvas"),s=n.captureStream();null!==s&&void 0!==s&&s.getTracks().forEach(e=>{d.addTrack(e,s)})}return i?(yield d.setRemoteDescription(i),e=yield d.createAnswer(),yield d.setLocalDescription(e),e):(e=yield d.createOffer(),yield d.setLocalDescription(e),e)}),play:"sendonly"===a?void 0:(e,t)=>{var n;l.uuid&&(n=d.getReceivers().map(e=>e.track),n=new MediaStream(n),null!=e&&e.setAttribute("autoplay",""),null!=e&&e.setAttribute("playsinline",""),e&&(e.srcObject=r([n],t)))},self:l,setRemoteSdp:e=>g(this,void 0,void 0,function*(){if(e)try{yield d.setRemoteDescription(e),console.error("缺失sdp信息错误")}catch(e){l.state="failed"}else console.error("缺失sdp信息"),l.state="failed"}),addListenByts:s=>{let i=null;s(0);const e=setInterval(()=>{d.getStats().then(e=>{const t={bytesReceived:0};var n;e.forEach(e=>{"transport"===e.type&&(t.bytesReceived+=e.bytesReceived)}),i=(i&&(e=i.bytesReceived,n=t.bytesReceived,s(Number(((n-e)/1024).toFixed(2)))),Object.assign({},t))})},1e3);return l.closeBytsListen=()=>{s(0),clearInterval(e),l.closeBytsListen=null},l.closeBytsListen},addIceCandidate:e=>{d.addIceCandidate(e)}}}getConnectById(e){return this.rtcConnectMap.get(e)}closeStream(e){if(e&&e.RTCPeerIns){const t={recvonly:()=>s(e.RTCPeerIns,"receivers"),sendonly:()=>s(e.RTCPeerIns,"senders"),sendrecv:()=>s(e.RTCPeerIns)},n=t[e.transDirect]();n.forEach(e=>{null!=e&&e.stop()}),e.streams=null}}disconnect(e){if(e){if(this.rtcConnectMap.has(e)){const t=this.getConnectById(e);null!==t&&void 0!==t&&t.closeBytsListen&&null!==t&&void 0!==t&&t.closeBytsListen(),t.state="closed",this.closeStream(t),null!==t&&void 0!==t&&t.RTCPeerIns.close(),this.rtcConnectMap.delete(e)}}else this.rtcConnectMap.forEach(e=>{e.closeBytsListen&&e.closeBytsListen(),e.state="closed",this.closeStream(e),e.RTCPeerIns.close()}),this.rtcConnectMap.clear()}close(){this.disconnect(),this.closeCaptureStream()}}e.concatStream=e=>{let t=[];return e.forEach(e=>{t=[...t,...e.getTracks()]}),new MediaStream(t)},e.default=C,e.filterStream=r,e.getMediaStream=n,e.getRtcPeerTracks=s,e.getUseAbleDevices=t,e.streamToRecord=(e,t={audioBitsPerSecond:128e3,videoBitsPerSecond:25e5,mimeType:"video/webm"})=>{const s=t.mimeType?t.mimeType.split("/"):["webm"];let i=(new Date).getTime().toString();const n=MediaRecorder.isTypeSupported(t.mimeType||"");if(!n)throw new Error(t.mimeType+"类型不支持");const r=new MediaRecorder(e,t);r.addEventListener("dataavailable",e=>{{e=e.data;var t=i+"."+s[(null===s||void 0===s?void 0:s.length)-1];e=URL.createObjectURL(e);const n=document.createElement("a");return n.href=e,n.target="_blank",n.style.display="none",document.body.appendChild(n),n.download=t,n.click(),URL.revokeObjectURL(e),void document.body.removeChild(n)}});const o=()=>{n&&r.stop()};return{start:()=>{n&&r.start()},pause:()=>{n&&r.pause()},save:e=>{n&&(i=e||(new Date).getTime().toString(),o())},stop:o,resume:()=>{n&&r.resume()}}},e.useWetRTC=function(e){const{connectionConfig:s,name:i,isLisenByts:t}=e,[d,l]=b.useState(0),r=b.useRef(""),o=b.useRef(e.senderSdp),v=b.useRef(e.senderIce),c=b.useRef(e.onError),a=(o.current=e.senderSdp,v.current=e.senderIce,c.current=e.onError,b.useRef(null)),u=b.useRef(null),[p,m]=b.useState({audioinput:!1,audiooutput:!1,videoinput:!1}),f=b.useRef({audioinput:!1,audiooutput:!1,videoinput:!1}),[n,y]=b.useState("new");return b.useEffect(()=>{a.current=new C(s&&(null===s||void 0===s?void 0:s.constraints)),a.current.getUseAbleDevices().then(e=>{const t={audioinput:!0,audiooutput:!0,videoinput:!0};if(e){const n=e.map(e=>e.kind);t.audioinput=n.includes("audioinput"),t.audiooutput=n.includes("audiooutput"),t.videoinput=n.includes("videoinput"),f.current=Object.assign({},t)}m(()=>t)})},[]),b.useEffect(()=>{var e;"connected"===n&&t&&null!==(e=u.current)&&void 0!==e&&e.addListenByts(e=>{l(e)})},[n,t]),{connect:b.useCallback((t="sendrecv",n)=>g(this,void 0,void 0,function*(){var e;i?r.current="object"==typeof i?i.current:i:r.current=r.current||h.v4(),a.current&&r.current&&(u.current=a.current.createConnectOne({uuid:r.current+"",transDirect:t,iceCb:v.current,configuration:s&&s.configuration}),(e=yield u.current.connect(n,e=>{y(()=>e)}))?o.current(e):(console.error("sdp获取失败,连接错误"),c.current&&c.current({code:"error",message:"sdp获取失败,连接错误"})))}),[i&&"object"==typeof i?i.current:i]),disconnect:()=>{var e;null!==(e=a.current)&&void 0!==e&&e.close()},play:(e,t,n)=>{"local"===e?null!==(e=a.current)&&void 0!==e&&e.playLocalStream(t,n):u.current&&u.current.play&&u.current.play(t,n)},answerAction:e=>{var t;null!==(t=u.current)&&void 0!==t&&t.setRemoteSdp(e)},byts:d,connectState:n,useAblesState:p,useAbleRef:f}},Object.defineProperty(e,"__esModule",{value:!0})});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).index={},e.react)}(this,function(e,f){"use strict";function y(e,o,a,c){return new(a=a||Promise)(function(n,t){function r(e){try{s(c.next(e))}catch(e){t(e)}}function i(e){try{s(c.throw(e))}catch(e){t(e)}}function s(e){var t;e.done?n(e.value):((t=e.value)instanceof a?t:new a(function(e){e(t)})).then(r,i)}s((c=c.apply(e,o||[])).next())})}const r=()=>y(void 0,void 0,void 0,function*(){return navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?yield navigator.mediaDevices.enumerateDevices():(console.error("navigator.mediaDevices.enumerateDevices"),null)}),i=(e="display",r)=>{const i="display"===e?"getDisplayMedia":"getUserMedia";return n=>y(void 0,void 0,void 0,function*(){let e=null;if(navigator.mediaDevices[i]){var t=Object.assign({video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,enableBackground:!1,suppressLocalAudioPlayback:!0}},n);try{e=yield navigator.mediaDevices[i](t)}catch(e){r&&r({name:e.name||"Error",message:e.message||"内部错误"})}}else r&&r({name:"CompatibleError",message:"不支持navigator.mediaDevices"});return e})},n=e=>{e&&e.getTracks().forEach(e=>{e.stop()})};const s=(e,t)=>{let n=[];return e.forEach(e=>{n=[...n,...e.getTracks().filter(e=>t?e.kind===t:e)]}),new MediaStream(n)},o=(e,t)=>{const n={receivers(){const t=[];return e.getReceivers().forEach(e=>{e.track&&t.push(e.track)}),t},senders(){const t=[];return e.getSenders().forEach(e=>{e.track&&t.push(e.track)}),t}};return t?n[t]():[...n.receivers(),...n.senders()]};const t={transDirect:"sendrecv",configuration:{iceServers:[{urls:"stun:stun.l.google.com:19302"}]},constraints:{video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,suppressLocalAudioPlayback:!0}}};class g{constructor(e){this.state="new",this.isUseAbles={audiooutput:!1,audioinput:!1,videoinput:!1},this.streamControl={close:e=>{const t={remote:()=>{n(this.streamControl.remoteStreams),this.streamControl.remoteStreams=null},local:()=>{n(this.streamControl.localStreams),this.streamControl.localStreams=null}};e?t[e]():(t.local(),t.remote())}},this.runByt={time:null,close:()=>{this.runByt.time&&clearInterval(this.runByt.time)},run:()=>{const i=this.EventMap.get("byts");let s=null;i&&0<i.length&&(null!==i&&void 0!==i&&i.forEach(e=>{e(0)}),this.runByt.time=setInterval(()=>{var e;null!==(e=this.RTCPeerIns)&&void 0!==e&&e.getStats().then(e=>{const t={bytesReceived:0};if(e.forEach(e=>{"transport"===e.type&&(t.bytesReceived+=e.bytesReceived)}),s){const n=s.bytesReceived,r=t.bytesReceived;null!==i&&void 0!==i&&i.forEach(e=>{e(Number(((r-n)/1024).toFixed(2)))}),s=Object.assign({},t)}else s=Object.assign({},t)})},1e3))}},this.EventMap=new Map([]),this.RTCPeerIns=null,this.removeListenFn=()=>{},this.WetOption=Object.assign({},t),this.WetOption=Object.assign(Object.assign({},this.WetOption),e)}runError(t){const e=this.EventMap.get("error");null!==e&&void 0!==e&&e.forEach(e=>{e(t)})}getUseAbleDevices(){return y(this,void 0,void 0,function*(){return yield r()})}addEventListener(e,t){const n=this.EventMap.get(e);n?n.find(e=>e===t)||(n.push(t),this.EventMap.set(e,n)):this.EventMap.set(e,[t])}removeEventListener(e,t){const n=this.EventMap.get(e);var r;n&&(r=n.filter(e=>e!==t),this.EventMap.set(e,r))}captureStream(){return y(this,void 0,void 0,function*(){const e=yield r();if(e){const n=e.map(e=>e.kind);this.isUseAbles.audioinput=n.includes("audioinput"),this.isUseAbles.videoinput=n.includes("videoinput"),this.isUseAbles.audiooutput=n.includes("audiooutput")}else this.isUseAbles.audioinput=!0,this.isUseAbles.videoinput=!0,this.isUseAbles.audiooutput=!0;var t;return this.isUseAbles.audioinput||this.isUseAbles.videoinput?((t=yield i("user",e=>{this.runError(e)})({video:!!this.isUseAbles.videoinput&&this.WetOption.constraints.video,audio:!!this.isUseAbles.audioinput&&this.WetOption.constraints.audio}))&&(this.streamControl.localStreams=t),t):(this.runError({name:"StreamError",message:"音频输入设备,视频输入设备均不可用"}),null)})}connect(c){var d;return y(this,void 0,void 0,function*(){if(["sendrecv","sendonly"].includes(this.WetOption.transDirect)&&(!this.streamControl.localStreams&&!(yield this.captureStream())))return null;let n="new",r=this;Object.defineProperty(this,"state",{get(){return n},set(e){"connected"===(n=e)?r.runByt.run():["disconnected","closed","failed"].includes(e)&&r.runByt.close();const t=r.EventMap.get("state");null!==t&&void 0!==t&&t.forEach(e=>{e(n)})}});var e,t,i;if(this.state="new",this.RTCPeerIns=new RTCPeerConnection(this.WetOption.configuration),this.removeListenFn=(e=this.RTCPeerIns,t={track:e=>{e.streams&&e.streams[0]&&(this.streamControl.remoteStreams=e.streams[0])},icecandidate:t=>{if(t.candidate){const e=r.EventMap.get("ice");null!==e&&void 0!==e&&e.forEach(e=>{e(t.candidate)})}},connectionstatechange:e=>{e=e.target;this.state=e.connectionState}},e.addEventListener("track",t.track),e.addEventListener("icecandidate",t.icecandidate),e.addEventListener("connectionstatechange",t.connectionstatechange),()=>{e.removeEventListener("track",t.track),e.removeEventListener("icecandidate",t.icecandidate),e.removeEventListener("connectionstatechange",t.connectionstatechange)}),["sendrecv","sendonly"].includes(this.WetOption.transDirect)){const s=null===(d=this.streamControl)||void 0===d?void 0:d.localStreams;null!==s&&void 0!==s&&s.getTracks().forEach(e=>{var t;null!==(t=this.RTCPeerIns)&&void 0!==t&&t.addTrack(e,s)})}else try{this.RTCPeerIns.addTransceiver("video",{direction:"recvonly"}),this.RTCPeerIns.addTransceiver("audio",{direction:"recvonly"})}catch(e){const o=document.createElement("canvas"),a=o.captureStream();null!==a&&void 0!==a&&a.getTracks().forEach(e=>{var t;null!==(t=this.RTCPeerIns)&&void 0!==t&&t.addTrack(e,a)})}return c?(yield this.setRemoteSdp(c),i=yield this.RTCPeerIns.createAnswer(),yield this.RTCPeerIns.setLocalDescription(i),i):(i=yield this.RTCPeerIns.createOffer(),yield this.RTCPeerIns.setLocalDescription(i),i)})}closePeerInsTracks(){if(this.RTCPeerIns){const e={recvonly:()=>o(this.RTCPeerIns,"receivers"),sendonly:()=>o(this.RTCPeerIns,"senders"),sendrecv:()=>o(this.RTCPeerIns)},t=e[this.WetOption.transDirect]();t.forEach(e=>{null!=e&&e.stop()})}}disconnect(){this.state="closed",this.removeListenFn(),this.closePeerInsTracks()}close(){this.disconnect(),this.streamControl.close()}setRemoteSdp(e){var t;return y(this,void 0,void 0,function*(){if(!e)return this.runError({name:"OperationError",message:"缺失sdp信息"}),void(this.state="failed");try{yield null===(t=this.RTCPeerIns)||void 0===t?void 0:t.setRemoteDescription(e)}catch(e){this.state="failed",this.runError({name:e.name||"Error",message:e.message||"内部错误"})}})}addIceCandidate(e){var t;return y(this,void 0,void 0,function*(){if(!e)return this.runError({name:"OperationError",message:"缺失IceSdp信息"}),void(this.state="failed");try{yield null===(t=this.RTCPeerIns)||void 0===t?void 0:t.addIceCandidate(e)}catch(e){this.state="failed",this.runError({name:e.name||"Error",message:e.message||"内部错误"})}})}playRemote(t,n){return y(this,void 0,void 0,function*(){var e;this.RTCPeerIns&&(e=this.RTCPeerIns.getReceivers().map(e=>e.track),e=new MediaStream(e),null!=t&&t.setAttribute("autoplay",""),null!=t&&t.setAttribute("playsinline",""),t&&(t.srcObject=s([e],n)))})}playLocal(t,n){return y(this,void 0,void 0,function*(){this.streamControl.localStreams||(yield this.captureStream());var e=this.streamControl.localStreams;null!=t&&t.setAttribute("autoplay",""),null!=t&&t.setAttribute("playsinline",""),t&&(t.srcObject=s([e],n))})}}let a;const d=new Uint8Array(16);const c=[];for(let e=0;e<256;++e)c.push((e+256).toString(16).slice(1));var u={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function b(e,t,n){if(u.randomUUID&&!t&&!e)return u.randomUUID();const r=(e=e||{}).random||(e.rng||function(){if(!a&&!(a="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return a(d)})();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(let e=0;e<16;++e)t[n+e]=r[e];return t}return e=r,i=0,(c[e[i+0]]+c[e[i+1]]+c[e[i+2]]+c[e[i+3]]+"-"+c[e[i+4]]+c[e[i+5]]+"-"+c[e[i+6]]+c[e[i+7]]+"-"+c[e[i+8]]+c[e[i+9]]+"-"+c[e[i+10]]+c[e[i+11]]+c[e[i+12]]+c[e[i+13]]+c[e[i+14]]+c[e[i+15]]).toLowerCase();var i}e.concatStream=e=>{let t=[];return e.forEach(e=>{t=[...t,...e.getTracks()]}),new MediaStream(t)},e.default=g,e.filterStream=s,e.getMediaStream=i,e.getRtcPeerTracks=o,e.getUseAbleDevices=r,e.stopStreamTrack=n,e.streamToRecord=(e,t={audioBitsPerSecond:128e3,videoBitsPerSecond:25e5,mimeType:"video/webm"})=>{const r=t.mimeType?t.mimeType.split("/"):["webm"];let i=(new Date).getTime().toString();const n=MediaRecorder.isTypeSupported(t.mimeType||"");if(!n)throw new Error(t.mimeType+"类型不支持");const s=new MediaRecorder(e,t);s.addEventListener("dataavailable",e=>{{e=e.data;var t=i+"."+r[(null===r||void 0===r?void 0:r.length)-1];e=URL.createObjectURL(e);const n=document.createElement("a");return n.href=e,n.target="_blank",n.style.display="none",document.body.appendChild(n),n.download=t,n.click(),URL.revokeObjectURL(e),void document.body.removeChild(n)}});const o=()=>{n&&s.stop()};return{start:()=>{n&&s.start()},pause:()=>{n&&s.pause()},save:e=>{n&&(i=e||(new Date).getTime().toString(),o())},stop:o,resume:()=>{n&&s.resume()}}},e.useWetRTC=function(e){const{connectionConfig:t,name:n,isLisenByts:r}=e,[u,l]=f.useState(0),i=f.useRef(""),s=f.useRef(e.senderSdp),o=f.useRef(e.senderIce),a=f.useRef(e.onError),c=(s.current=e.senderSdp,o.current=e.senderIce,a.current=e.onError,f.useRef(null)),[v,p]=f.useState({audioinput:!1,audiooutput:!1,videoinput:!1}),h=f.useRef({audioinput:!1,audiooutput:!1,videoinput:!1}),[d,m]=f.useState("new");return f.useEffect(()=>{c.current=new g(t),c.current.addEventListener("error",e=>{a.current&&a.current(e)}),c.current.addEventListener("state",e=>{m(e)}),c.current.addEventListener("ice",e=>{o.current&&o.current(e)}),c.current.getUseAbleDevices().then(e=>{const t={audioinput:!0,audiooutput:!0,videoinput:!0};if(e){const n=e.map(e=>e.kind);t.audioinput=n.includes("audioinput"),t.audiooutput=n.includes("audiooutput"),t.videoinput=n.includes("videoinput"),h.current=Object.assign({},t)}p(()=>t)})},[]),f.useEffect(()=>{var e;"connected"===d&&r&&null!==(e=c.current)&&void 0!==e&&e.addEventListener("byts",e=>{l(e)})},[d,r]),{connect:f.useCallback(t=>y(this,void 0,void 0,function*(){var e;n?i.current="object"==typeof n?n.current:n:i.current=i.current||b(),c.current&&i.current&&((e=yield c.current.connect(t))&&s.current(e))}),[n&&"object"==typeof n?n.current:n]),disconnect:()=>{var e;null!==(e=c.current)&&void 0!==e&&e.close()},play:(e,t,n)=>{"local"===e?null!==(e=c.current)&&void 0!==e&&e.playLocal(t,n):null!==(e=c.current)&&void 0!==e&&e.playRemote(t,n)},answerAction:e=>{var t;null!==(t=c.current)&&void 0!==t&&t.setRemoteSdp(e)},byts:u,connectState:d,useAblesState:v}},Object.defineProperty(e,"__esModule",{value:!0})});
|
package/lib/libs/index.d.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* 获取可用设备
|
|
3
3
|
* @returns Promise
|
|
4
4
|
*/
|
|
5
|
+
export interface ErrorMsgType {
|
|
6
|
+
name: string;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
5
9
|
export declare const getUseAbleDevices: () => Promise<MediaDeviceInfo[] | null>;
|
|
6
10
|
/**
|
|
7
11
|
* 获取支持的约束
|
|
@@ -11,10 +15,11 @@ export declare const getSupportedConsitains: () => MediaTrackSupportedConstraint
|
|
|
11
15
|
* 选择分享流(本地视频流) / 捕获用户许可的输入信号流
|
|
12
16
|
* @returns Promise
|
|
13
17
|
*/
|
|
14
|
-
export declare const getMediaStream: (type?: 'user' | 'display') => (constraints?: MediaStreamConstraints | undefined) => Promise<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
export declare const getMediaStream: (type?: 'user' | 'display', onError?: ((params: ErrorMsgType) => void) | undefined) => (constraints?: MediaStreamConstraints | undefined) => Promise<MediaStream | null>;
|
|
19
|
+
/**
|
|
20
|
+
* 关闭流和轨道追踪
|
|
21
|
+
*/
|
|
22
|
+
export declare const stopStreamTrack: (streams?: MediaStream | null | undefined) => void;
|
|
18
23
|
/**
|
|
19
24
|
* 将多个stream 整合为一个stream
|
|
20
25
|
* @param options
|
|
@@ -29,3 +34,8 @@ export declare const concatStream: (options: MediaStream[]) => MediaStream;
|
|
|
29
34
|
*/
|
|
30
35
|
export declare const filterStream: (options: MediaStream[], type?: "audio" | "video" | undefined) => MediaStream;
|
|
31
36
|
export declare const getRtcPeerTracks: (peerConnection: RTCPeerConnection, type?: "receivers" | "senders" | undefined) => MediaStreamTrack[];
|
|
37
|
+
export declare const listenerEvent: (RTCPeerIns: RTCPeerConnection, option: {
|
|
38
|
+
track: (e: RTCTrackEvent) => void;
|
|
39
|
+
icecandidate: (e: RTCPeerConnectionIceEvent) => void;
|
|
40
|
+
connectionstatechange: (e: Event) => void;
|
|
41
|
+
}) => () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wetspace/wetrtc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "wetrtc",
|
|
5
5
|
"author": "tangjie <981955667@qq.com>",
|
|
6
6
|
"license": "ISC",
|
|
@@ -37,10 +37,7 @@
|
|
|
37
37
|
"build": "rm -fr lib && rm -fr es && set NODE_ENV=production&& rollup -c rollup.config.js"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@types/uuid": "^8.3.4",
|
|
41
40
|
"rollup": "^2.67.3"
|
|
42
41
|
},
|
|
43
|
-
"dependencies": {
|
|
44
|
-
"uuid": "^9.0.0"
|
|
45
|
-
}
|
|
42
|
+
"dependencies": {}
|
|
46
43
|
}
|