index.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // wrt + socket + contrl
  2. const io = require("socket.io-client")
  3. const PWM = require('./lib/Pwm')
  4. const { PeerConnection, Video } = require('node-datachannel');
  5. const { createSocket } = require('dgram')
  6. const { spawn } = require('child_process')
  7. // const url = 'ws://10.10.3.196:7896'
  8. const url = process.argv.splice(2);
  9. class CarServer {
  10. constructor() {
  11. this.Peer = null
  12. this.track = null
  13. this.child = null
  14. this.udp = null
  15. this.socket = io(url, { auth: { roomID: "feiCar", name: 'car' } });
  16. this.socket.on('connect', this.connected.bind(this))
  17. this.socket.on('msg', this.onMsg.bind(this))
  18. this.socket.on('leaved', this.onLeved.bind(this))
  19. this.socket.on('joined', this.startVideo.bind(this))
  20. this.socket.on('disconnect',this.onLeved.bind(this))
  21. }
  22. // socket 连接
  23. connected() {
  24. console.log('connected');
  25. this.Peer = new PeerConnection("Peer1", { iceServers: [] });
  26. // 发送offer
  27. this.Peer.onGatheringStateChange(state => {
  28. console.log('GatheringState: ', state);
  29. if (state === 'complete') {
  30. const offer = this.Peer.localDescription();
  31. this.socket.emit("msg", offer);
  32. }
  33. })
  34. }
  35. // 用户信息
  36. onMsg(data) {
  37. try {
  38. if (data.type == 'answer') {
  39. this.Peer.setRemoteDescription(data.sdp, data.type);
  40. } else if (data.type === 'startRTC') {
  41. this.startVideo()
  42. } if (data.type === 'conctrl') {
  43. const state = this.Peer.iceConnectionState;
  44. if(state === 'connected') PWM.changPWM(data.conctrl);
  45. }
  46. } catch (error) {
  47. console.log(error);
  48. throw error
  49. }
  50. }
  51. // 用户离开
  52. onLeved() {
  53. if (this.child) this.child.kill()
  54. if (this.udp) this.udp.close()
  55. PWM.stop()
  56. this.child = null
  57. this.udp = null
  58. process.exit(1)
  59. }
  60. // 开始视频
  61. startVideo() {
  62. try {
  63. if (this.child) this.child.kill()
  64. if (this.udp) this.udp.close()
  65. // test video
  66. const video = new Video('video', 'SendOnly')
  67. video.addH264Codec(96)
  68. video.addSSRC(42, "video-send")
  69. this.track = this.Peer.addTrack(video)
  70. this.Peer.setLocalDescription()
  71. // UDP server
  72. const port = 7788
  73. this.udp = createSocket("udp4")
  74. this.udp.bind(port)
  75. // video push
  76. const args = [
  77. "libcamerasrc",
  78. "video/x-raw,width=960,height=720",
  79. "videoconvert",
  80. "queue",
  81. "x264enc tune=zerolatency bitrate=1000 key-int-max=30 speed-preset=1",
  82. "video/x-h264, profile=constrained-baseline",
  83. "rtph264pay pt=96 mtu=1200 ssrc=42",
  84. `udpsink host=127.0.0.1 port=${port}`,
  85. ].join(" ! ").split(" ")
  86. this.child = spawn("gst-launch-1.0", args)
  87. // listen UDP
  88. this.udp.on("message", (data) => {
  89. if (!this.track.isOpen()) return
  90. this.track.sendMessageBinary(data)
  91. });
  92. } catch (error) {
  93. console.log(error);
  94. throw error
  95. }
  96. }
  97. }
  98. new CarServer(url[0])