// Functions that you want function listDevices(callback, config) { callback = (typeof callback == "function") ? callback : null; if (config == null) config = {audio: true, video: true}; if (navigator.mediaDevices) { navigator.mediaDevices.getUserMedia(config) .then(function (stream) { navigator.mediaDevices.enumerateDevices().then(function (devices) { console.log(devices); callback(devices); // Get rid of the now useless stream try { var tracks = stream.getTracks(); for (var i in tracks) { var mst = tracks[i]; if (mst !== null && mst !== undefined) mst.stop(); } } catch (e) { } }); }) .catch(function (err) { console.error(err); callback([]); }); } else { console.warn("navigator.mediaDevices unavailable"); callback([]); } } function publishOwnFeed(videoid, streamid, videoSelect = '', audioSelect = 'default') { connect(streamid, true, false, videoid, videoSelect, audioSelect); /* var event = new Event('mediaSoupPublished'); document.dispatchEvent(event); jQuery.event.trigger({ type: 'getMyStreamId', id: streamid, }); */ } function playStream(streamid, hisVideoid) { connect(streamid, false, true, hisVideoid); } function muteVideo(videoid, value) { //videoid no needed; value:boolean if (value) { currentProducer.client.disableWebcam(); } else { currentProducer.client.enableWebcam(); } } /* stop playing a stream ! */ function stopStream(streamid) { disconnect(streamid) } /* stop publising my own stream */ function unpublishOwnFeed(_video) { if (currentProducer) { currentProducer.client.close(); } } function mute(videoid, value) { //videoid no needed; value:boolean if (value) { currentProducer.client.disableMic() } else { currentProducer.client.enableMic(); } } document.addEventListener('mediasoupError', function(event) { console.log('*** mediasoupError', event); if (!hasError) { //hasError = true; callEvent(); console.error(event) } }) document.addEventListener('mediasoupProducerPlaying', function(event) { callEvent() }) function callEvent() { var event = new Event('mediaSoupPublished'); document.dispatchEvent(event); //console.log('***** callEvent hasError',hasError); if (!hasError) { var event = new Event('mediaSoupPublished'); document.dispatchEvent(event); jQuery.event.trigger({ type: 'getMyStreamId', // 'getMyStreamid' when success or doNotGetMyStreamId if it failed (like not authorized webcam access or some other issues) id: currentConfig.roomId, }); } else { jQuery.event.trigger({ type: 'doNotGetMyStreamId', // 'getMyStreamid' when success or doNotGetMyStreamId if it failed (like not authorized webcam access or some other issues) id: currentConfig.roomId }); } } /* Internal MS functions... */ var currentProducer; var currentConfig; var consumers = {}; let hasError = false; function disconnect(streamid) { if (!streamid || streamid=='undefined') { return false; } var consumer = consumers[streamid.toString()]; if (consumer) { consumer.client.close(); consumer = null; } } function connect(roomId, produce, consume, videoid, videoDeviceId, audioDeviceId) { console.log(videoDeviceId, audioDeviceId) let currentVideoTag = $(videoid).get(0); let user_uuid = "user" + Date.now(); debugger; let config = currentConfig = { autorun: true, roomId:roomId, peerId:user_uuid, media_server_wss:media_server_wss, produce: produce === true, consume: consume === true, cam_device_id: videoDeviceId, mic_device_id: audioDeviceId }; let em; if (produce) { em = currentProducer = new EasyMediasoup.Init(config) let previousErrors; currentProducer.store.subscribe(function() { const currentValue = em.store.getState(); if (currentValue.notifications && currentValue.notifications.length) { const errors = currentValue.notifications.filter(x => x.type == 'error') if (errors && errors.length != 0) { //const error = errors[errors.length - 1]; let event = new Event('mediasoupError'); event.message = errors; document.dispatchEvent(event); previousErrors = errors; } } }) } else { em = new EasyMediasoup.Init(config) consumers[roomId.toString()] = em; } let streamStarted = false; let peers = []; em.emitter.on("SET_PRODUCER_TRACK", (MSTrack) => { console.warn("SET_PRODUCER_TRACK",MSTrack) setProducerTrack(MSTrack) }) em.emitter.on("ADD_PRODUCER", (MSTrack) => { console.warn("ADD_PRODUCER",MSTrack) setProducerTrack(MSTrack) }); let setProducerTrack = (MSTrack) =>{ setTimeout(() => { console.log(MSTrack.source, MSTrack.track.getConstraints()) //Take current redux state to get mediastream var state = em.store.getState() if (!state.me.stream) { state.me.stream = new MediaStream; } //Find old track and remove it out let oldTrack = state.me.stream.getTracks().find((track) => { return track.kind == MSTrack.track.kind }) if (oldTrack) state.me.stream.removeTrack(oldTrack) console.warn("My tracks",state.me.stream.getTracks()) //Add new track instead old state.me.stream.addTrack(MSTrack.track); var video if (currentVideoTag) { video = currentVideoTag; } else { video = $('#myVideo').get(0) } video.srcObject = state.me.stream; video.play(); if (!streamStarted) { streamStarted = true; let event = new Event('mediasoupProducerPlaying'); document.dispatchEvent(event); } }, 300); }; em.emitter.on("ADD_CONSUMER", (consumer) => { setTimeout(() => { console.warn("ADD_CONSUMER", consumer) //Take current redux var state = em.store.getState() //Find necessary peer let peer = state.peers[consumer.peerId] //Create new peer stream and add if (!peer.stream){ peer.stream = new MediaStream; } let oldTrack = peer.stream.getTracks().find((track) => { return track.kind == consumer.consumer.track.kind }) if (oldTrack) peer.stream.removeTrack(oldTrack) peer.stream.addTrack(consumer.consumer.track) //render final stream if (peer.name != user_uuid){ add_peer(peer.name, peer.stream) } }, 300) }); function get_peer(user_uuid){ let peer = peers.find(x => x.name == user_uuid) if (!peer){ peers.push({ name:user_uuid }) } console.log( peers.find(x => x.name == user_uuid)) return peers.find(x => x.name == user_uuid) } function add_peer(user_uuid, stream) { console.log('add_peer', user_uuid); const peer = get_peer(user_uuid); peer.stream_url = stream; render_peers() } function render_peers(){ peers.forEach((peer) => { console.log('render_peers', peer.stream_url); if (peer.stream_url){ var remoteVideo = currentVideoTag; try { remoteVideo.srcObject = peer.stream_url; } catch (e) { } remoteVideo.autoplay = true; remoteVideo.play(); } }) } }