|
|
@@ -2,36 +2,104 @@
|
|
|
// wrt + socket + contrl
|
|
|
const io = require("socket.io-client")
|
|
|
const PWM = require('./Pwm')
|
|
|
-const HOST = 'ws://10.10.3.196:7896'
|
|
|
+const { PeerConnection, Video, RtcpReceivingSession } = require('node-datachannel');
|
|
|
+const { createSocket } = require('dgram')
|
|
|
+const { spawn } = require('child_process')
|
|
|
+
|
|
|
+
|
|
|
class CarServer {
|
|
|
- constructor(HOST) {
|
|
|
- this.webRTC = null
|
|
|
- this.mediaStream = null
|
|
|
- this.videoSource = null
|
|
|
- this.socket = io(HOST, {
|
|
|
- auth: {
|
|
|
- roomID: "feiCar",
|
|
|
- name: 'car'
|
|
|
+ constructor() {
|
|
|
+ this.Peer = null
|
|
|
+ this.track = null
|
|
|
+ this.child = null
|
|
|
+ this.udp = null
|
|
|
+ this.socket = io('ws://10.10.3.196:7896', { auth: { roomID: "feiCar", name: 'car' } });
|
|
|
+ this.socket.on('connect', this.connected.bind(this))
|
|
|
+ this.socket.on('msg', this.onMsg.bind(this))
|
|
|
+ this.socket.on('leaved', this.onLeved.bind(this))
|
|
|
+ this.socket.on('joined', this.startVideo.bind(this))
|
|
|
+ }
|
|
|
+ // socket 连接
|
|
|
+ connected() {
|
|
|
+ console.log('connected');
|
|
|
+ this.Peer = new PeerConnection("Peer1", { iceServers: [] });
|
|
|
+ // 发送offer
|
|
|
+ this.Peer.onGatheringStateChange(state => {
|
|
|
+ console.log('GatheringState: ', state);
|
|
|
+ if (state === 'complete') {
|
|
|
+ const offer = this.Peer.localDescription();
|
|
|
+ this.socket.emit("msg", offer);
|
|
|
}
|
|
|
- });
|
|
|
- this.socket.on('connect', () => {
|
|
|
- console.log(`连接成功`)
|
|
|
- })
|
|
|
- this.socket.on('leaved', user => {
|
|
|
- console.log(`${user.name}离开${user.roomID}房间`)
|
|
|
- })
|
|
|
- this.socket.on('joined', user => {
|
|
|
- console.log(`${user.name}加入${user.roomID}房间`)
|
|
|
})
|
|
|
- this.socket.on('msg', data => {
|
|
|
- console.log('用户信息', data.type);
|
|
|
- if (data.type === 'conctrl') {
|
|
|
+ }
|
|
|
+
|
|
|
+ // 用户信息
|
|
|
+ onMsg(data) {
|
|
|
+ try {
|
|
|
+ if (data.type == 'answer') {
|
|
|
+ this.Peer.setRemoteDescription(data.sdp, data.type);
|
|
|
+ } else if (data.type === 'startRTC') {
|
|
|
+ this.startVideo()
|
|
|
+ } if (data.type === 'conctrl') {
|
|
|
PWM.changPWM(data.conctrl)
|
|
|
}
|
|
|
- })
|
|
|
- this.socket.on('connect_error', err => {
|
|
|
- console.log('连接错误', err)
|
|
|
- })
|
|
|
- }
|
|
|
+ } catch (error) {
|
|
|
+ console.log('msg error:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 用户离开
|
|
|
+ onLeved() {
|
|
|
+ if (this.child) this.child.kill()
|
|
|
+ if (this.udp) this.udp.close()
|
|
|
+ this.child = null
|
|
|
+ this.udp = null
|
|
|
+ process.exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开始视频
|
|
|
+ startVideo() {
|
|
|
+ try {
|
|
|
+ if (this.child) this.child.kill()
|
|
|
+ if (this.udp) this.udp.close()
|
|
|
+
|
|
|
+ // test video
|
|
|
+ const video = new Video('video', 'SendOnly')
|
|
|
+ video.addH264Codec(96)
|
|
|
+ video.addSSRC(42, "video-send")
|
|
|
+ this.track = this.Peer.addTrack(video)
|
|
|
+ this.Peer.setLocalDescription()
|
|
|
+
|
|
|
+ // UDP server
|
|
|
+ const port = 7788
|
|
|
+ this.udp = createSocket("udp4")
|
|
|
+ this.udp.bind(port)
|
|
|
+
|
|
|
+ // video push
|
|
|
+
|
|
|
+ const args = [
|
|
|
+ "libcamerasrc",
|
|
|
+ "video/x-raw,width=320,height=240",
|
|
|
+ "videoconvert",
|
|
|
+ "queue",
|
|
|
+ "x264enc tune=zerolatency bitrate=1000 key-int-max=30",
|
|
|
+ "video/x-h264, profile=constrained-baseline",
|
|
|
+ "rtph264pay pt=96 mtu=1200 ssrc=42",
|
|
|
+ `udpsink host=127.0.0.1 port=${port}`,
|
|
|
+ ].join(" ! ").split(" ")
|
|
|
+ this.child = spawn("gst-launch-1.0", args)
|
|
|
+
|
|
|
+ // listen UDP
|
|
|
+ this.udp.on("message", (data) => {
|
|
|
+ if (!this.track.isOpen()) return
|
|
|
+ console.log(data);
|
|
|
+ this.track.setMediaHandler(new RtcpReceivingSession())
|
|
|
+ this.track.sendMessageBinary(data)
|
|
|
+ });
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.log('startvideo:', error)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-new CarServer(HOST)
|
|
|
+new CarServer()
|