ball_admin/src/util/webRtc.ts

188 lines
6.3 KiB
TypeScript

import Config from "./config";
import SocketService from "./socket";
class WebRtc {
private mediaStream: MediaStream | Blob | null = null;
private pee: RTCPeerConnection | null = null;
private ws: WebSocket | null = null;
private video: HTMLVideoElement | null = null;
private userToId: string = "";
open = () => {
this.ws?.send(JSON.stringify({
type: "new", "data": {
"name": "admin",
"id": "31283192",
"user_agent": "flutter-webrtc/js"
}
}))
}
async init() {
this.createOffer()
// this.ws.onmessage = function (evt) {
// let msg = JSON.parse(evt.data)
// if (!msg) {
// return console.log('failed to parse msg')
// }
// switch (msg.type) {
// case 'offer':
// let offer = msg.data.description
// that.pee?.setRemoteDescription(offer)
// that.pee?.createAnswer().then(answer => {
// that.pee?.setLocalDescription(answer)
// that.ws?.send(JSON.stringify({
// type: 'answer', data: {
// 'to': msg.data.from,
// 'from': "31283192",
// 'description': { 'sdp': answer.sdp, 'type': answer.type },
// 'session_id': msg.data.from + "-31283192",
// }
// }))
// })
// return
// case 'candidate':
// let candidate = msg.data.candidate
// if (!candidate) {
// return console.log('failed to parse candidate')
// }
// that.pee?.addIceCandidate(candidate)
// break;
// case "answer":
// that.pee?.setRemoteDescription(msg.data.description)
// break;
// case "bye":
// that.pee?.close()
// that.close()
// break;
// }
// }
}
async createOffer() {
var url =
'https://rw.quwanya.cn/api/turn?service=turn&username=flutter-webrtc';
fetch(url)
.then(response => response.json())
.then(data => {
const configuration = {
iceServers: [
{
urls: data.uris[0],
"username": data.username,
"credential": data.password
},
]
}
this.gets(configuration)
})
}
// 设置远程offer
setRemoteDes(answer) {
this.pee?.setRemoteDescription(answer)
}
addCandidate(candidate) {
if (!candidate) {
return console.log('failed to parse candidate')
}
this.pee?.addIceCandidate(candidate)
}
async gets(configuration) {
const peerConnection = new RTCPeerConnection(configuration);
this.pee = peerConnection
// 获取远方流添加到页面播放
peerConnection.ontrack = event => {
const remoteVideo = document.querySelector('#remoteVideo') as HTMLVideoElement;
remoteVideo.autoplay = true
remoteVideo.controls = true
remoteVideo.srcObject = event.streams[0];
console.log(event);
event.track.onmute = function () {
remoteVideo.play()
}
};
await this.getMedia(peerConnection)
peerConnection.onicecandidate = e => {
if (!e.candidate) {
return
}
this.ws?.send(JSON.stringify({ type: 'candidate', data: e }))
}
}
sendOffer(userId) {
let that = this;
that.userToId = userId;
that.video = document.getElementById('rtcVideo') as HTMLVideoElement;
if (that.pee?.connectionState === "closed") {
that.createOffer()
}
that.pee?.createOffer().then(function (offer) {
that.pee?.setLocalDescription(offer);
that.ws?.send(JSON.stringify({
type: "offer", "data": {
"to": userId,
"from": "admin",
"description": offer,
"media": "video",
"session_id": userId + "-admin",
}
}))
}).catch(function (error) {
// 错误处理
console.error(error);
});
}
addIceCandidate(candidate) {
this.pee?.addIceCandidate(candidate)
}
async getMedia(pee: RTCPeerConnection) {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
this.mediaStream = stream;
stream.getTracks().forEach(track => pee.addTrack(track, stream))
} catch (error) {
console.log(error);
}
}
calls(userId) {
this.sendOffer("admin123")
if (this.video) {
this.video.srcObject = this.mediaStream;
this.video.autoplay = true;
}
}
// 发送本地offer
setIceOffer(offer, toid) {
this.pee?.setRemoteDescription(offer)
this.pee?.createAnswer().then(answer => {
this.pee?.setLocalDescription(answer)
SocketService.getInstance().send({
type: 'answer', data: {
'to': toid,
'from': "admin",
'description': { 'sdp': answer.sdp, 'type': answer.type },
'session_id': toid + "-admin",
}
})
})
}
close() {
this.video?.pause();
this.pee?.close();
this.ws?.send(JSON.stringify({
"type": "bye", "data": {
"session_id": this.userToId + "admin",
"to": this.userToId
}
}
));
(this.mediaStream as MediaStream)?.getTracks().forEach(track => track.stop());
this.ws?.close()
}
}
export const webRTC = new WebRtc()