SRSWebRtcPlayer.ts 4.1 KB

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