pixelstream-cn
Version:
基于虚幻引擎的像素流平台
169 lines (160 loc) • 5.54 kB
JavaScript
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((_) => {
})
}
}