Skip to content

Instantly share code, notes, and snippets.

@okparaa
Created January 30, 2023 07:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okparaa/664434a7fbb23e4d086ad24a7c96af34 to your computer and use it in GitHub Desktop.
Save okparaa/664434a7fbb23e4d086ad24a7c96af34 to your computer and use it in GitHub Desktop.
midea dev
import { h, FunctionComponent } from 'preact'
import { Device } from 'mediasoup-client'
import { useEffect, useRef } from 'preact/hooks'
import {
Consumer,
Producer,
RtpCapabilities,
Transport,
} from 'mediasoup-client/lib/types'
import { openSocket } from '../../lib/socket'
// import acelogo from '../../assets/acelogo.jpg'
// import { Transport } from 'mediasoup-client/lib/Transport'
// import { Producer } from 'mediasoup-client/lib/Producer'
interface CommonProps {}
const Index: FunctionComponent<CommonProps> = (props) => {
let btnLocalVideo = useRef<HTMLButtonElement>(null)
let btnRtpCapabilities = useRef<HTMLButtonElement>(null)
let btnDevice = useRef<HTMLButtonElement>(null)
let btnCreateProducerTransport = useRef<HTMLButtonElement>(null)
let btnConnectProducerTransport = useRef<HTMLButtonElement>(null)
let btnCreateConsumerTransport = useRef<HTMLButtonElement>(null)
let btnConnectConsumerTransport = useRef<HTMLButtonElement>(null)
let localVideo = useRef<HTMLVideoElement>(null)
let remoteVideo = useRef<HTMLVideoElement>(null)
let device: Device
let producerTransport: Transport
let consumerTransport: Transport
// let userId
let producer: Producer
let consumer: Consumer
// let isWebcam: boolean
let produceTransportCallback: Function
// let connectTransportCallback: Function
// let connectConsumerCallback: Function
let rtpCapabilities: RtpCapabilities
let socket: WebSocket
const websocketUrl = 'wss://eklass.org:8000/ws'
let params: any = {
encoding: [
{
rid: 'r0',
maxBitrate: 100000,
scalabilityMode: 'S1T3',
},
{
rid: 'r1',
maxBitrate: 300000,
scalabilityMode: 'S1T3',
},
{
rid: 'r2',
maxBitrate: 900000,
scalabilityMode: 'S1T3',
},
],
codecOptions: {
videoGoogleStartBitrate: 1000,
},
}
useEffect(() => {
// console.log('okpara',btnDevice.current);
socket = openSocket(websocketUrl, 1000, 1000, 2)
socket.onmessage = (event) => {
const jsonValidation = IsJsonString(event.data)
if (!jsonValidation) {
console.error('json error')
return
}
let resp = JSON.parse(event.data)
console.log(resp)
switch (resp.type) {
case 'rtpCapabilities':
onRtpCapabilities(resp)
break
case 'producerTransportCreated':
onProducerTransportCreated(resp)
break
case 'consumerTransportCreated':
onConsumerTransportCreated(resp)
break
case 'producerCreated':
onProducerCreated(resp)
break
case 'consumerCreated':
onConsumerCreated(resp)
break
default:
break
}
}
btnLocalVideo.current &&
btnLocalVideo.current.addEventListener('click', getLocalStream)
btnRtpCapabilities.current &&
btnRtpCapabilities.current.addEventListener('click', getRtpCapabilities)
btnDevice.current &&
btnDevice.current.addEventListener('click', createDevice)
btnCreateProducerTransport.current &&
btnCreateProducerTransport.current.addEventListener(
'click',
createProducerTransport
)
btnConnectProducerTransport.current &&
btnConnectProducerTransport.current.addEventListener(
'click',
connectProducerTransport
)
btnCreateConsumerTransport.current &&
btnCreateConsumerTransport.current.addEventListener(
'click',
createConsumerTransport
)
btnConnectConsumerTransport.current &&
btnConnectConsumerTransport.current.addEventListener(
'click',
connectConsumerTransport
)
return () => {}
}, [])
const streamSuccess = async (stream: MediaStream) => {
localVideo.current && (localVideo.current.srcObject = stream)
const track = stream.getVideoTracks()[0]
params = {
track,
...params,
}
}
const getLocalStream = () => {
let constraints = {
audio: false,
video: {
width: {
min: 640,
max: 1920,
},
height: {
min: 400,
max: 1080,
},
},
}
try {
navigator.mediaDevices
.getUserMedia(constraints)
.then(streamSuccess, (error) => {
console.log(error)
})
} catch (error) {
console.error(error)
}
}
const onConsumerCreated = async (resp: any) => {
let param = resp.data
console.log('parameters view', param)
if (param.error) {
console.log('cannot connnect consumerTransport')
return
}
consumer = await consumerTransport.consume({
id: param.id,
producerId: param.producerId,
kind: param.kind,
rtpParameters: param.rtpParameters,
})
const { track } = consumer
remoteVideo.current &&
(remoteVideo.current.srcObject = new MediaStream([track]))
// console.log('track',track, 'remoteVideo', remoteVideo.current);
const message = {
type: 'resumeConsumer',
}
const req = JSON.stringify(message)
socket.send(req)
}
const connectConsumerTransport = () => {
const message = {
type: 'consumeMedia',
rtpCapabilities: device.rtpCapabilities,
}
const req = JSON.stringify(message)
socket.send(req)
}
const onConsumerTransportCreated = (resp: any) => {
console.log(resp.data)
consumerTransport = device.createRecvTransport(resp.data)
consumerTransport.on('connect', ({ dtlsParameters }, callback, errback) => {
try {
const message = {
type: 'connectConsumerTransport',
dtlsParameters,
}
const req = JSON.stringify(message)
socket.send(req)
callback()
} catch (error: any) {
errback(error)
}
})
}
const createConsumerTransport = async () => {
const message = {
type: 'createWebRtcTransport',
sender: false,
}
const req = JSON.stringify(message)
socket.send(req)
}
const onProducerCreated = (resp: any) => {
produceTransportCallback({ id: resp.data.id })
}
const connectProducerTransport = async () => {
producer = await producerTransport.produce(params)
producer.on('trackended', () => {
console.log('track ended')
})
producer.on('transportclose', () => {
console.log('transport closed')
})
}
const onProducerTransportCreated = async (event: any) => {
const params = event.data
producerTransport = device.createSendTransport(params)
producerTransport.on(
'connect',
async ({ dtlsParameters }, callback, errback) => {
try {
const message = {
type: 'connectProducerTransport',
dtlsParameters,
}
const req = JSON.stringify(message)
socket.send(req)
callback()
// connectTransportCallback = callback
} catch (error: any) {
errback(error)
}
}
)
producerTransport.on('produce', async (params, callback, errback) => {
try {
const message = {
type: 'produceMedia',
kind: params.kind,
rtpParameters: params.rtpParameters,
appData: params.appData,
}
const req = JSON.stringify(message)
socket.send(req)
produceTransportCallback = callback
} catch (error: any) {
errback(error)
}
})
}
const createProducerTransport = () => {
const message = {
type: 'createWebRtcTransport',
sender: true,
}
const req = JSON.stringify(message)
socket.send(req)
}
const createDevice = async () => {
try {
device = new Device()
await device.load({
routerRtpCapabilities: rtpCapabilities,
})
console.log('RTP Capabilities', rtpCapabilities)
} catch (error: any) {
if (error.name === 'UnsupportedError') {
console.warn('browser not supported')
}
console.warn(error)
}
}
const onRtpCapabilities = (resp: any) => {
rtpCapabilities = resp.data.rtpCapabilities
}
const getRtpCapabilities = () => {
const msg = {
type: 'getRtpCapabilities',
}
const req = JSON.stringify(msg)
socket.send(req)
}
const IsJsonString = (str: string) => {
try {
JSON.parse(str)
} catch (error) {
return false
}
return true
}
return (
<div id='video'>
<table>
<thead>
<th>Local Video</th>
<th>Remote Video</th>
</thead>
<tbody>
<tr>
<td>
<div className='sharedBtns'>
<video
ref={localVideo}
id='localVideo'
autoPlay
class='video'
></video>
</div>
</td>
<td>
<div className='sharedBtns'>
<video
ref={remoteVideo}
id='remoteVideo'
autoPlay
class='video'
></video>
</div>
</td>
</tr>
<tr>
<td>
<div className='sharedBtns'>
<button ref={btnLocalVideo} id='btnLocalVideo'>
1. Get Local Video
</button>
</div>
</td>
</tr>
<tr>
<td colSpan={2}>
<div className='sharedBtns'>
<button ref={btnRtpCapabilities} id='btnRtpCapabilities'>
2. Get Rtp Capabilities
</button>
<br />
<button ref={btnDevice} id='btnDevice'>
3. Create Device
</button>
</div>
</td>
</tr>
<tr>
<td>
<div className='sharedBtns'>
<button
ref={btnCreateProducerTransport}
id='btnCreateSendTransport'
>
4. Create Send Transport
</button>
<br />
<button
ref={btnConnectProducerTransport}
id='btnConnectSendTransport'
>
5. Connect Send Transport & Produce
</button>
</div>
</td>
<td>
<div className='sharedBtns'>
<button
ref={btnCreateConsumerTransport}
id='btnCreateRecvTransport'
>
6. Create Recv Transport
</button>
<br />
<button
ref={btnConnectConsumerTransport}
id='btnConnectRecvTransport'
>
7. Connect Recv Transport & Consume
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
)
}
export default Index
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment