forwardHuya.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import { getRandomString } from 'billd-utils';
  2. import { ref } from 'vue';
  3. import { fetchRtcV1Publish } from '@/api/srs';
  4. import { SRS_CB_URL_PARAMS } from '@/constant';
  5. import { useRTCParams } from '@/hooks/use-rtcParams';
  6. import { useNetworkStore } from '@/store/network';
  7. import { useUserStore } from '@/store/user';
  8. import { LiveRoomTypeEnum } from '@/types/ILiveRoom';
  9. import { WebRTCClass } from '@/utils/network/webRTC';
  10. export const useForwardHuya = () => {
  11. const userStore = useUserStore();
  12. const networkStore = useNetworkStore();
  13. const { maxBitrate, maxFramerate, resolutionRatio } = useRTCParams();
  14. const currentMaxBitrate = ref(maxBitrate.value[3].value);
  15. const currentMaxFramerate = ref(maxFramerate.value[2].value);
  16. const currentResolutionRatio = ref(resolutionRatio.value[3].value);
  17. const isPk = ref(false);
  18. const roomId = ref('');
  19. const canvasVideoStream = ref<MediaStream>();
  20. function updateForwardHuyaConfig(data: { isPk; roomId; canvasVideoStream }) {
  21. isPk.value = data.isPk;
  22. roomId.value = data.roomId;
  23. canvasVideoStream.value = data.canvasVideoStream;
  24. }
  25. const forwardHuya = {
  26. newWebRtc: (data: {
  27. sender: string;
  28. receiver: string;
  29. videoEl: HTMLVideoElement;
  30. }) => {
  31. return new WebRTCClass({
  32. maxBitrate: currentMaxBitrate.value,
  33. maxFramerate: currentMaxFramerate.value,
  34. resolutionRatio: currentResolutionRatio.value,
  35. isSRS: true,
  36. roomId: roomId.value,
  37. videoEl: data.videoEl,
  38. sender: data.sender,
  39. receiver: data.receiver,
  40. });
  41. },
  42. /**
  43. * 主播发offer给观众
  44. */
  45. sendOffer: async ({
  46. sender,
  47. receiver,
  48. }: {
  49. sender: string;
  50. receiver: string;
  51. }) => {
  52. console.log('开始ForwardHuya的sendOffer', {
  53. sender,
  54. receiver,
  55. });
  56. try {
  57. const ws = networkStore.wsMap.get(roomId.value);
  58. if (!ws) return;
  59. const rtc = networkStore.rtcMap.get(receiver);
  60. if (rtc) {
  61. canvasVideoStream.value?.getTracks().forEach((track) => {
  62. if (canvasVideoStream.value) {
  63. console.log(
  64. 'ForwardHuya的canvasVideoStream插入track',
  65. track.kind,
  66. track
  67. );
  68. rtc.peerConnection?.addTrack(track, canvasVideoStream.value);
  69. }
  70. });
  71. const offerSdp = await rtc.createOffer();
  72. if (!offerSdp) {
  73. console.error('ForwardHuya的offerSdp为空');
  74. window.$message.error('ForwardHuya的offerSdp为空');
  75. return;
  76. }
  77. await rtc.setLocalDescription(offerSdp!);
  78. const liveRooms = userStore.userInfo?.live_rooms;
  79. const myLiveRoom = liveRooms?.[0];
  80. if (!myLiveRoom) {
  81. window.$message.error('你没有开通直播间');
  82. return;
  83. }
  84. const answerRes = await fetchRtcV1Publish({
  85. api: `/rtc/v1/publish/`,
  86. clientip: null,
  87. sdp: offerSdp.sdp!,
  88. streamurl: `${myLiveRoom.rtmp_url!}?${
  89. SRS_CB_URL_PARAMS.publishKey
  90. }=${myLiveRoom.key!}&${SRS_CB_URL_PARAMS.publishType}=${
  91. isPk.value ? LiveRoomTypeEnum.pk : LiveRoomTypeEnum.forward_huya
  92. }`,
  93. tid: getRandomString(10),
  94. });
  95. if (answerRes.data.code !== 0) {
  96. console.error('/rtc/v1/publish/拿不到sdp');
  97. window.$message.error('/rtc/v1/publish/拿不到sdp');
  98. return;
  99. }
  100. await rtc.setRemoteDescription(
  101. new RTCSessionDescription({
  102. type: 'answer',
  103. sdp: answerRes.data.sdp,
  104. })
  105. );
  106. } else {
  107. console.error('rtc不存在');
  108. }
  109. } catch (error) {
  110. console.error('ForwardHuya的sendOffer错误');
  111. }
  112. },
  113. };
  114. return { updateForwardHuyaConfig, forwardHuya };
  115. };