SRSWebRtcPlayer.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /**
  2. * srs webrtc palyer
  3. * auth Caner
  4. */
  5. class WebRtcPlayer {
  6. private Peer: any
  7. private TIMER: any
  8. constructor(option: { HOST: string, TOKEN: string, UUID: string, PROFILE: number, PORT: number, DOM: HTMLElement }) {
  9. this.initWebRtc(option.HOST, option.PORT, option.TOKEN, option.UUID, option.PROFILE, option.DOM).then(res => {
  10. this.Peer = res
  11. }).catch(() => {
  12. this.Peer = null
  13. })
  14. }
  15. /**
  16. * 初始化webrtc
  17. * @param HOST 媒体服务器地址
  18. * @param TOKEN 用户token
  19. * @param UUID 摄像头uuid
  20. * @param PROFILE 码流
  21. * @param DOM video节点
  22. * @returns
  23. */
  24. private async initWebRtc(HOST: string, PORT: number, TOKEN: string, UUID: string, PROFILE: number, DOM: HTMLElement | any | null) {
  25. try {
  26. const Peer = new RTCPeerConnection() as any
  27. Peer.addTransceiver('video', { direction: 'recvonly' })
  28. const offer = await Peer.createOffer()
  29. await Peer.setLocalDescription(offer)
  30. // 监听视频=播放
  31. Peer.ontrack = (event: Event | any) => {
  32. if (DOM) {
  33. const { streams } = event
  34. DOM.srcObject = streams[0]
  35. console.log('track', event)
  36. }
  37. }
  38. Peer.oniceconnectionstatechange = () => {
  39. const state = Peer.iceConnectionState
  40. console.log('ICE状态', state)
  41. }
  42. Peer.onicegatheringstatechange = () => {
  43. console.log('GatheringState: ', Peer.iceGatheringState)
  44. }
  45. Peer.onconnectionstatechange = () => {
  46. const state = Peer.connectionState
  47. console.log('连接状态', state)
  48. }
  49. // SDP SRS params
  50. const params = {
  51. api: `http://${HOST}:${PORT}/rtc/v1/play/?token=${TOKEN}&uuid=${UUID}&stream=${UUID + PROFILE}&profile=${PROFILE}`,
  52. clientip: null,
  53. sdp: offer.sdp,
  54. streamurl: `webrtc://${HOST}/live/${UUID + PROFILE}?token=${TOKEN}&uuid=${UUID}&stream=${UUID + PROFILE}&profile=${PROFILE}`,
  55. tid: Number(Math.floor(new Date().getTime() * Math.random() * 100)).toString(16).slice(0, 7)
  56. }
  57. console.log('params', params)
  58. // 发送offer
  59. const res = await window.fetch(params.api, {
  60. method: 'POST',
  61. headers: { 'Content-Type': 'application/json' },
  62. body: JSON.stringify(params)
  63. })
  64. // 接收 answer
  65. const { sdp } = await res.json()
  66. if (sdp) await Peer.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp }))
  67. return Peer
  68. } catch (error) {
  69. console.warn('webRtcInit:', error);
  70. return null
  71. }
  72. }
  73. /**
  74. * 云台控制
  75. * @param URL
  76. * @param UUID
  77. * @param TOKEN
  78. * @param command 指令:数字键盘1-9去掉5,10:焦距放大,11:焦距缩小 12:亮度,13:色彩饱和度,14:对比度,15:清晰度
  79. * @param number [云台速度|焦距参数|色彩饱和度]等值 亮度值 0-100
  80. * @returns
  81. */
  82. public contrl(URL: string, UUID: string, TOKEN: string, command: number, number: number) {
  83. if (!UUID) return
  84. if (this.TIMER !== null) clearTimeout(this.TIMER)
  85. this.TIMER = setTimeout(() => {
  86. window.fetch(URL, {
  87. method: 'POST',
  88. headers: { 'Content-Type': 'application/json' },
  89. body: JSON.stringify({
  90. code: 'cloudcontrol.control',
  91. token: TOKEN,
  92. body: {
  93. uuid: UUID,
  94. command,
  95. number
  96. }
  97. })
  98. })
  99. }, 500);
  100. }
  101. /**
  102. * 关闭webrtc
  103. */
  104. public async close() {
  105. if (this.Peer) this.Peer.close()
  106. if (this.TIMER) clearTimeout(this.TIMER)
  107. }
  108. }
  109. export default WebRtcPlayer