@wetspace/wetrtc 2.0.2 → 2.1.0

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/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # WetRTC
2
+
3
+ 本工具库是基于 WebRTC 的进一步封装,简化了其 WebRTC 中生涩的 API 的使用. 如果要考虑到兼容性,推荐引入`webrtc-adapter`这个适配库
4
+
5
+ 适配库的安装:
6
+
7
+ `npm install webrtc-adapter`
8
+
9
+ [适配库的使用文档地址](https://github.com/webrtchacks/adapter#readme)
10
+
11
+ 在 Electron 应用中是不需要使用适配库的,高版本的 Electron 对该部分支持非常到位
12
+
13
+ ## 1. 下载安装
14
+
15
+ `npm i @wetspace/wetrtc -S` 或 `yarn add @wetspace/wetrtc`
16
+
17
+ ## 2. 源码地址
18
+
19
+ [地址](https://gitee.com/wetspace/wetrtc)
20
+
21
+ ## 3. [Chrome 对 RTC 的测试指标显示地址](chrome://webrtc-internals/)
22
+
23
+ 该地址就是当你开启了 WebRTC 的音视频传输,它就能显示一些通讯中的基本信息,可用于某些功能的调试
24
+
25
+ ## 测试体验工具(音视频通讯)
26
+
27
+ 下载地址:[windows 版本]()
package/es/core/hook.d.ts CHANGED
@@ -1,24 +1,12 @@
1
1
  import { WetRTCPlayer } from './index';
2
2
  import type { WetCreateConnectOneOption, ConnectionState } from './index';
3
3
  import type { MutableRefObject } from 'react';
4
- interface UseWebRtcParams {
5
- name: string | number | MutableRefObject<string | number>;
6
- senderSdp: (sdp: RTCSessionDescriptionInit) => void;
7
- senderIce?: (ice: RTCIceCandidate) => void;
8
- connectionConfig?: {
9
- configuration?: RTCConfiguration;
10
- constraints?: MediaStreamConstraints;
11
- };
12
- onError?: (err: {
13
- code: string;
14
- message: string;
15
- }) => void;
16
- }
17
- declare const useWetRTC: (options: UseWebRtcParams) => {
18
- connect: (transDirect?: WetCreateConnectOneOption['transDirect'], sdp?: RTCSessionDescriptionInit | undefined) => Promise<void>;
4
+ interface UseWebRtcRetrun {
5
+ connect: (transDirect?: WetCreateConnectOneOption['transDirect'], sdp?: RTCSessionDescriptionInit) => Promise<void>;
19
6
  disconnect: () => void;
20
- play: (type: 'remote' | 'local', player?: WetRTCPlayer) => void;
7
+ play: (type: 'remote' | 'local', player: WetRTCPlayer, outType?: 'video' | 'audio') => void;
21
8
  answerAction: (sdp: RTCSessionDescriptionInit) => void;
9
+ byts: number;
22
10
  connectState: ConnectionState;
23
11
  useAblesState: {
24
12
  audioinput: boolean;
@@ -30,5 +18,23 @@ declare const useWetRTC: (options: UseWebRtcParams) => {
30
18
  audiooutput: boolean;
31
19
  videoinput: boolean;
32
20
  }>;
33
- };
21
+ }
22
+ interface UseWebRtcParams {
23
+ name?: string | number | MutableRefObject<string | number>;
24
+ senderSdp: (sdp: RTCSessionDescriptionInit) => void;
25
+ senderIce?: (ice: RTCIceCandidate) => void;
26
+ connectionConfig?: {
27
+ configuration?: RTCConfiguration;
28
+ constraints?: MediaStreamConstraints;
29
+ };
30
+ onError?: (err: {
31
+ code: string;
32
+ message: string;
33
+ }) => void;
34
+ isLisenByts?: boolean;
35
+ }
36
+ declare function useWetRTC(options: Omit<UseWebRtcParams, 'isLisenByts'> & {
37
+ isLisenByts: true;
38
+ }): UseWebRtcRetrun;
39
+ declare function useWetRTC(options: UseWebRtcParams): Omit<UseWebRtcRetrun, 'byts'>;
34
40
  export { useWetRTC };
@@ -7,13 +7,15 @@ export interface WetRTCConnectctItem {
7
7
  name: string;
8
8
  streams: MediaStream | null;
9
9
  transDirect: 'recvonly' | 'sendonly' | 'sendrecv';
10
+ closeBytsListen: (() => void) | null;
10
11
  }
11
12
  export interface WetRTCItemType {
12
13
  connect: (sdp?: RTCSessionDescriptionInit | undefined, stateChange?: ((state: ConnectionState) => void) | undefined) => Promise<RTCSessionDescriptionInit | null>;
13
- play?: (player?: WetRTCPlayer) => void;
14
+ play?: (player: WetRTCPlayer, type?: 'video' | 'audio') => void;
14
15
  setRemoteSdp: (sdp: RTCSessionDescriptionInit) => void;
15
16
  addIceCandidate: (sdp: RTCIceCandidate) => void;
16
17
  self: WetRTCConnectctItem;
18
+ addListenByts: (callFn: (...params: any) => any) => () => void;
17
19
  }
18
20
  export interface WetCreateConnectOneOption {
19
21
  configuration?: RTCConfiguration;
@@ -31,7 +33,7 @@ export declare class WetRTC {
31
33
  getUseAbleDevices(): Promise<MediaDeviceInfo[] | null>;
32
34
  private captureStream;
33
35
  closeCaptureStream(): void;
34
- playLocalStream(player: WetRTCPlayer): void;
36
+ playLocalStream(player: WetRTCPlayer, type?: 'video' | 'audio'): void;
35
37
  createConnectOne(option: Omit<WetCreateConnectOneOption, 'transDirect'> & {
36
38
  transDirect: 'sendonly';
37
39
  }): Omit<WetRTCItemType, 'play'>;
package/es/index.js CHANGED
@@ -1 +1 @@
1
- import{useRef,useState,useEffect,useCallback}from"react";function __awaiter(e,s,a,c){return new(a=a||Promise)(function(n,t){function r(e){try{o(c.next(e))}catch(e){t(e)}}function i(e){try{o(c.throw(e))}catch(e){t(e)}}function o(e){var t;e.done?n(e.value):((t=e.value)instanceof a?t:new a(function(e){e(t)})).then(r,i)}o((c=c.apply(e,s||[])).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 r="display"===e?"getDisplayMedia":"getUserMedia";return n=>__awaiter(void 0,void 0,void 0,function*(){if(navigator.mediaDevices[r]){var e=n||{video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,enableBackground:!1,suppressLocalAudioPlayback:!0}};const t=yield navigator.mediaDevices[r](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(){return e.getReceivers().map(e=>e.track)},senders(){return e.getSenders().map(e=>e.track)}};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 r=(new Date).getTime().toString();const i=MediaRecorder.isTypeSupported(t.mimeType||"");if(!i)throw new Error(t.mimeType+"类型不支持");const o=new MediaRecorder(e,t);o.addEventListener("dataavailable",e=>{SaveFileToLocal(e.data,r+"."+n[(null===n||void 0===n?void 0:n.length)-1])});const s=()=>{i&&o.stop()};return{start:()=>{i&&o.start()},pause:()=>{i&&o.pause()},save:e=>{i&&(r=e||(new Date).getTime().toString(),s())},stop:s,resume:()=>{i&&o.resume()}}};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)}const 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){this.streamControl&&e&&(e.setAttribute("autoPlay",""),e.setAttribute("playsInline",""),e.srcObject=this.streamControl.streams)}createConnectOne(e){let i="new";const{configuration:t,uuid:n,name:r,transDirect:d,iceCb:o}=e||{};e=t||DefaultConfiguration;const s=d||"sendrecv",a=n||v4(),c=new RTCPeerConnection(e),u={RTCPeerIns:c,state:"new",name:r||a,uuid:"",streams:null,transDirect:s};return{connect:(n,r)=>__awaiter(this,void 0,void 0,function*(){var e;if(["sendrecv","sendonly"].includes(s)&&!this.streamControl&&!(yield this.captureStream()))return null;if(u.uuid=a,this.rtcConnectMap.set(a,u),c.addEventListener("track",e=>{u.streams=e.streams[0]}),Object.defineProperty(u,"state",{get(){return i},set(e){i=e,r&&r(e)}}),c.addEventListener("icecandidate",e=>{e.candidate&&o&&o(e.candidate)}),c.addEventListener("connectionstatechange",e=>{e=e.target;u.state=e.connectionState}),["sendrecv","sendonly"].includes(s)){const t=null===(e=this.streamControl)||void 0===e?void 0:e.streams;null!==t&&void 0!==t&&t.getTracks().forEach(e=>{c.addTrack(e,t)})}else c.addTransceiver("video",{direction:"recvonly"}),c.addTransceiver("audio",{direction:"recvonly"});return n?(yield c.setRemoteDescription(n),e=yield c.createAnswer(),yield c.setLocalDescription(e),e):(e=yield c.createOffer(),yield c.setLocalDescription(e),e)}),play:"sendonly"===s?void 0:e=>{let t=0;if(u.uuid)if(u.streams)null!=e&&e.setAttribute("autoplay",""),null!=e&&e.setAttribute("playsinline",""),e&&(e.srcObject=u.streams);else{const n=setInterval(()=>{t+=100,u.streams&&(null!=e&&e.setAttribute("autoplay",""),null!=e&&e.setAttribute("playsinline",""),e&&(e.srcObject=u.streams),clearInterval(n)),1e4<=t&&(clearInterval(n),console.error("流媒体轨道错误,播放失败"))},100)}},self:u,setRemoteSdp:e=>{c.setRemoteDescription(e)},addIceCandidate:e=>{c.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);t.state="closed",this.closeStream(t),null!==t&&void 0!==t&&t.RTCPeerIns.close(),this.rtcConnectMap.delete(e)}}else this.rtcConnectMap.forEach(e=>{e.state="closed",this.closeStream(e),e.RTCPeerIns.close()}),this.rtcConnectMap.clear()}close(){this.disconnect(),this.closeCaptureStream()}}const useWetRTC=e=>{const{senderSdp:r,senderIce:i,connectionConfig:o,name:s,onError:a}=e,c=useRef(null),u=useRef(null),[t,l]=useState({audioinput:!1,audiooutput:!1,videoinput:!1}),d=useRef({audioinput:!1,audiooutput:!1,videoinput:!1}),[n,p]=useState("new");useEffect(()=>{c.current=new WetRTC(o&&(null===o||void 0===o?void 0:o.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"),d.current=Object.assign({},t)}l(()=>t)})},[]);return{connect:useCallback((t="sendrecv",n)=>__awaiter(void 0,void 0,void 0,function*(){var e="object"==typeof s?s.current:s;c.current&&e&&(u.current=c.current.createConnectOne({transDirect:t,iceCb:i,configuration:o&&o.configuration}),(e=yield u.current.connect(n,e=>{p(()=>e)}))?r(e):(console.error("sdp获取失败,连接错误"),a&&a({code:"error",message:"sdp获取失败,连接错误"})))}),["object"==typeof s?s.current:s]),disconnect:()=>{var e;null!==(e=c.current)&&void 0!==e&&e.close()},play:(e,t)=>{"local"===e?null!==(e=c.current)&&void 0!==e&&e.playLocalStream(t):u.current&&u.current.play&&u.current.play(t)},answerAction:e=>{var t;null!==(t=u.current)&&void 0!==t&&t.setRemoteSdp(e)},connectState:n,useAblesState:t,useAbleRef:d}};export{concatStream,WetRTC as default,filterStream,getMediaStream,getRtcPeerTracks,getUseAbleDevices,streamToRecord,useWetRTC};
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};
@@ -28,4 +28,4 @@ export declare const concatStream: (options: MediaStream[]) => MediaStream;
28
28
  * @returns
29
29
  */
30
30
  export declare const filterStream: (options: MediaStream[], type?: "audio" | "video" | undefined) => MediaStream;
31
- export declare const getRtcPeerTracks: (peerConnection: RTCPeerConnection, type?: "receivers" | "senders" | undefined) => (MediaStreamTrack | null)[];
31
+ export declare const getRtcPeerTracks: (peerConnection: RTCPeerConnection, type?: "receivers" | "senders" | undefined) => MediaStreamTrack[];
@@ -1,24 +1,12 @@
1
1
  import { WetRTCPlayer } from './index';
2
2
  import type { WetCreateConnectOneOption, ConnectionState } from './index';
3
3
  import type { MutableRefObject } from 'react';
4
- interface UseWebRtcParams {
5
- name: string | number | MutableRefObject<string | number>;
6
- senderSdp: (sdp: RTCSessionDescriptionInit) => void;
7
- senderIce?: (ice: RTCIceCandidate) => void;
8
- connectionConfig?: {
9
- configuration?: RTCConfiguration;
10
- constraints?: MediaStreamConstraints;
11
- };
12
- onError?: (err: {
13
- code: string;
14
- message: string;
15
- }) => void;
16
- }
17
- declare const useWetRTC: (options: UseWebRtcParams) => {
18
- connect: (transDirect?: WetCreateConnectOneOption['transDirect'], sdp?: RTCSessionDescriptionInit | undefined) => Promise<void>;
4
+ interface UseWebRtcRetrun {
5
+ connect: (transDirect?: WetCreateConnectOneOption['transDirect'], sdp?: RTCSessionDescriptionInit) => Promise<void>;
19
6
  disconnect: () => void;
20
- play: (type: 'remote' | 'local', player?: WetRTCPlayer) => void;
7
+ play: (type: 'remote' | 'local', player: WetRTCPlayer, outType?: 'video' | 'audio') => void;
21
8
  answerAction: (sdp: RTCSessionDescriptionInit) => void;
9
+ byts: number;
22
10
  connectState: ConnectionState;
23
11
  useAblesState: {
24
12
  audioinput: boolean;
@@ -30,5 +18,23 @@ declare const useWetRTC: (options: UseWebRtcParams) => {
30
18
  audiooutput: boolean;
31
19
  videoinput: boolean;
32
20
  }>;
33
- };
21
+ }
22
+ interface UseWebRtcParams {
23
+ name?: string | number | MutableRefObject<string | number>;
24
+ senderSdp: (sdp: RTCSessionDescriptionInit) => void;
25
+ senderIce?: (ice: RTCIceCandidate) => void;
26
+ connectionConfig?: {
27
+ configuration?: RTCConfiguration;
28
+ constraints?: MediaStreamConstraints;
29
+ };
30
+ onError?: (err: {
31
+ code: string;
32
+ message: string;
33
+ }) => void;
34
+ isLisenByts?: boolean;
35
+ }
36
+ declare function useWetRTC(options: Omit<UseWebRtcParams, 'isLisenByts'> & {
37
+ isLisenByts: true;
38
+ }): UseWebRtcRetrun;
39
+ declare function useWetRTC(options: UseWebRtcParams): Omit<UseWebRtcRetrun, 'byts'>;
34
40
  export { useWetRTC };
@@ -7,13 +7,15 @@ export interface WetRTCConnectctItem {
7
7
  name: string;
8
8
  streams: MediaStream | null;
9
9
  transDirect: 'recvonly' | 'sendonly' | 'sendrecv';
10
+ closeBytsListen: (() => void) | null;
10
11
  }
11
12
  export interface WetRTCItemType {
12
13
  connect: (sdp?: RTCSessionDescriptionInit | undefined, stateChange?: ((state: ConnectionState) => void) | undefined) => Promise<RTCSessionDescriptionInit | null>;
13
- play?: (player?: WetRTCPlayer) => void;
14
+ play?: (player: WetRTCPlayer, type?: 'video' | 'audio') => void;
14
15
  setRemoteSdp: (sdp: RTCSessionDescriptionInit) => void;
15
16
  addIceCandidate: (sdp: RTCIceCandidate) => void;
16
17
  self: WetRTCConnectctItem;
18
+ addListenByts: (callFn: (...params: any) => any) => () => void;
17
19
  }
18
20
  export interface WetCreateConnectOneOption {
19
21
  configuration?: RTCConfiguration;
@@ -31,7 +33,7 @@ export declare class WetRTC {
31
33
  getUseAbleDevices(): Promise<MediaDeviceInfo[] | null>;
32
34
  private captureStream;
33
35
  closeCaptureStream(): void;
34
- playLocalStream(player: WetRTCPlayer): void;
36
+ playLocalStream(player: WetRTCPlayer, type?: 'video' | 'audio'): void;
35
37
  createConnectOne(option: Omit<WetCreateConnectOneOption, 'transDirect'> & {
36
38
  transDirect: 'sendonly';
37
39
  }): Omit<WetRTCItemType, 'play'>;
package/lib/index.js CHANGED
@@ -1 +1 @@
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,v){"use strict";function m(e,o,a,c){return new(a=a||Promise)(function(n,t){function i(e){try{s(c.next(e))}catch(e){t(e)}}function r(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(i,r)}s((c=c.apply(e,o||[])).next())})}const t=()=>m(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 i="display"===e?"getDisplayMedia":"getUserMedia";return n=>m(void 0,void 0,void 0,function*(){if(navigator.mediaDevices[i]){var e=n||{video:!0,audio:{noiseSuppression:!0,echoCancellation:!0,enableBackground:!1,suppressLocalAudioPlayback:!0}};const t=yield navigator.mediaDevices[i](e);return{streams:t,close(){t.getTracks().forEach(e=>{e.stop()})}}}return console.error("不支持mediaDevices"),null})};const i=(e,t)=>{const n={receivers(){return e.getReceivers().map(e=>e.track)},senders(){return e.getSenders().map(e=>e.track)}};return t?n[t]():[...n.receivers(),...n.senders()]};let s;const c=new Uint8Array(16);const o=[];for(let e=0;e<256;++e)o.push((e+256).toString(16).slice(1));var a={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function l(e,t,n){if(a.randomUUID&&!t&&!e)return a.randomUUID();const i=(e=e||{}).random||(e.rng||function(){if(!s&&!(s="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 s(c)})();if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,t){n=n||0;for(let e=0;e<16;++e)t[n+e]=i[e];return t}return e=i,r=0,(o[e[r+0]]+o[e[r+1]]+o[e[r+2]]+o[e[r+3]]+"-"+o[e[r+4]]+o[e[r+5]]+"-"+o[e[r+6]]+o[e[r+7]]+"-"+o[e[r+8]]+o[e[r+9]]+"-"+o[e[r+10]]+o[e[r+11]]+o[e[r+12]]+o[e[r+13]]+o[e[r+14]]+o[e[r+15]]).toLowerCase();var r}const p={iceServers:[{urls:"stun:stun.l.google.com:19302"}]};class f{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 m(this,void 0,void 0,function*(){return yield t()})}captureStream(){return m(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){this.streamControl&&e&&(e.setAttribute("autoPlay",""),e.setAttribute("playsInline",""),e.srcObject=this.streamControl.streams)}createConnectOne(e){let r="new";const{configuration:t,uuid:n,name:i,transDirect:d,iceCb:s}=e||{};e=t||p;const o=d||"sendrecv",a=n||l(),c=new RTCPeerConnection(e),u={RTCPeerIns:c,state:"new",name:i||a,uuid:"",streams:null,transDirect:o};return{connect:(n,i)=>m(this,void 0,void 0,function*(){var e;if(["sendrecv","sendonly"].includes(o)&&!this.streamControl&&!(yield this.captureStream()))return null;if(u.uuid=a,this.rtcConnectMap.set(a,u),c.addEventListener("track",e=>{u.streams=e.streams[0]}),Object.defineProperty(u,"state",{get(){return r},set(e){r=e,i&&i(e)}}),c.addEventListener("icecandidate",e=>{e.candidate&&s&&s(e.candidate)}),c.addEventListener("connectionstatechange",e=>{e=e.target;u.state=e.connectionState}),["sendrecv","sendonly"].includes(o)){const t=null===(e=this.streamControl)||void 0===e?void 0:e.streams;null!==t&&void 0!==t&&t.getTracks().forEach(e=>{c.addTrack(e,t)})}else c.addTransceiver("video",{direction:"recvonly"}),c.addTransceiver("audio",{direction:"recvonly"});return n?(yield c.setRemoteDescription(n),e=yield c.createAnswer(),yield c.setLocalDescription(e),e):(e=yield c.createOffer(),yield c.setLocalDescription(e),e)}),play:"sendonly"===o?void 0:e=>{let t=0;if(u.uuid)if(u.streams)null!=e&&e.setAttribute("autoplay",""),null!=e&&e.setAttribute("playsinline",""),e&&(e.srcObject=u.streams);else{const n=setInterval(()=>{t+=100,u.streams&&(null!=e&&e.setAttribute("autoplay",""),null!=e&&e.setAttribute("playsinline",""),e&&(e.srcObject=u.streams),clearInterval(n)),1e4<=t&&(clearInterval(n),console.error("流媒体轨道错误,播放失败"))},100)}},self:u,setRemoteSdp:e=>{c.setRemoteDescription(e)},addIceCandidate:e=>{c.addIceCandidate(e)}}}getConnectById(e){return this.rtcConnectMap.get(e)}closeStream(e){if(e&&e.RTCPeerIns){const t={recvonly:()=>i(e.RTCPeerIns,"receivers"),sendonly:()=>i(e.RTCPeerIns,"senders"),sendrecv:()=>i(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);t.state="closed",this.closeStream(t),null!==t&&void 0!==t&&t.RTCPeerIns.close(),this.rtcConnectMap.delete(e)}}else this.rtcConnectMap.forEach(e=>{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=f,e.filterStream=(e,t)=>{let n=[];return e.forEach(e=>{n=[...n,...e.getTracks().filter(e=>t?e.kind===t:e)]}),new MediaStream(n)},e.getMediaStream=n,e.getRtcPeerTracks=i,e.getUseAbleDevices=t,e.streamToRecord=(e,t={audioBitsPerSecond:128e3,videoBitsPerSecond:25e5,mimeType:"video/webm"})=>{const i=t.mimeType?t.mimeType.split("/"):["webm"];let r=(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=r+"."+i[(null===i||void 0===i?void 0:i.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&&(r=e||(new Date).getTime().toString(),o())},stop:o,resume:()=>{n&&s.resume()}}},e.useWetRTC=e=>{const{senderSdp:i,senderIce:r,connectionConfig:s,name:o,onError:a}=e,c=v.useRef(null),u=v.useRef(null),[t,l]=v.useState({audioinput:!1,audiooutput:!1,videoinput:!1}),d=v.useRef({audioinput:!1,audiooutput:!1,videoinput:!1}),[n,p]=v.useState("new");v.useEffect(()=>{c.current=new f(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"),d.current=Object.assign({},t)}l(()=>t)})},[]);return{connect:v.useCallback((t="sendrecv",n)=>m(void 0,void 0,void 0,function*(){var e="object"==typeof o?o.current:o;c.current&&e&&(u.current=c.current.createConnectOne({transDirect:t,iceCb:r,configuration:s&&s.configuration}),(e=yield u.current.connect(n,e=>{p(()=>e)}))?i(e):(console.error("sdp获取失败,连接错误"),a&&a({code:"error",message:"sdp获取失败,连接错误"})))}),["object"==typeof o?o.current:o]),disconnect:()=>{var e;null!==(e=c.current)&&void 0!==e&&e.close()},play:(e,t)=>{"local"===e?null!==(e=c.current)&&void 0!==e&&e.playLocalStream(t):u.current&&u.current.play&&u.current.play(t)},answerAction:e=>{var t;null!==(t=u.current)&&void 0!==t&&t.setRemoteSdp(e)},connectState:n,useAblesState:t,useAbleRef:d}},Object.defineProperty(e,"__esModule",{value:!0})});
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})});
@@ -28,4 +28,4 @@ export declare const concatStream: (options: MediaStream[]) => MediaStream;
28
28
  * @returns
29
29
  */
30
30
  export declare const filterStream: (options: MediaStream[], type?: "audio" | "video" | undefined) => MediaStream;
31
- export declare const getRtcPeerTracks: (peerConnection: RTCPeerConnection, type?: "receivers" | "senders" | undefined) => (MediaStreamTrack | null)[];
31
+ export declare const getRtcPeerTracks: (peerConnection: RTCPeerConnection, type?: "receivers" | "senders" | undefined) => MediaStreamTrack[];
package/package.json CHANGED
@@ -1,38 +1,46 @@
1
1
  {
2
- "name": "@wetspace/wetrtc",
3
- "version": "2.0.2",
4
- "description": "wetrtc",
5
- "author": "tangjie <981955667@qq.com>",
6
- "license": "ISC",
7
- "main": "lib/index.js",
8
- "module": "es/index.js",
9
- "types": "es/index.d.ts",
10
- "sideEffects": [
11
- "./src/**/*.less",
12
- "./es/**/*.less",
13
- "./lib/**/*.less"
14
- ],
15
- "files": [
16
- "lib",
17
- "es"
18
- ],
19
- "publishConfig": {
20
- "registry": "https://registry.npmjs.org/",
21
- "access": "public"
22
- },
23
- "repository": {
24
- "type": "git",
25
- "url": "https://gitee.com/wetspace/wetrtc.git"
26
- },
27
- "scripts": {
28
- "start": "rollup -c -w",
29
- "build": "rm -fr lib && rm -fr es && set NODE_ENV=production&& rollup -c rollup.config.js"
30
- },
31
- "devDependencies": {
32
- "@types/uuid": "^8.3.4",
33
- "rollup": "^2.67.3"
34
- },
35
- "dependencies": {
36
- "uuid": "^9.0.0"
37
- }
2
+ "name": "@wetspace/wetrtc",
3
+ "version": "2.1.0",
4
+ "description": "wetrtc",
5
+ "author": "tangjie <981955667@qq.com>",
6
+ "license": "ISC",
7
+ "main": "lib/index.js",
8
+ "module": "es/index.js",
9
+ "types": "es/index.d.ts",
10
+ "keywords": [
11
+ "component",
12
+ "webrtc",
13
+ "hooks",
14
+ "react",
15
+ "wetrtc"
16
+ ],
17
+ "sideEffects": [
18
+ "./src/**/*.less",
19
+ "./es/**/*.less",
20
+ "./lib/**/*.less"
21
+ ],
22
+ "files": [
23
+ "lib",
24
+ "es"
25
+ ],
26
+ "publishConfig": {
27
+ "registry": "https://registry.npmjs.org/",
28
+ "access": "public"
29
+ },
30
+ "homepage": "https://wetspace.gitee.io/wetrtc/",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://gitee.com/wetspace/wetrtc.git"
34
+ },
35
+ "scripts": {
36
+ "start": "rollup -c -w",
37
+ "build": "rm -fr lib && rm -fr es && set NODE_ENV=production&& rollup -c rollup.config.js"
38
+ },
39
+ "devDependencies": {
40
+ "@types/uuid": "^8.3.4",
41
+ "rollup": "^2.67.3"
42
+ },
43
+ "dependencies": {
44
+ "uuid": "^9.0.0"
45
+ }
38
46
  }