UNPKG

pixelstream-cn

Version:

基于虚幻引擎的像素流平台

169 lines (160 loc) 5.54 kB
const ToClientMessageType = { QualityControlOwnership: 0, Response: 1, Command: 2, FreezeFrame: 3, UnfreezeFrame: 4, VideoEncoderAvgQP: 5, } export default class Webrtc{ constructor(){ this.audio=null; this.stream=null; } //设置ice处理函数 setIceCandidateHandel(fn){ this.iceCandidateHandel=fn; return this; } //设置媒体流处理函数 setStreamHandel(fn){ this.streamHandel=fn; this.streamHandel(this.stream); return this; } setAudioHandel(fn){ this.audioHandel=fn; this.audioHandel(this.audio); return this; } //设置数据通道打开处理函数 setDataChannelOpenHandel(fn){ this.dataChannelOpenHandel =fn; return this; } //设置数据通道关闭处理函数 setDataChannelCloseHandel(fn){ this.dataChannelCloseHandel =fn; return this; } //設置速率事件動作 setSpeedHandel(fn){ this.speedHandel=fn; return this; } //发送动作 send(action){ // if(this.dcClient && this.dcClient.readyState == 'open'){ this.sendBuffer(action.buffer); if(action.promise){ return action.promise; } // } return this; } sendBuffer(buffer){ this.dcClient.send(buffer); return this; } message(message){ this.dataChannelMessageHandel = ((type,response)=>{ switch(type){ case ToClientMessageType.QualityControlOwnership: message.qualityControlOwnershipHandel(response); break; case ToClientMessageType.Response: try { let result=JSON.parse(response); if(result.message){ callback.runFunction(result.message,result); } } catch (error) { console.warn("返回的数据非json字符串"); } message.responseHandel(response); break; case ToClientMessageType.Command: message.commandHandel(response); break; case ToClientMessageType.FreezeFrame: message.freezeFrameHandel(response); break; case ToClientMessageType.UnfreezeFrame: message.unfreezeFrameHandel(response); break; case ToClientMessageType.VideoEncoderAvgQP: message.videoEncoderAvgQPHandel(response); break; } }); return this; } async init(config){ let _this = this; this.pc = new RTCPeerConnection(config); this.pc.addEventListener('icecandidate', (e) => { if (e.candidate && e.candidate.candidate) { if(_this.iceCandidateHandel){ _this.iceCandidateHandel(e.candidate); } } }) this.pc.addEventListener('track', (e) => { if(e.track.kind == "audio"){ _this.audio=e.streams[0]; if(_this.audioHandel){ _this.audioHandel(_this.audio); } return; }else if(e.receiver.track.kind=="video"){ _this.stream=e.streams[0]; if(_this.streamHandel){ _this.streamHandel(_this.stream); } } }) this.dcClient = this.pc.createDataChannel('cirrus', { ordered: true }) this.dcClient.onopen = function (e) { _this.dataChannelOpenHandel(e); } this.dcClient.onclose = function (e) { _this.dataChannelCloseHandel(e); } this.dcClient.onmessage = function (e) { let data = e.data var view = new Uint8Array(data) let response = new TextDecoder('utf-16').decode(data.slice(1)); if(_this.dataChannelMessageHandel){ _this.dataChannelMessageHandel(view[0],response); } if(view[0]==5){ if(_this.speedHandel){ _this.speedHandel(response); } } } let offer = await this.getOffer(); return offer; } async getOffer() { let offer = await this.pc.createOffer({ offerToReceiveAudio: 1, // 1开启 0关闭 offerToReceiveVideo: 1, voiceActivityDetection: false }) //设置压缩率和立体声 offer.sdp = offer.sdp.replace('useinbandfec=1', 'maxaveragebitrate=510000;sprop-stereo=1;stereo=1;useinbandfec=1'); // offer.sdp = offer.sdp.replace(/(a=extmap-allow-mixed)\r\n/gm, ""); await this.pc.setLocalDescription(offer) return offer } setAnswer(answer){ var answerDesc = new RTCSessionDescription(answer) this.pc.setRemoteDescription(answerDesc) } setIceCandidate(candidate){ let rtcCandidate = new RTCIceCandidate(candidate) this.pc.addIceCandidate(rtcCandidate).then((_) => { }) } }