index.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // wrt + socket + contrl
  2. const io = require("socket.io-client")
  3. const RTCVideoSource = require('./lib/videoSource')
  4. const RTCAudioSource = require('./lib/audioSource')
  5. //const PWM = require('./lib/Pwm')
  6. const { RTCPeerConnection, MediaStream } = require("wrtc")
  7. const HOST = 'ws://10.10.3.196:7896'
  8. class CarServer {
  9. constructor(HOST) {
  10. this.webRTC = null
  11. this.mediaStream = null
  12. this.videoSource = null
  13. this.audioSource = null
  14. this.socket = io(HOST, {
  15. auth: {
  16. roomID: "feiCar",
  17. name: 'car'
  18. }
  19. });
  20. this.socket.on('connect', () => {
  21. this.connect()
  22. })
  23. this.socket.on('leaved', user => {
  24. console.log(`${user.name}离开${user.roomID}房间`)
  25. // 用户离开移除RTC
  26. this.destroyed()
  27. })
  28. this.socket.on('joined', user => {
  29. console.log(`${user.name}加入${user.roomID}房间`)
  30. // 发送offer
  31. this.createOffer()
  32. })
  33. this.socket.on('msg', data => {
  34. console.log('用户信息', data.type);
  35. this.msg(data)
  36. })
  37. this.socket.on('connect_error', err => {
  38. console.log('连接错误', err)
  39. this.destroyed()
  40. })
  41. }
  42. // 连接
  43. connect() {
  44. console.log('连接成功,开始初始化webrtc')
  45. // 初始化rtc
  46. this.webRTC = new RTCPeerConnection()
  47. // 初始化媒体源
  48. this.mediaStream = new MediaStream()
  49. this.videoSource = new RTCVideoSource()
  50. this.audioSource = new RTCAudioSource()
  51. // 加入媒体源
  52. const videoTrack = this.videoSource.createTrack()
  53. this.mediaStream.addTrack(videoTrack)
  54. this.webRTC.addTrack(videoTrack, this.mediaStream)
  55. // 加入音频源
  56. const audioTrack = this.audioSource.createTrack()
  57. this.mediaStream.addTrack(audioTrack)
  58. this.webRTC.addTrack(audioTrack, this.mediaStream)
  59. // 加入媒体
  60. this.videoSource.start()
  61. this.audioSource.start()
  62. // 监听ice
  63. this.webRTC.onicecandidate = event => {
  64. if (event.candidate) {
  65. // 发送ICE
  66. this.socket.emit('msg', {
  67. type: 'candidate',
  68. candidate: event.candidate
  69. })
  70. }
  71. }
  72. // 监听ice状态
  73. this.webRTC.oniceconnectionstatechange = () => {
  74. if (this.webRTC.iceConnectionState === 'failed' || this.webRTC.iceConnectionState === 'closed' || this.webRTC.iceConnectionState === "disconnected") {
  75. console.log('ICE 连接失败')
  76. this.destroyed()
  77. }
  78. }
  79. }
  80. // 用户信息
  81. msg(data){
  82. if (data.type === 'answer') {
  83. // 设置本地应答
  84. this.webRTC.setRemoteDescription(data.answer)
  85. } else if (data.type === 'candidate') {
  86. // 本地设置ICE
  87. this.webRTC.addIceCandidate(data.candidate)
  88. } else if (data.type === 'conctrl') {
  89. // 控制信息
  90. //PWM.changPWM(data.conctrl)
  91. } else if (data.type === 'startRTC') {
  92. // 向其它房间人发送offer
  93. this.createOffer()
  94. }
  95. }
  96. // 创建offer
  97. async createOffer() {
  98. // 创建offer
  99. const offer = await this.webRTC.createOffer()
  100. this.webRTC.setLocalDescription(offer)
  101. // 发送offer
  102. this.socket.emit('msg', {
  103. type: 'offer',
  104. offer: offer
  105. })
  106. }
  107. destroyed() {
  108. if (this.webRTC) this.webRTC.close()
  109. if (this.audioSource) this.audioSource.stop()
  110. if (this.videoSource) this.videoSource.stop()
  111. this.webRTC = null
  112. this.mediaStream = null
  113. this.videoSource = null
  114. this.audioSource = null
  115. process.exit(1)
  116. }
  117. }
  118. new CarServer(HOST)