Guest User

Untitled

a guest
Feb 2nd, 2023
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.67 KB | None | 0 0
  1. import { useCallback, useEffect, useRef, useState } from 'react';
  2. import { getUserMedia, LocalTrack, Space, SpaceEvent, TrackKind, TrackSource } from '@mux/spaces-web';
  3. import { Participant } from './';
  4.  
  5. const CanvasBroadcast = () => {
  6.  
  7. // 🚨 Don’t forget to add your own JWT here!
  8. const JWT = "..."
  9.  
  10. const spaceRef = useRef(null);
  11. const [localParticipant, setLocalParticipant] = useState(null);
  12. const [participants, setParticipants] = useState([]);
  13. const joined = !!localParticipant;
  14. const canvasVideo = useRef<HTMLVideoElement>();
  15.  
  16. const addParticipant = useCallback(
  17. (participant) => {
  18. setParticipants((currentParticipants) => [
  19. ...currentParticipants,
  20. participant,
  21. ]);
  22. },
  23. [setParticipants],
  24. );
  25.  
  26. const removeParticipant = useCallback(
  27. (participantLeaving) => {
  28. setParticipants((currentParticipants) =>
  29. currentParticipants.filter(
  30. (currentParticipant) =>
  31. currentParticipant.connectionId !== participantLeaving.connectionId,
  32. ),
  33. );
  34. },
  35. [setParticipants],
  36. );
  37.  
  38. useEffect(() => {
  39. const space = new Space(JWT);
  40.  
  41. space.on(SpaceEvent.ParticipantJoined, addParticipant);
  42. space.on(SpaceEvent.ParticipantLeft, removeParticipant);
  43.  
  44. spaceRef.current = space;
  45.  
  46. return () => {
  47. space.off(SpaceEvent.ParticipantJoined, addParticipant);
  48. space.off(SpaceEvent.ParticipantLeft, removeParticipant);
  49. };
  50. }, [addParticipant, removeParticipant]);
  51.  
  52. const join = useCallback(async () => {
  53. // Join the Space
  54. let localParticipant = await spaceRef.current.join();
  55.  
  56. // Get and publish our local tracks
  57.  
  58. /*let realTracks = await getUserMedia({
  59. audio: true,
  60. video: true,
  61. });*/
  62.  
  63. const localTracks = canvasStream.current.getTracks().map(t => {
  64. console.log(t.getSettings());
  65. const payload = {
  66. tid: t.id,
  67. name: t.id,
  68. muted: false,
  69. type: t.kind == 'video' ? TrackKind.Video : TrackKind.Audio,
  70. source: t.kind == 'video' ? TrackSource.Camera : TrackSource.Microphone,
  71. height: t.getSettings().height || 0,
  72. width: t.getSettings().width || 0,
  73. metadata: {},
  74. };
  75. console.log(payload);
  76. // @ts-ignore
  77. return new LocalTrack(payload, t, 'Synthetic');
  78. });
  79.  
  80. //console.log('tracks:', realTracks, localTracks);
  81.  
  82. await localParticipant.publishTracks(localTracks);
  83. // Set the local participant so it will be rendered
  84. setLocalParticipant(localParticipant);
  85. }, []);
  86.  
  87.  
  88. const cancan = useRef<HTMLCanvasElement>();
  89.  
  90. const canvasStream = useRef<MediaStream>();
  91.  
  92. const drawSomething = () => {
  93. let c = cancan.current;
  94. if (c) {
  95. const ctx = c.getContext('2d');
  96. if (Math.random() < .001) {
  97. ctx.fillStyle = `hsl(${Math.random()*360}, 100%, 50%)`
  98. ctx.fillRect(0, 0, c.width, c.height);
  99. }
  100. ctx.strokeStyle = `hsl(${Math.random()*360}, 100%, 50%)`
  101. ctx.beginPath();
  102. ctx.arc(Math.random() * 300, Math.random() * 300, 20, 0, 2 * Math.PI);
  103. ctx.stroke();
  104. }
  105. };
  106.  
  107. useEffect(() => {
  108. if (cancan.current) {
  109. let c = cancan.current;
  110. const ctx = c.getContext('2d');
  111. ctx.fillStyle = `hsl(0, 100%, 50%)`
  112. ctx.fillRect(0, 0, c.width, c.height);
  113. ctx.strokeStyle = `hsl(${Math.random()*360}, 100%, 50%)`
  114. ctx.beginPath();
  115. ctx.arc(Math.random() * 300, Math.random() * 300, 50, 0, 2 * Math.PI);
  116. ctx.stroke();
  117.  
  118. setInterval(() => {
  119. drawSomething();
  120. }, 15);
  121.  
  122. canvasStream.current = c.captureStream(25);
  123. //canvasVideo.current.srcObject = canvasStream.current;
  124. console.log(canvasStream.current);
  125. }
  126. }, [cancan]);
  127.  
  128. return (<div>
  129. <button onClick={join} disabled={joined}>
  130. Join Space
  131. </button>
  132.  
  133. <canvas width="400" height="200" ref={cancan}
  134. style={{ width: '400px', height: '225px', border: '1px solid red', backgroundColor: '#EEE' }}>
  135. </canvas>
  136.  
  137. <video
  138. ref={canvasVideo}
  139. crossOrigin="anonymous"
  140. autoPlay
  141. playsInline
  142. muted={true}
  143. style={{ width: '400px', height: '225px', border: '1px solid green' }}/>
  144.  
  145. {localParticipant && (
  146. <Participant
  147. key={localParticipant.connectionId}
  148. participant={localParticipant}
  149. />
  150. )}
  151.  
  152. {participants.map((participant) => {
  153. return (
  154. <Participant
  155. key={participant.connectionId}
  156. participant={participant}
  157. />
  158. );
  159. })}
  160. </div>
  161. );
  162. };
  163.  
  164.  
  165. export default CanvasBroadcast;
  166.  
Advertisement
Add Comment
Please, Sign In to add comment