index.js 3.2 KB

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