diff --git a/plugin/live/amd/build/videotime.min.js b/plugin/live/amd/build/videotime.min.js index 94eece3d..bad87700 100644 --- a/plugin/live/amd/build/videotime.min.js +++ b/plugin/live/amd/build/videotime.min.js @@ -1,4 +1,4 @@ -define("videotimeplugin_live/videotime",["exports","core/ajax","mod_videotime/videotime","block_deft/janus-gateway","core/log","core/notification","block_deft/publish","block_deft/subscribe","videotimeplugin_live/socket"],(function(_exports,_ajax,_videotime,_janusGateway,_log,_notification,_publish,_subscribe,_socket){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("videotimeplugin_live/videotime",["exports","core/ajax","core/config","mod_videotime/videotime","block_deft/janus-gateway","core/log","core/notification","block_deft/publish","block_deft/subscribe","videotimeplugin_live/socket"],(function(_exports,_ajax,_config,_videotime,_janusGateway,_log,_notification,_publish,_subscribe,_socket){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /* * Video time player specific js * @@ -6,6 +6,6 @@ define("videotimeplugin_live/videotime",["exports","core/ajax","mod_videotime/vi * @module videotimeplugin_live/videotime * @copyright 2022 bdecent gmbh * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_ajax=_interopRequireDefault(_ajax),_videotime=_interopRequireDefault(_videotime),_janusGateway=_interopRequireDefault(_janusGateway),_log=_interopRequireDefault(_log),_notification=_interopRequireDefault(_notification),_publish=_interopRequireDefault(_publish),_subscribe=_interopRequireDefault(_subscribe),_socket=_interopRequireDefault(_socket);var rooms={};class Publish extends _publish.default{register(pluginHandle){return _ajax.default.call([{args:{handle:pluginHandle.getId(),id:Number(this.contextid),plugin:pluginHandle.plugin,room:this.roomid,ptype:"publish"==this.ptype,session:pluginHandle.session.getSessionId()},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_join_room"}])[0].then((response=>{this.feed=response.id})).catch(_notification.default.exception)}publishFeed(){return _ajax.default.call([{args:{id:Number(this.feed),room:this.roomid},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_publish_feed"}])[0]}unpublish(){return document.querySelectorAll("#video-controls-camera, #video-controls-display").forEach((video=>{video.srcObject=null,video.parentNode.classList.add("hidden")})),_ajax.default.call([{args:{id:Number(this.feed),publish:!1,room:this.roomid},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_publish_feed"}])[0]}handleClose(){document.querySelectorAll('[data-contextid="'+this.contextid+'"][data-action="publish"]').forEach((button=>{button.classList.remove("hidden")})),this.janus.destroy(),[this.currentCamera||Promise.resolve(null),this.currentDisplay||Promise.resolve(null)].forEach((videoInput=>{videoInput.then((videoStream=>(videoStream&&videoStream.getTracks().forEach((track=>{track.enabled=!1,track.stop()})),null))).catch(_notification.default.exception)}))}onLocalTrack(track,on){const remoteStream=new MediaStream([track]);on&&"audio"!=track.kind&&(remoteStream.mid=track.mid,_log.default.debug(on),_log.default.debug(remoteStream),_janusGateway.default.attachMediaStream(document.getElementById("video-controls-"+this.tracks[track.id]),remoteStream))}handleClick(e){const button=e.target.closest('[data-contextid="'+this.contextid+'"][data-action="publish"], [data-contextid="'+this.contextid+'"][data-action="close"], [data-contextid="'+this.contextid+'"][data-action="mute"], [data-contextid="'+this.contextid+'"][data-action="unmute"], [data-contextid="'+this.contextid+'"][data-action="switch"], [data-contextid="'+this.contextid+'"][data-action="unpublish"]');if(button){const action=button.getAttribute("data-action"),type=button.getAttribute("data-type")||"camera";switch(e.stopPropagation(),e.preventDefault(),document.querySelectorAll('[data-region="deft-venue"] [data-action="publish"], [data-region="deft-venue"] [data-action="unpublish"]').forEach((button=>{button.getAttribute("data-action")==action&&button.getAttribute("data-type")==type||button.classList.remove("hidden")})),action){case"close":document.getElementById("video-controls-"+type).srcObject=null,document.getElementById("video-controls-"+type).parentNode.classList.add("hidden"),this.tracks[this.selectedTrack.id]==type&&this.unpublish();break;case"mute":case"unmute":("display"==type?this.currentDisplay:this.currentCamera).then((videoStream=>(videoStream&&videoStream.getAudioTracks().forEach((track=>{track.enabled="unmute"==action})),videoStream))).catch(_notification.default.exception);break;case"publish":_log.default.debug(type),"display"==type?this.shareDisplay():this.shareCamera(),document.querySelectorAll("#video-controls-camera, #video-controls-display").forEach((video=>{video.parentNode.classList.remove("selected")})),document.getElementById("video-controls-"+type).parentNode.classList.remove("hidden"),document.getElementById("video-controls-"+type).parentNode.classList.add("selected"),this.processStream([]);break;case"switch":document.querySelectorAll("#video-controls-camera, #video-controls-display").forEach((video=>{video.parentNode.classList.remove("selected")})),this.videoInput="display"==type?this.currentDisplay:this.currentCamera,document.getElementById("video-controls-"+type).parentNode.classList.remove("hidden"),document.getElementById("video-controls-"+type).parentNode.classList.add("selected"),this.processStream([]);break;case"unpublish":this.unpublish()}}return!0}shareCamera(){const videoInput=this.videoInput,currentCamera=this.currentCamera||Promise.resolve(null);this.videoInput=currentCamera.then((videoStream=>{if(videoStream)return videoStream;{const cameraInput=navigator.mediaDevices.getUserMedia({video:!0,audio:!0});return this.currentCamera=cameraInput.catch((()=>currentCamera)),cameraInput.then((videoStream=>(this.tracks=this.tracks||{},videoStream.getTracks().forEach((track=>{this.tracks[track.id]="camera"})),videoStream))).catch((e=>(_log.default.debug(e),videoInput)))}}))}shareDisplay(){const videoInput=this.videoInput,currentDisplay=this.currentDisplay||Promise.resolve(null),displayInput=navigator.mediaDevices.getDisplayMedia({video:!0,audio:!0});this.videoInput=displayInput.then((videoStream=>(videoInput&&videoInput.then((videoStream=>(videoStream&&videoStream.getTracks().forEach((track=>{_log.default.debug(track)})),videoStream))).catch(_notification.default.exception),this.tracks=this.tracks||{},videoStream.getTracks().forEach((track=>{this.tracks[track.id]="display"})),videoStream))).catch((e=>(_log.default.debug(e),videoInput))),this.currentDisplay=displayInput.then((videoStream=>(currentDisplay.then((videoStream=>{videoStream&&videoStream.getTracks().forEach((track=>{_log.default.debug("stop track"),_log.default.debug(track),track.stop()}))})),videoStream))).catch((e=>(_log.default.debug(e),currentDisplay)))}processStream(tracks){this.videoInput.then((videoStream=>{if(this.tracks=this.tracks||{},videoStream){const audiotransceiver=this.getTransceiver("audio"),videotransceiver=this.getTransceiver("video");if(videoStream.getVideoTracks().forEach((track=>{track.addEventListener("ended",(()=>{this.selectedTrack.id==track.id?this.unpublish():document.getElementById("video-controls-"+this.tracks[track.id]).parentNode.classList.add("hidden")})),this.selectedTrack=track,videotransceiver?this.videoroom.replaceTracks({tracks:[{type:"video",mid:videotransceiver.mid,capture:track}],error:_notification.default.exception}):tracks.push({type:"video",capture:track,recv:!1})})),videoStream.getAudioTracks().forEach((track=>{document.querySelector('.hidden[data-action="mute"][data-contextid="'+this.contextid+'"][data-type="'+this.tracks[this.selectedTrack.id]+'"]')&&(track.enabled=!1),audiotransceiver?this.videoroom.replaceTracks({tracks:[{type:"audio",mid:audiotransceiver.mid,capture:track}],error:_notification.default.exception}):tracks.push({type:"audio",capture:track,recv:!1})})),!tracks.length)return videoStream;this.videoroom.createOffer({tracks:tracks,success:jsep=>{this.videoroom.send({message:{request:"configure",video:!0,audio:!0},jsep:jsep})},error:function(error){_notification.default.alert("WebRTC error... ",error.message)}})}return videoStream})).catch(_notification.default.exception)}}class VideoTime extends _videotime.default{initialize(contextid,token,peerid){return _log.default.debug("Initializing Video Time "+this.elementId),this.contextid=contextid,this.peerid=peerid,_ajax.default.call([{methodname:"videotimeplugin_live_get_room",args:{contextid:contextid},done:response=>{const socket=new _socket.default(contextid,token);this.iceservers=JSON.parse(response.iceservers),this.roomid=response.roomid,this.server=response.server,rooms[String(contextid)]={contextid:contextid,peerid:peerid,roomid:response.roomid,server:response.server,iceServers:JSON.parse(response.iceservers)},this.roomid=response.roomid,document.querySelector('[data-contextid="'+this.contextid+'"] .videotime-control').classList.remove("hidden"),socket.subscribe((()=>{_ajax.default.call([{methodname:"videotimeplugin_live_get_feed",args:{contextid:contextid},done:response=>{const room=rooms[String(contextid)];room.publish&&room.publish.restart&&(response.feed==peerid&&this.unpublish(),room.publish=null),this.subscribeTo(Number(response.feed))},fail:_notification.default.exception}])}))},fail:_notification.default.exception}]),this.addListeners(),!0}addListeners(){document.querySelector("body").removeEventListener("click",handleClick),document.querySelector("body").addEventListener("click",handleClick)}subscribeTo(source){_log.default.debug(source);const room=rooms[String(this.contextid)];if(document.querySelectorAll('[data-contextid="'+this.contextid+'"][data-action="publish"]').forEach((button=>{Number(this.peerid),button.classList.remove("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"][data-action="unpublish"]').forEach((button=>{Number(this.peerid),button.classList.remove("hidden")})),_log.default.debug(source),!this.remoteFeed||this.remoteFeed.creatingSubscription||this.remoteFeed.restart)this.remoteFeed&&this.remoteFeed.restart?this.remoteFeed.current!=source&&(this.remoteFeed=null,this.subscribeTo(source)):this.remoteFeed?setTimeout((()=>{this.subscribeTo(source)}),500):source&&(this.remoteFeed=new Subscribe(this.contextid,this.iceservers,this.roomid,this.server,this.peerid),this.remoteFeed.remoteVideo=document.getElementById(this.elementId),this.remoteFeed.remoteAudio=document.getElementById(this.elementId).parentNode.querySelector("audio"),this.remoteFeed.muteAudio=room.publish&&room.publish.feed===source,this.remoteFeed.startConnection(source),document.querySelectorAll('[data-contextid="'+this.contextid+'"] img.poster-img').forEach((img=>{img.classList.add("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"] video').forEach((img=>{img.classList.remove("hidden")})));else{const update={request:"update",subscribe:[{feed:Number(source)}],unsubscribe:[{feed:Number(this.remoteFeed.current)}]};!source&&this.remoteFeed.current?delete update.subscribe:source&&!this.remoteFeed.current&&delete update.unsubscribe,this.remoteFeed.current!=source&&(this.remoteFeed.muteAudio=room.publish&&room.publish.feed===source,this.remoteFeed.videoroom.send({message:update}),this.remoteFeed.audioTrack&&(this.remoteFeed.audioTrack.enabled=!this.remoteFeed.muteAudio),room.publish&&this.remoteFeed.current==room.publish.feed&&(room.publish.handleClose(),room.publish=null),this.remoteFeed.current=source,!source&&this.remoteFeed&&(this.remoteFeed.handleClose(),this.remoteFeed=null),_log.default.debug('[data-contextid="'+this.contextid+'"] img.poster-img'),Number(source)?(document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed img.poster-img').forEach((img=>{img.classList.add("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed video').forEach((video=>{video.classList.remove("hidden")}))):(document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed img.poster-img').forEach((img=>{img.classList.remove("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed video').forEach((video=>{video.srcObject=null,video.classList.add("hidden")}))))}}}_exports.default=VideoTime;const handleClick=function(e){const button=e.target.closest('[data-roomid] [data-action="publish"], [data-roomid] [data-action="unpublish"],[data-roomid] [data-action="close"], [data-roomid] [data-action="switch"], [data-roomid] [data-action="mute"], [data-roomid] [data-action="unmute"]');if(button){const action=button.getAttribute("data-action"),contextid=e.target.closest("[data-contextid]").getAttribute("data-contextid"),room=rooms[String(contextid)],iceServers=room.iceServers,peerid=room.peerid,roomid=room.roomid,server=room.server,type=button.getAttribute("data-type");e.stopPropagation(),e.preventDefault(),"publish"!=action||room.publish&&!room.publish.restart?("mute"!=action&&"unmute"!=action||(button.classList.add("hidden"),button.parentNode.querySelectorAll('[data-action="mute"], [data-action="unmute"]').forEach((button=>{button.getAttribute("data-action")!=action&&button.classList.remove("hidden")}))),room.publish&&room.publish.handleClick(e)):(room.publish=new Publish(contextid,iceServers,roomid,server,peerid),"display"==type?room.publish.shareDisplay():room.publish.shareCamera(),room.publish.startConnection(),document.getElementById("video-controls-"+(type||"camera")).parentNode.classList.remove("hidden"),document.getElementById("video-controls-"+(type||"camera")).parentNode.classList.add("selected"))}};class Subscribe extends _subscribe.default{register(pluginHandle){return _ajax.default.call([{args:{handle:pluginHandle.getId(),id:Number(this.contextid),plugin:pluginHandle.plugin,room:this.roomid,ptype:!1,feed:this.feed,session:pluginHandle.session.getSessionId()},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_join_room"}])[0]}attachAudio(audioStream){_janusGateway.default.attachMediaStream(this.remoteVideo.parentNode.querySelector("audio"),audioStream),audioStream.getTracks().forEach((track=>{this.audioTrack=track,track.enabled=!this.muteAudio}))}attachVideo(videoStream){_janusGateway.default.attachMediaStream(this.remoteVideo,videoStream)}}return _exports.default})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_ajax=_interopRequireDefault(_ajax),_config=_interopRequireDefault(_config),_videotime=_interopRequireDefault(_videotime),_janusGateway=_interopRequireDefault(_janusGateway),_log=_interopRequireDefault(_log),_notification=_interopRequireDefault(_notification),_publish=_interopRequireDefault(_publish),_subscribe=_interopRequireDefault(_subscribe),_socket=_interopRequireDefault(_socket);var wstoken,rooms={};class Publish extends _publish.default{register(pluginHandle){return _ajax.default.call([{args:{handle:pluginHandle.getId(),id:Number(this.contextid),plugin:pluginHandle.plugin,room:this.roomid,ptype:"publish"==this.ptype,session:pluginHandle.session.getSessionId()},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_join_room"}])[0].then((response=>{this.feed=response.id})).catch(_notification.default.exception)}publishFeed(){return _ajax.default.call([{args:{id:Number(this.feed),room:this.roomid},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_publish_feed"}])[0]}unpublish(){return document.querySelectorAll("#video-controls-camera, #video-controls-display").forEach((video=>{video.srcObject=null,video.parentNode.classList.add("hidden")})),_ajax.default.call([{args:{id:Number(this.feed),publish:!1,room:this.roomid},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_publish_feed"}])[0]}handleClose(){document.querySelectorAll('[data-contextid="'+this.contextid+'"][data-action="publish"]').forEach((button=>{button.classList.remove("hidden")})),this.janus.destroy(),[this.currentCamera||Promise.resolve(null),this.currentDisplay||Promise.resolve(null)].forEach((videoInput=>{videoInput.then((videoStream=>(videoStream&&videoStream.getTracks().forEach((track=>{track.enabled=!1,track.stop()})),null))).catch(_notification.default.exception)}))}onLocalTrack(track,on){const remoteStream=new MediaStream([track]);on&&"audio"!=track.kind&&(remoteStream.mid=track.mid,_log.default.debug(on),_log.default.debug(remoteStream),_janusGateway.default.attachMediaStream(document.getElementById("video-controls-"+this.tracks[track.id]),remoteStream))}handleClick(e){const button=e.target.closest('[data-contextid="'+this.contextid+'"][data-action="publish"], [data-contextid="'+this.contextid+'"][data-action="close"], [data-contextid="'+this.contextid+'"][data-action="mute"], [data-contextid="'+this.contextid+'"][data-action="unmute"], [data-contextid="'+this.contextid+'"][data-action="switch"], [data-contextid="'+this.contextid+'"][data-action="unpublish"]');if(button){const action=button.getAttribute("data-action"),type=button.getAttribute("data-type")||"camera";switch(e.stopPropagation(),e.preventDefault(),document.querySelectorAll('[data-region="deft-venue"] [data-action="publish"], [data-region="deft-venue"] [data-action="unpublish"]').forEach((button=>{button.getAttribute("data-action")==action&&button.getAttribute("data-type")==type||button.classList.remove("hidden")})),action){case"close":document.getElementById("video-controls-"+type).srcObject=null,document.getElementById("video-controls-"+type).parentNode.classList.add("hidden"),this.tracks[this.selectedTrack.id]==type&&this.unpublish();break;case"mute":case"unmute":("display"==type?this.currentDisplay:this.currentCamera).then((videoStream=>(videoStream&&videoStream.getAudioTracks().forEach((track=>{track.enabled="unmute"==action})),videoStream))).catch(_notification.default.exception);break;case"publish":_log.default.debug(type),"display"==type?this.shareDisplay():this.shareCamera(),document.querySelectorAll("#video-controls-camera, #video-controls-display").forEach((video=>{video.parentNode.classList.remove("selected")})),document.getElementById("video-controls-"+type).parentNode.classList.remove("hidden"),document.getElementById("video-controls-"+type).parentNode.classList.add("selected"),this.processStream([]);break;case"switch":document.querySelectorAll("#video-controls-camera, #video-controls-display").forEach((video=>{video.parentNode.classList.remove("selected")})),this.videoInput="display"==type?this.currentDisplay:this.currentCamera,document.getElementById("video-controls-"+type).parentNode.classList.remove("hidden"),document.getElementById("video-controls-"+type).parentNode.classList.add("selected"),this.processStream([]);break;case"unpublish":this.unpublish()}}return!0}shareCamera(){const videoInput=this.videoInput,currentCamera=this.currentCamera||Promise.resolve(null);this.videoInput=currentCamera.then((videoStream=>{if(videoStream)return videoStream;{const cameraInput=navigator.mediaDevices.getUserMedia({video:!0,audio:!0});return this.currentCamera=cameraInput.catch((()=>currentCamera)),cameraInput.then((videoStream=>(this.tracks=this.tracks||{},videoStream.getTracks().forEach((track=>{this.tracks[track.id]="camera"})),videoStream))).catch((e=>(_log.default.debug(e),videoInput)))}}))}shareDisplay(){const videoInput=this.videoInput,currentDisplay=this.currentDisplay||Promise.resolve(null),displayInput=navigator.mediaDevices.getDisplayMedia({video:!0,audio:!0});this.videoInput=displayInput.then((videoStream=>(videoInput&&videoInput.then((videoStream=>(videoStream&&videoStream.getTracks().forEach((track=>{_log.default.debug(track)})),videoStream))).catch(_notification.default.exception),this.tracks=this.tracks||{},videoStream.getTracks().forEach((track=>{this.tracks[track.id]="display"})),videoStream))).catch((e=>(_log.default.debug(e),videoInput))),this.currentDisplay=displayInput.then((videoStream=>(currentDisplay.then((videoStream=>{videoStream&&videoStream.getTracks().forEach((track=>{_log.default.debug("stop track"),_log.default.debug(track),track.stop()}))})),videoStream))).catch((e=>(_log.default.debug(e),currentDisplay)))}processStream(tracks){this.videoInput.then((videoStream=>{if(this.tracks=this.tracks||{},videoStream){const audiotransceiver=this.getTransceiver("audio"),videotransceiver=this.getTransceiver("video");if(videoStream.getVideoTracks().forEach((track=>{track.addEventListener("ended",(()=>{this.selectedTrack.id==track.id?this.unpublish():document.getElementById("video-controls-"+this.tracks[track.id]).parentNode.classList.add("hidden")})),this.selectedTrack=track,videotransceiver?this.videoroom.replaceTracks({tracks:[{type:"video",mid:videotransceiver.mid,capture:track}],error:_notification.default.exception}):tracks.push({type:"video",capture:track,recv:!1})})),videoStream.getAudioTracks().forEach((track=>{document.querySelector('.hidden[data-action="mute"][data-contextid="'+this.contextid+'"][data-type="'+this.tracks[this.selectedTrack.id]+'"]')&&(track.enabled=!1),audiotransceiver?this.videoroom.replaceTracks({tracks:[{type:"audio",mid:audiotransceiver.mid,capture:track}],error:_notification.default.exception}):tracks.push({type:"audio",capture:track,recv:!1})})),!tracks.length)return videoStream;this.videoroom.createOffer({tracks:tracks,success:jsep=>{this.videoroom.send({message:{request:"configure",video:!0,audio:!0},jsep:jsep})},error:function(error){_notification.default.alert("WebRTC error... ",error.message)}})}return videoStream})).catch(_notification.default.exception)}}class VideoTime extends _videotime.default{initialize(contextid,token,peerid){return _log.default.debug("Initializing Video Time "+this.elementId),this.contextid=contextid,this.peerid=peerid,this.instance.token&&(wstoken=this.instance.token),this.getRoom().then((response=>{const socket=new _socket.default(contextid,token);this.iceservers=JSON.parse(response.iceservers),this.roomid=response.roomid,this.server=response.server,rooms[String(contextid)]={contextid:contextid,peerid:peerid,roomid:response.roomid,server:response.server,iceServers:JSON.parse(response.iceservers)},this.roomid=response.roomid,document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-control').forEach((control=>{control.classList.remove("hidden")})),socket.subscribe((()=>{this.getFeed().then((response=>{const room=rooms[String(contextid)];room.publish&&room.publish.restart&&(response.feed==peerid&&this.unpublish(),room.publish=null),this.subscribeTo(Number(response.feed))})).catch(_notification.default.exception)}))})).catch(_notification.default.exception),this.addListeners(),!0}getRoom(){if(wstoken){const url=new URL(_config.default.wwwroot+"/webservice/rest/server.php"),data=url.searchParams;return data.set("wstoken",wstoken),data.set("moodlewsrestformat","json"),data.set("wsfunction","videotimeplugin_live_get_room"),data.set("contextid",this.contextid),fetch(url).then((response=>(response.ok||_notification.default.exeption("Web service error"),response.json())))}return _ajax.default.call([{methodname:"videotimeplugin_live_get_room",args:{contextid:this.contextid},fail:_notification.default.exception}])[0]}getFeed(){if(wstoken){const url=new URL(_config.default.wwwroot+"/webservice/rest/server.php"),data=url.searchParams;return data.set("wstoken",wstoken),data.set("moodlewsrestformat","json"),data.set("wsfunction","videotimeplugin_live_get_feed"),data.set("contextid",this.contextid),fetch(url).then((response=>(response.ok||_notification.default.exeption("Web service error"),response.json())))}return _ajax.default.call([{methodname:"videotimeplugin_live_get_feed",args:{contextid:this.contextid},fail:_notification.default.exception}])[0]}addListeners(){document.querySelector("body").removeEventListener("click",handleClick),document.querySelector("body").addEventListener("click",handleClick)}subscribeTo(source){_log.default.debug(source);const room=rooms[String(this.contextid)];if(document.querySelectorAll('[data-contextid="'+this.contextid+'"][data-action="publish"]').forEach((button=>{Number(this.peerid),button.classList.remove("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"][data-action="unpublish"]').forEach((button=>{Number(this.peerid),button.classList.remove("hidden")})),_log.default.debug(source),!this.remoteFeed||this.remoteFeed.creatingSubscription||this.remoteFeed.restart)this.remoteFeed&&this.remoteFeed.restart?this.remoteFeed.current!=source&&(this.remoteFeed=null,this.subscribeTo(source)):this.remoteFeed?setTimeout((()=>{this.subscribeTo(source)}),500):source&&(this.remoteFeed=new Subscribe(this.contextid,this.iceservers,this.roomid,this.server,this.peerid),this.remoteFeed.remoteVideo=document.getElementById(this.elementId),this.remoteFeed.remoteAudio=document.getElementById(this.elementId).parentNode.querySelector("audio"),this.remoteFeed.muteAudio=room.publish&&room.publish.feed===source,this.remoteFeed.startConnection(source),document.querySelectorAll('[data-contextid="'+this.contextid+'"] img.poster-img').forEach((img=>{img.classList.add("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"] video').forEach((img=>{img.classList.remove("hidden")})));else{const update={request:"update",subscribe:[{feed:Number(source)}],unsubscribe:[{feed:Number(this.remoteFeed.current)}]};!source&&this.remoteFeed.current?delete update.subscribe:source&&!this.remoteFeed.current&&delete update.unsubscribe,this.remoteFeed.current!=source&&(this.remoteFeed.muteAudio=room.publish&&room.publish.feed===source,this.remoteFeed.videoroom.send({message:update}),this.remoteFeed.audioTrack&&(this.remoteFeed.audioTrack.enabled=!this.remoteFeed.muteAudio),room.publish&&this.remoteFeed.current==room.publish.feed&&(room.publish.handleClose(),room.publish=null),this.remoteFeed.current=source,!source&&this.remoteFeed&&(this.remoteFeed.handleClose(),this.remoteFeed=null),_log.default.debug('[data-contextid="'+this.contextid+'"] img.poster-img'),Number(source)?(document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed img.poster-img').forEach((img=>{img.classList.add("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed video').forEach((video=>{video.classList.remove("hidden")}))):(document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed img.poster-img').forEach((img=>{img.classList.remove("hidden")})),document.querySelectorAll('[data-contextid="'+this.contextid+'"] .videotime-embed video').forEach((video=>{video.srcObject=null,video.classList.add("hidden")}))))}}}_exports.default=VideoTime;const handleClick=function(e){const button=e.target.closest('[data-roomid] [data-action="publish"], [data-roomid] [data-action="unpublish"],[data-roomid] [data-action="close"], [data-roomid] [data-action="switch"], [data-roomid] [data-action="mute"], [data-roomid] [data-action="unmute"]');if(button){const action=button.getAttribute("data-action"),contextid=e.target.closest("[data-contextid]").getAttribute("data-contextid"),room=rooms[String(contextid)],iceServers=room.iceServers,peerid=room.peerid,roomid=room.roomid,server=room.server,type=button.getAttribute("data-type");e.stopPropagation(),e.preventDefault(),"publish"!=action||room.publish&&!room.publish.restart?("mute"!=action&&"unmute"!=action||(button.classList.add("hidden"),button.parentNode.querySelectorAll('[data-action="mute"], [data-action="unmute"]').forEach((button=>{button.getAttribute("data-action")!=action&&button.classList.remove("hidden")}))),room.publish&&room.publish.handleClick(e)):(room.publish=new Publish(contextid,iceServers,roomid,server,peerid),"display"==type?room.publish.shareDisplay():room.publish.shareCamera(),room.publish.startConnection(),document.getElementById("video-controls-"+(type||"camera")).parentNode.classList.remove("hidden"),document.getElementById("video-controls-"+(type||"camera")).parentNode.classList.add("selected"))}};class Subscribe extends _subscribe.default{register(pluginHandle){if(wstoken){const url=new URL(_config.default.wwwroot+"/webservice/rest/server.php"),data=url.searchParams;return data.set("wstoken",wstoken),data.set("moodlewsrestformat","json"),data.set("wsfunction","videotimeplugin_live_join_room"),data.set("handle",pluginHandle.getId()),data.set("id",Number(this.contextid)),data.set("plugin",pluginHandle.plugin),data.set("room",this.roomid),data.set("feed",this.feed),data.set("session",pluginHandle.session.getSessionId()),fetch(url).then((response=>(response.ok||_notification.default.exeption("Web service error"),response.json()))).catch(_notification.default.exception)}return _ajax.default.call([{args:{handle:pluginHandle.getId(),id:Number(this.contextid),plugin:pluginHandle.plugin,room:this.roomid,ptype:!1,feed:this.feed,session:pluginHandle.session.getSessionId()},contextid:this.contextid,fail:_notification.default.exception,methodname:"videotimeplugin_live_join_room"}])[0]}attachAudio(audioStream){_janusGateway.default.attachMediaStream(this.remoteVideo.parentNode.querySelector("audio"),audioStream),audioStream.getTracks().forEach((track=>{this.audioTrack=track,track.enabled=!this.muteAudio}))}attachVideo(videoStream){_log.default.debug(this.remoteVideo),_janusGateway.default.attachMediaStream(this.remoteVideo,videoStream)}}return _exports.default})); //# sourceMappingURL=videotime.min.js.map \ No newline at end of file diff --git a/plugin/live/amd/build/videotime.min.js.map b/plugin/live/amd/build/videotime.min.js.map index d3538ee3..68eb71d1 100644 --- a/plugin/live/amd/build/videotime.min.js.map +++ b/plugin/live/amd/build/videotime.min.js.map @@ -1 +1 @@ -{"version":3,"file":"videotime.min.js","sources":["../src/videotime.js"],"sourcesContent":["/*\n * Video time player specific js\n *\n * @package videotimeplugin_live\n * @module videotimeplugin_live/videotime\n * @copyright 2022 bdecent gmbh \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from \"core/ajax\";\nimport VideoTimeBase from \"mod_videotime/videotime\";\nimport Janus from 'block_deft/janus-gateway';\nimport Log from \"core/log\";\nimport Notification from \"core/notification\";\nimport PublishBase from \"block_deft/publish\";\nimport SubscribeBase from \"block_deft/subscribe\";\nimport Socket from \"videotimeplugin_live/socket\";\n\nvar rooms = {};\n\nclass Publish extends PublishBase {\n /**\n * Register the room\n *\n * @param {object} pluginHandle\n * @return {Promise}\n */\n register(pluginHandle) {\n // Try a registration\n return Ajax.call([{\n args: {\n handle: pluginHandle.getId(),\n id: Number(this.contextid),\n plugin: pluginHandle.plugin,\n room: this.roomid,\n ptype: this.ptype == 'publish',\n session: pluginHandle.session.getSessionId()\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_join_room'\n }])[0].then(response => {\n this.feed = response.id;\n }).catch(Notification.exception);\n }\n\n /**\n * Publish current video feed\n */\n publishFeed() {\n return Ajax.call([{\n args: {\n id: Number(this.feed),\n room: this.roomid,\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_publish_feed'\n }])[0];\n }\n\n\n /**\n * Stop video feed\n */\n unpublish() {\n document.querySelectorAll('#video-controls-camera, #video-controls-display').forEach(video => {\n video.srcObject = null;\n video.parentNode.classList.add('hidden');\n });\n return Ajax.call([{\n args: {\n id: Number(this.feed),\n publish: false,\n room: this.roomid\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_publish_feed'\n }])[0];\n }\n\n handleClose() {\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"][data-action=\"publish\"]'\n ).forEach(button => {\n button.classList.remove('hidden');\n });\n\n this.janus.destroy();\n\n [\n this.currentCamera || Promise.resolve(null),\n this.currentDisplay || Promise.resolve(null),\n ].forEach(videoInput => {\n videoInput.then(videoStream => {\n if (videoStream) {\n videoStream.getTracks().forEach(track => {\n track.enabled = false;\n track.stop();\n });\n }\n\n return null;\n }).catch(Notification.exception);\n });\n }\n\n onLocalTrack(track, on) {\n const remoteStream = new MediaStream([track]);\n if (!on || (track.kind == 'audio')) {\n return;\n }\n remoteStream.mid = track.mid;\n Log.debug(on);\n Log.debug(remoteStream);\n Janus.attachMediaStream(\n document.getElementById('video-controls-' + this.tracks[track.id]),\n remoteStream\n );\n }\n\n handleClick(e) {\n const button = e.target.closest(\n '[data-contextid=\"' + this.contextid + '\"][data-action=\"publish\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"close\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"mute\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"unmute\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"switch\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"unpublish\"]'\n );\n if (button) {\n const action = button.getAttribute('data-action'),\n type = button.getAttribute('data-type') || 'camera';\n e.stopPropagation();\n e.preventDefault();\n document.querySelectorAll(\n '[data-region=\"deft-venue\"] [data-action=\"publish\"], [data-region=\"deft-venue\"] [data-action=\"unpublish\"]'\n ).forEach(button => {\n if ((button.getAttribute('data-action') != action) || (button.getAttribute('data-type') != type)) {\n button.classList.remove('hidden');\n }\n });\n switch (action) {\n case 'close':\n document.getElementById('video-controls-' + type).srcObject = null;\n document.getElementById('video-controls-' + type).parentNode.classList.add('hidden');\n if (this.tracks[this.selectedTrack.id] == type) {\n this.unpublish();\n }\n break;\n case 'mute':\n case 'unmute':\n ((type == 'display') ? this.currentDisplay : this.currentCamera)\n .then(videoStream => {\n if (videoStream) {\n videoStream.getAudioTracks().forEach(track => {\n track.enabled = (action == 'unmute');\n });\n }\n return videoStream;\n }).catch(Notification.exception);\n break;\n case 'publish':\n Log.debug(type);\n if (type == 'display') {\n this.shareDisplay();\n } else {\n this.shareCamera();\n }\n document.querySelectorAll('#video-controls-camera, #video-controls-display').forEach(video => {\n video.parentNode.classList.remove('selected');\n });\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .remove('hidden');\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .add('selected');\n\n this.processStream([]);\n break;\n case 'switch':\n document.querySelectorAll('#video-controls-camera, #video-controls-display').forEach(video => {\n video.parentNode.classList.remove('selected');\n });\n if (type == 'display') {\n this.videoInput = this.currentDisplay;\n } else {\n this.videoInput = this.currentCamera;\n }\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .remove('hidden');\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .add('selected');\n this.processStream([]);\n break;\n case 'unpublish':\n this.unpublish();\n }\n }\n\n return true;\n }\n\n /**\n * Set video source to user camera\n */\n shareCamera() {\n const videoInput = this.videoInput,\n currentCamera = this.currentCamera || Promise.resolve(null);\n\n this.videoInput = currentCamera.then(videoStream => {\n if (videoStream) {\n return videoStream;\n } else {\n const cameraInput = navigator.mediaDevices.getUserMedia({\n video: true,\n audio: true\n });\n\n this.currentCamera = cameraInput.catch(() => {\n return currentCamera;\n });\n\n return cameraInput.then(videoStream => {\n this.tracks = this.tracks || {};\n videoStream.getTracks().forEach(track => {\n this.tracks[track.id] = 'camera';\n });\n\n return videoStream;\n }).catch((e) => {\n Log.debug(e);\n\n return videoInput;\n });\n }\n });\n }\n\n /**\n * Set video source to display surface\n */\n shareDisplay() {\n const videoInput = this.videoInput,\n currentDisplay = this.currentDisplay || Promise.resolve(null),\n displayInput = navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: true\n });\n\n this.videoInput = displayInput.then(videoStream => {\n if (videoInput) {\n videoInput.then(videoStream => {\n if (videoStream) {\n videoStream.getTracks().forEach(track => {\n Log.debug(track); //track.stop();\n });\n }\n return videoStream;\n }).catch(Notification.exception);\n }\n this.tracks = this.tracks || {};\n videoStream.getTracks().forEach(track => {\n this.tracks[track.id] = 'display';\n });\n\n return videoStream;\n }).catch((e) => {\n Log.debug(e);\n\n return videoInput;\n });\n\n this.currentDisplay = displayInput.then(videoStream => {\n currentDisplay.then(videoStream => {\n if (videoStream) {\n videoStream.getTracks().forEach(track => {\n Log.debug('stop track');\n Log.debug(track);\n track.stop();\n });\n }\n });\n\n return videoStream;\n }).catch((e) => {\n Log.debug(e);\n\n return currentDisplay;\n });\n }\n\n processStream(tracks) {\n this.videoInput.then(videoStream => {\n this.tracks = this.tracks || {};\n if (videoStream) {\n const audiotransceiver = this.getTransceiver('audio'),\n videotransceiver = this.getTransceiver('video');\n videoStream.getVideoTracks().forEach(track => {\n track.addEventListener('ended', () => {\n if (this.selectedTrack.id == track.id) {\n this.unpublish();\n } else {\n document\n .getElementById('video-controls-' + this.tracks[track.id])\n .parentNode\n .classList\n .add('hidden');\n }\n });\n this.selectedTrack = track;\n if (videotransceiver) {\n this.videoroom.replaceTracks({\n tracks: [{\n type: 'video',\n mid: videotransceiver.mid,\n capture: track\n }],\n error: Notification.exception\n });\n\n return;\n }\n tracks.push({\n type: 'video',\n capture: track,\n recv: false\n });\n });\n videoStream.getAudioTracks().forEach(track => {\n if (\n document.querySelector('.hidden[data-action=\"mute\"][data-contextid=\"' + this.contextid + '\"][data-type=\"'\n + this.tracks[this.selectedTrack.id] + '\"]'\n )) {\n track.enabled = false;\n }\n\n if (audiotransceiver) {\n this.videoroom.replaceTracks({\n tracks: [{\n type: 'audio',\n mid: audiotransceiver.mid,\n capture: track\n }],\n error: Notification.exception\n });\n\n return;\n }\n tracks.push({\n type: 'audio',\n capture: track,\n recv: false\n });\n });\n if (!tracks.length) {\n return videoStream;\n }\n this.videoroom.createOffer({\n tracks: tracks,\n success: (jsep) => {\n const publish = {\n request: \"configure\",\n video: true,\n audio: true\n };\n this.videoroom.send({\n message: publish,\n jsep: jsep\n });\n },\n error: function(error) {\n Notification.alert(\"WebRTC error... \", error.message);\n }\n });\n }\n\n return videoStream;\n }).catch(Notification.exception);\n }\n}\n\nexport default class VideoTime extends VideoTimeBase {\n initialize(contextid, token, peerid) {\n Log.debug(\"Initializing Video Time \" + this.elementId);\n\n this.contextid = contextid;\n this.peerid = peerid;\n\n Ajax.call([{\n methodname: 'videotimeplugin_live_get_room',\n args: {contextid: contextid},\n done: (response) => {\n const socket = new Socket(contextid, token);\n\n this.iceservers = JSON.parse(response.iceservers);\n this.roomid = response.roomid;\n this.server = response.server;\n\n rooms[String(contextid)] = {\n contextid: contextid,\n peerid: peerid,\n roomid: response.roomid,\n server: response.server,\n iceServers: JSON.parse(response.iceservers)\n };\n this.roomid = response.roomid;\n\n document.querySelector('[data-contextid=\"' + this.contextid + '\"] .videotime-control').classList.remove('hidden');\n\n socket.subscribe(() => {\n Ajax.call([{\n methodname: 'videotimeplugin_live_get_feed',\n args: {contextid: contextid},\n done: (response) => {\n const room = rooms[String(contextid)];\n if (room.publish && room.publish.restart) {\n if (response.feed == peerid) {\n this.unpublish();\n }\n room.publish = null;\n }\n this.subscribeTo(Number(response.feed));\n },\n fail: Notification.exception\n }]);\n });\n },\n fail: Notification.exception\n }]);\n\n this.addListeners();\n\n return true;\n }\n\n /**\n * Register player events to respond to user interaction and play progress.\n */\n addListeners() {\n document.querySelector('body').removeEventListener('click', handleClick);\n document.querySelector('body').addEventListener('click', handleClick);\n return;\n }\n\n /**\n * Subscribe to feed\n *\n * @param {int} source Feed to subscribe\n */\n subscribeTo(source) {\n Log.debug(source);\n const room = rooms[String(this.contextid)];\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"][data-action=\"publish\"]').forEach(button => {\n if (source == Number(this.peerid)) {\n button.classList.remove('hidden');\n } else {\n button.classList.remove('hidden');\n }\n });\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"][data-action=\"unpublish\"]').forEach(button => {\n if (source == Number(this.peerid)) {\n button.classList.remove('hidden');\n } else {\n button.classList.remove('hidden');\n }\n });\n Log.debug(source);\n\n if (this.remoteFeed && !this.remoteFeed.creatingSubscription && !this.remoteFeed.restart) {\n const update = {\n request: 'update',\n subscribe: [{\n feed: Number(source)\n }],\n unsubscribe: [{\n feed: Number(this.remoteFeed.current)\n }]\n };\n\n if (!source && this.remoteFeed.current) {\n delete update.subscribe;\n } else if (source && !this.remoteFeed.current) {\n delete update.unsubscribe;\n }\n\n if (this.remoteFeed.current != source) {\n this.remoteFeed.muteAudio = room.publish && (room.publish.feed === source);\n this.remoteFeed.videoroom.send({message: update});\n if (this.remoteFeed.audioTrack) {\n this.remoteFeed.audioTrack.enabled = !this.remoteFeed.muteAudio;\n }\n\n if (room.publish && this.remoteFeed.current == room.publish.feed) {\n room.publish.handleClose();\n room.publish = null;\n }\n this.remoteFeed.current = source;\n if (!source && this.remoteFeed) {\n this.remoteFeed.handleClose();\n this.remoteFeed = null;\n }\n Log.debug('[data-contextid=\"' + this.contextid + '\"] img.poster-img');\n if (Number(source)) {\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed img.poster-img'\n ).forEach(img => {\n img.classList.add('hidden');\n });\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed video'\n ).forEach(video => {\n video.classList.remove('hidden');\n });\n } else {\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed img.poster-img'\n ).forEach(img => {\n img.classList.remove('hidden');\n });\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed video'\n ).forEach(video => {\n video.srcObject = null;\n video.classList.add('hidden');\n });\n }\n }\n } else if (this.remoteFeed && this.remoteFeed.restart) {\n if (this.remoteFeed.current != source) {\n this.remoteFeed = null;\n this.subscribeTo(source);\n }\n } else if (this.remoteFeed) {\n setTimeout(() => {\n this.subscribeTo(source);\n }, 500);\n } else if (source) {\n this.remoteFeed = new Subscribe(this.contextid, this.iceservers, this.roomid, this.server, this.peerid);\n this.remoteFeed.remoteVideo = document.getElementById(this.elementId);\n this.remoteFeed.remoteAudio = document.getElementById(this.elementId).parentNode.querySelector('audio');\n this.remoteFeed.muteAudio = room.publish && (room.publish.feed === source);\n this.remoteFeed.startConnection(source);\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"] img.poster-img').forEach(img => {\n img.classList.add('hidden');\n });\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"] video').forEach(img => {\n img.classList.remove('hidden');\n });\n }\n }\n}\n\nconst handleClick = function(e) {\n const button = e.target.closest(\n '[data-roomid] [data-action=\"publish\"], [data-roomid] [data-action=\"unpublish\"],'\n + '[data-roomid] [data-action=\"close\"], '\n + '[data-roomid] [data-action=\"switch\"], '\n + '[data-roomid] [data-action=\"mute\"], [data-roomid] [data-action=\"unmute\"]'\n );\n if (button) {\n const action = button.getAttribute('data-action'),\n contextid = e.target.closest('[data-contextid]').getAttribute('data-contextid'),\n room = rooms[String(contextid)],\n iceServers = room.iceServers,\n peerid = room.peerid,\n roomid = room.roomid,\n server = room.server,\n type = button.getAttribute('data-type');\n e.stopPropagation();\n e.preventDefault();\n if ((action == 'publish') && (!room.publish || room.publish.restart)) {\n room.publish = new Publish(contextid, iceServers, roomid, server, peerid);\n if (type == 'display') {\n room.publish.shareDisplay();\n } else {\n room.publish.shareCamera();\n }\n room.publish.startConnection();\n document\n .getElementById('video-controls-' + (type || 'camera'))\n .parentNode\n .classList\n .remove('hidden');\n document\n .getElementById('video-controls-' + (type || 'camera'))\n .parentNode\n .classList\n .add('selected');\n } else {\n if ((action == 'mute') || (action == 'unmute')) {\n button.classList.add('hidden');\n button.parentNode.querySelectorAll('[data-action=\"mute\"], [data-action=\"unmute\"]').forEach(button => {\n if (button.getAttribute('data-action') != action) {\n button.classList.remove('hidden');\n }\n });\n }\n if (room.publish) {\n room.publish.handleClick(e);\n }\n }\n }\n};\n\nclass Subscribe extends SubscribeBase {\n /**\n * Register the room\n *\n * @param {object} pluginHandle\n * @return {Promise}\n */\n register(pluginHandle) {\n // Try a registration\n return Ajax.call([{\n args: {\n handle: pluginHandle.getId(),\n id: Number(this.contextid),\n plugin: pluginHandle.plugin,\n room: this.roomid,\n ptype: false,\n feed: this.feed,\n session: pluginHandle.session.getSessionId()\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_join_room'\n }])[0];\n }\n\n attachAudio(audioStream) {\n Janus.attachMediaStream(\n this.remoteVideo.parentNode.querySelector('audio'),\n audioStream\n );\n audioStream.getTracks().forEach(track => {\n this.audioTrack = track;\n track.enabled = !this.muteAudio;\n });\n }\n\n attachVideo(videoStream) {\n Janus.attachMediaStream(\n this.remoteVideo,\n videoStream\n );\n }\n}\n"],"names":["rooms","Publish","PublishBase","register","pluginHandle","Ajax","call","args","handle","getId","id","Number","this","contextid","plugin","room","roomid","ptype","session","getSessionId","fail","Notification","exception","methodname","then","response","feed","catch","publishFeed","unpublish","document","querySelectorAll","forEach","video","srcObject","parentNode","classList","add","publish","handleClose","button","remove","janus","destroy","currentCamera","Promise","resolve","currentDisplay","videoInput","videoStream","getTracks","track","enabled","stop","onLocalTrack","on","remoteStream","MediaStream","kind","mid","debug","attachMediaStream","getElementById","tracks","handleClick","e","target","closest","action","getAttribute","type","stopPropagation","preventDefault","selectedTrack","getAudioTracks","shareDisplay","shareCamera","processStream","cameraInput","navigator","mediaDevices","getUserMedia","audio","displayInput","getDisplayMedia","audiotransceiver","getTransceiver","videotransceiver","getVideoTracks","addEventListener","videoroom","replaceTracks","capture","error","push","recv","querySelector","length","createOffer","success","jsep","send","message","request","alert","VideoTime","VideoTimeBase","initialize","token","peerid","elementId","done","socket","Socket","iceservers","JSON","parse","server","String","iceServers","subscribe","restart","subscribeTo","addListeners","removeEventListener","source","remoteFeed","creatingSubscription","current","setTimeout","Subscribe","remoteVideo","remoteAudio","muteAudio","startConnection","img","update","unsubscribe","audioTrack","SubscribeBase","attachAudio","audioStream","attachVideo"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"videotime.min.js","sources":["../src/videotime.js"],"sourcesContent":["/*\n * Video time player specific js\n *\n * @package videotimeplugin_live\n * @module videotimeplugin_live/videotime\n * @copyright 2022 bdecent gmbh \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from \"core/ajax\";\nimport Config from \"core/config\";\nimport VideoTimeBase from \"mod_videotime/videotime\";\nimport Janus from 'block_deft/janus-gateway';\nimport Log from \"core/log\";\nimport Notification from \"core/notification\";\nimport PublishBase from \"block_deft/publish\";\nimport SubscribeBase from \"block_deft/subscribe\";\nimport Socket from \"videotimeplugin_live/socket\";\n\nvar rooms = {},\n wstoken;\n\nclass Publish extends PublishBase {\n /**\n * Register the room\n *\n * @param {object} pluginHandle\n * @return {Promise}\n */\n register(pluginHandle) {\n // Try a registration\n return Ajax.call([{\n args: {\n handle: pluginHandle.getId(),\n id: Number(this.contextid),\n plugin: pluginHandle.plugin,\n room: this.roomid,\n ptype: this.ptype == 'publish',\n session: pluginHandle.session.getSessionId()\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_join_room'\n }])[0].then(response => {\n this.feed = response.id;\n }).catch(Notification.exception);\n }\n\n /**\n * Publish current video feed\n */\n publishFeed() {\n return Ajax.call([{\n args: {\n id: Number(this.feed),\n room: this.roomid,\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_publish_feed'\n }])[0];\n }\n\n\n /**\n * Stop video feed\n */\n unpublish() {\n document.querySelectorAll('#video-controls-camera, #video-controls-display').forEach(video => {\n video.srcObject = null;\n video.parentNode.classList.add('hidden');\n });\n return Ajax.call([{\n args: {\n id: Number(this.feed),\n publish: false,\n room: this.roomid\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_publish_feed'\n }])[0];\n }\n\n handleClose() {\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"][data-action=\"publish\"]'\n ).forEach(button => {\n button.classList.remove('hidden');\n });\n\n this.janus.destroy();\n\n [\n this.currentCamera || Promise.resolve(null),\n this.currentDisplay || Promise.resolve(null),\n ].forEach(videoInput => {\n videoInput.then(videoStream => {\n if (videoStream) {\n videoStream.getTracks().forEach(track => {\n track.enabled = false;\n track.stop();\n });\n }\n\n return null;\n }).catch(Notification.exception);\n });\n }\n\n onLocalTrack(track, on) {\n const remoteStream = new MediaStream([track]);\n if (!on || (track.kind == 'audio')) {\n return;\n }\n remoteStream.mid = track.mid;\n Log.debug(on);\n Log.debug(remoteStream);\n Janus.attachMediaStream(\n document.getElementById('video-controls-' + this.tracks[track.id]),\n remoteStream\n );\n }\n\n handleClick(e) {\n const button = e.target.closest(\n '[data-contextid=\"' + this.contextid + '\"][data-action=\"publish\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"close\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"mute\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"unmute\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"switch\"], [data-contextid=\"'\n + this.contextid + '\"][data-action=\"unpublish\"]'\n );\n if (button) {\n const action = button.getAttribute('data-action'),\n type = button.getAttribute('data-type') || 'camera';\n e.stopPropagation();\n e.preventDefault();\n document.querySelectorAll(\n '[data-region=\"deft-venue\"] [data-action=\"publish\"], [data-region=\"deft-venue\"] [data-action=\"unpublish\"]'\n ).forEach(button => {\n if ((button.getAttribute('data-action') != action) || (button.getAttribute('data-type') != type)) {\n button.classList.remove('hidden');\n }\n });\n switch (action) {\n case 'close':\n document.getElementById('video-controls-' + type).srcObject = null;\n document.getElementById('video-controls-' + type).parentNode.classList.add('hidden');\n if (this.tracks[this.selectedTrack.id] == type) {\n this.unpublish();\n }\n break;\n case 'mute':\n case 'unmute':\n ((type == 'display') ? this.currentDisplay : this.currentCamera)\n .then(videoStream => {\n if (videoStream) {\n videoStream.getAudioTracks().forEach(track => {\n track.enabled = (action == 'unmute');\n });\n }\n return videoStream;\n }).catch(Notification.exception);\n break;\n case 'publish':\n Log.debug(type);\n if (type == 'display') {\n this.shareDisplay();\n } else {\n this.shareCamera();\n }\n document.querySelectorAll('#video-controls-camera, #video-controls-display').forEach(video => {\n video.parentNode.classList.remove('selected');\n });\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .remove('hidden');\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .add('selected');\n\n this.processStream([]);\n break;\n case 'switch':\n document.querySelectorAll('#video-controls-camera, #video-controls-display').forEach(video => {\n video.parentNode.classList.remove('selected');\n });\n if (type == 'display') {\n this.videoInput = this.currentDisplay;\n } else {\n this.videoInput = this.currentCamera;\n }\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .remove('hidden');\n document\n .getElementById('video-controls-' + type)\n .parentNode\n .classList\n .add('selected');\n this.processStream([]);\n break;\n case 'unpublish':\n this.unpublish();\n }\n }\n\n return true;\n }\n\n /**\n * Set video source to user camera\n */\n shareCamera() {\n const videoInput = this.videoInput,\n currentCamera = this.currentCamera || Promise.resolve(null);\n\n this.videoInput = currentCamera.then(videoStream => {\n if (videoStream) {\n return videoStream;\n } else {\n const cameraInput = navigator.mediaDevices.getUserMedia({\n video: true,\n audio: true\n });\n\n this.currentCamera = cameraInput.catch(() => {\n return currentCamera;\n });\n\n return cameraInput.then(videoStream => {\n this.tracks = this.tracks || {};\n videoStream.getTracks().forEach(track => {\n this.tracks[track.id] = 'camera';\n });\n\n return videoStream;\n }).catch((e) => {\n Log.debug(e);\n\n return videoInput;\n });\n }\n });\n }\n\n /**\n * Set video source to display surface\n */\n shareDisplay() {\n const videoInput = this.videoInput,\n currentDisplay = this.currentDisplay || Promise.resolve(null),\n displayInput = navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: true\n });\n\n this.videoInput = displayInput.then(videoStream => {\n if (videoInput) {\n videoInput.then(videoStream => {\n if (videoStream) {\n videoStream.getTracks().forEach(track => {\n Log.debug(track); //track.stop();\n });\n }\n return videoStream;\n }).catch(Notification.exception);\n }\n this.tracks = this.tracks || {};\n videoStream.getTracks().forEach(track => {\n this.tracks[track.id] = 'display';\n });\n\n return videoStream;\n }).catch((e) => {\n Log.debug(e);\n\n return videoInput;\n });\n\n this.currentDisplay = displayInput.then(videoStream => {\n currentDisplay.then(videoStream => {\n if (videoStream) {\n videoStream.getTracks().forEach(track => {\n Log.debug('stop track');\n Log.debug(track);\n track.stop();\n });\n }\n });\n\n return videoStream;\n }).catch((e) => {\n Log.debug(e);\n\n return currentDisplay;\n });\n }\n\n processStream(tracks) {\n this.videoInput.then(videoStream => {\n this.tracks = this.tracks || {};\n if (videoStream) {\n const audiotransceiver = this.getTransceiver('audio'),\n videotransceiver = this.getTransceiver('video');\n videoStream.getVideoTracks().forEach(track => {\n track.addEventListener('ended', () => {\n if (this.selectedTrack.id == track.id) {\n this.unpublish();\n } else {\n document\n .getElementById('video-controls-' + this.tracks[track.id])\n .parentNode\n .classList\n .add('hidden');\n }\n });\n this.selectedTrack = track;\n if (videotransceiver) {\n this.videoroom.replaceTracks({\n tracks: [{\n type: 'video',\n mid: videotransceiver.mid,\n capture: track\n }],\n error: Notification.exception\n });\n\n return;\n }\n tracks.push({\n type: 'video',\n capture: track,\n recv: false\n });\n });\n videoStream.getAudioTracks().forEach(track => {\n if (\n document.querySelector('.hidden[data-action=\"mute\"][data-contextid=\"' + this.contextid + '\"][data-type=\"'\n + this.tracks[this.selectedTrack.id] + '\"]'\n )) {\n track.enabled = false;\n }\n\n if (audiotransceiver) {\n this.videoroom.replaceTracks({\n tracks: [{\n type: 'audio',\n mid: audiotransceiver.mid,\n capture: track\n }],\n error: Notification.exception\n });\n\n return;\n }\n tracks.push({\n type: 'audio',\n capture: track,\n recv: false\n });\n });\n if (!tracks.length) {\n return videoStream;\n }\n this.videoroom.createOffer({\n tracks: tracks,\n success: (jsep) => {\n const publish = {\n request: \"configure\",\n video: true,\n audio: true\n };\n this.videoroom.send({\n message: publish,\n jsep: jsep\n });\n },\n error: function(error) {\n Notification.alert(\"WebRTC error... \", error.message);\n }\n });\n }\n\n return videoStream;\n }).catch(Notification.exception);\n }\n}\n\nexport default class VideoTime extends VideoTimeBase {\n initialize(contextid, token, peerid) {\n Log.debug(\"Initializing Video Time \" + this.elementId);\n\n this.contextid = contextid;\n this.peerid = peerid;\n\n if (this.instance.token) {\n wstoken = this.instance.token;\n }\n\n this.getRoom().then(response => {\n const socket = new Socket(contextid, token);\n\n this.iceservers = JSON.parse(response.iceservers);\n this.roomid = response.roomid;\n this.server = response.server;\n\n rooms[String(contextid)] = {\n contextid: contextid,\n peerid: peerid,\n roomid: response.roomid,\n server: response.server,\n iceServers: JSON.parse(response.iceservers)\n };\n this.roomid = response.roomid;\n\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"] .videotime-control').forEach(control => {\n control.classList.remove('hidden');\n });\n\n socket.subscribe(() => {\n this.getFeed().then(response => {\n const room = rooms[String(contextid)];\n if (room.publish && room.publish.restart) {\n if (response.feed == peerid) {\n this.unpublish();\n }\n room.publish = null;\n }\n this.subscribeTo(Number(response.feed));\n }).catch(Notification.exception);\n });\n }).catch(Notification.exception);\n\n this.addListeners();\n\n return true;\n }\n\n getRoom() {\n if (wstoken) {\n const url = new URL(Config.wwwroot + '/webservice/rest/server.php'),\n data = url.searchParams;\n data.set('wstoken', wstoken);\n data.set('moodlewsrestformat', 'json');\n data.set('wsfunction', 'videotimeplugin_live_get_room');\n data.set('contextid', this.contextid);\n\n return fetch(url).then((response) => {\n if (!response.ok) {\n Notification.exeption('Web service error');\n }\n return response.json();\n });\n }\n\n return Ajax.call([{\n methodname: 'videotimeplugin_live_get_room',\n args: {contextid: this.contextid},\n fail: Notification.exception\n }])[0];\n }\n\n getFeed() {\n if (wstoken) {\n const url = new URL(Config.wwwroot + '/webservice/rest/server.php'),\n data = url.searchParams;\n data.set('wstoken', wstoken);\n data.set('moodlewsrestformat', 'json');\n data.set('wsfunction', 'videotimeplugin_live_get_feed');\n data.set('contextid', this.contextid);\n\n return fetch(url).then((response) => {\n if (!response.ok) {\n Notification.exeption('Web service error');\n }\n return response.json();\n });\n }\n\n return Ajax.call([{\n methodname: 'videotimeplugin_live_get_feed',\n args: {contextid: this.contextid},\n fail: Notification.exception\n }])[0];\n }\n /**\n * Register player events to respond to user interaction and play progress.\n */\n addListeners() {\n document.querySelector('body').removeEventListener('click', handleClick);\n document.querySelector('body').addEventListener('click', handleClick);\n return;\n }\n\n /**\n * Subscribe to feed\n *\n * @param {int} source Feed to subscribe\n */\n subscribeTo(source) {\n Log.debug(source);\n const room = rooms[String(this.contextid)];\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"][data-action=\"publish\"]').forEach(button => {\n if (source == Number(this.peerid)) {\n button.classList.remove('hidden');\n } else {\n button.classList.remove('hidden');\n }\n });\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"][data-action=\"unpublish\"]').forEach(button => {\n if (source == Number(this.peerid)) {\n button.classList.remove('hidden');\n } else {\n button.classList.remove('hidden');\n }\n });\n Log.debug(source);\n\n if (this.remoteFeed && !this.remoteFeed.creatingSubscription && !this.remoteFeed.restart) {\n const update = {\n request: 'update',\n subscribe: [{\n feed: Number(source)\n }],\n unsubscribe: [{\n feed: Number(this.remoteFeed.current)\n }]\n };\n\n if (!source && this.remoteFeed.current) {\n delete update.subscribe;\n } else if (source && !this.remoteFeed.current) {\n delete update.unsubscribe;\n }\n\n if (this.remoteFeed.current != source) {\n this.remoteFeed.muteAudio = room.publish && (room.publish.feed === source);\n this.remoteFeed.videoroom.send({message: update});\n if (this.remoteFeed.audioTrack) {\n this.remoteFeed.audioTrack.enabled = !this.remoteFeed.muteAudio;\n }\n\n if (room.publish && this.remoteFeed.current == room.publish.feed) {\n room.publish.handleClose();\n room.publish = null;\n }\n this.remoteFeed.current = source;\n if (!source && this.remoteFeed) {\n this.remoteFeed.handleClose();\n this.remoteFeed = null;\n }\n Log.debug('[data-contextid=\"' + this.contextid + '\"] img.poster-img');\n if (Number(source)) {\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed img.poster-img'\n ).forEach(img => {\n img.classList.add('hidden');\n });\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed video'\n ).forEach(video => {\n video.classList.remove('hidden');\n });\n } else {\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed img.poster-img'\n ).forEach(img => {\n img.classList.remove('hidden');\n });\n document.querySelectorAll(\n '[data-contextid=\"' + this.contextid + '\"] .videotime-embed video'\n ).forEach(video => {\n video.srcObject = null;\n video.classList.add('hidden');\n });\n }\n }\n } else if (this.remoteFeed && this.remoteFeed.restart) {\n if (this.remoteFeed.current != source) {\n this.remoteFeed = null;\n this.subscribeTo(source);\n }\n } else if (this.remoteFeed) {\n setTimeout(() => {\n this.subscribeTo(source);\n }, 500);\n } else if (source) {\n this.remoteFeed = new Subscribe(this.contextid, this.iceservers, this.roomid, this.server, this.peerid);\n this.remoteFeed.remoteVideo = document.getElementById(this.elementId);\n this.remoteFeed.remoteAudio = document.getElementById(this.elementId).parentNode.querySelector('audio');\n this.remoteFeed.muteAudio = room.publish && (room.publish.feed === source);\n this.remoteFeed.startConnection(source);\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"] img.poster-img').forEach(img => {\n img.classList.add('hidden');\n });\n document.querySelectorAll('[data-contextid=\"' + this.contextid + '\"] video').forEach(img => {\n img.classList.remove('hidden');\n });\n }\n }\n}\n\nconst handleClick = function(e) {\n const button = e.target.closest(\n '[data-roomid] [data-action=\"publish\"], [data-roomid] [data-action=\"unpublish\"],'\n + '[data-roomid] [data-action=\"close\"], '\n + '[data-roomid] [data-action=\"switch\"], '\n + '[data-roomid] [data-action=\"mute\"], [data-roomid] [data-action=\"unmute\"]'\n );\n if (button) {\n const action = button.getAttribute('data-action'),\n contextid = e.target.closest('[data-contextid]').getAttribute('data-contextid'),\n room = rooms[String(contextid)],\n iceServers = room.iceServers,\n peerid = room.peerid,\n roomid = room.roomid,\n server = room.server,\n type = button.getAttribute('data-type');\n e.stopPropagation();\n e.preventDefault();\n if ((action == 'publish') && (!room.publish || room.publish.restart)) {\n room.publish = new Publish(contextid, iceServers, roomid, server, peerid);\n if (type == 'display') {\n room.publish.shareDisplay();\n } else {\n room.publish.shareCamera();\n }\n room.publish.startConnection();\n document\n .getElementById('video-controls-' + (type || 'camera'))\n .parentNode\n .classList\n .remove('hidden');\n document\n .getElementById('video-controls-' + (type || 'camera'))\n .parentNode\n .classList\n .add('selected');\n } else {\n if ((action == 'mute') || (action == 'unmute')) {\n button.classList.add('hidden');\n button.parentNode.querySelectorAll('[data-action=\"mute\"], [data-action=\"unmute\"]').forEach(button => {\n if (button.getAttribute('data-action') != action) {\n button.classList.remove('hidden');\n }\n });\n }\n if (room.publish) {\n room.publish.handleClick(e);\n }\n }\n }\n};\n\nclass Subscribe extends SubscribeBase {\n /**\n * Register the room\n *\n * @param {object} pluginHandle\n * @return {Promise}\n */\n register(pluginHandle) {\n // Try a registration\n if (wstoken) {\n const url = new URL(Config.wwwroot + '/webservice/rest/server.php'),\n data = url.searchParams;\n data.set('wstoken', wstoken);\n data.set('moodlewsrestformat', 'json');\n data.set('wsfunction', 'videotimeplugin_live_join_room');\n data.set('handle', pluginHandle.getId());\n data.set('id', Number(this.contextid));\n data.set('plugin', pluginHandle.plugin);\n data.set('room', this.roomid);\n data.set('feed', this.feed);\n data.set('session', pluginHandle.session.getSessionId());\n return fetch(url).then((response) => {\n if (!response.ok) {\n Notification.exeption('Web service error');\n }\n return response.json();\n }).catch(Notification.exception);\n }\n\n return Ajax.call([{\n args: {\n handle: pluginHandle.getId(),\n id: Number(this.contextid),\n plugin: pluginHandle.plugin,\n room: this.roomid,\n ptype: false,\n feed: this.feed,\n session: pluginHandle.session.getSessionId()\n },\n contextid: this.contextid,\n fail: Notification.exception,\n methodname: 'videotimeplugin_live_join_room'\n }])[0];\n }\n\n attachAudio(audioStream) {\n Janus.attachMediaStream(\n this.remoteVideo.parentNode.querySelector('audio'),\n audioStream\n );\n audioStream.getTracks().forEach(track => {\n this.audioTrack = track;\n track.enabled = !this.muteAudio;\n });\n }\n\n attachVideo(videoStream) {\n Log.debug(this.remoteVideo);\n Janus.attachMediaStream(\n this.remoteVideo,\n videoStream\n );\n }\n}\n"],"names":["wstoken","rooms","Publish","PublishBase","register","pluginHandle","Ajax","call","args","handle","getId","id","Number","this","contextid","plugin","room","roomid","ptype","session","getSessionId","fail","Notification","exception","methodname","then","response","feed","catch","publishFeed","unpublish","document","querySelectorAll","forEach","video","srcObject","parentNode","classList","add","publish","handleClose","button","remove","janus","destroy","currentCamera","Promise","resolve","currentDisplay","videoInput","videoStream","getTracks","track","enabled","stop","onLocalTrack","on","remoteStream","MediaStream","kind","mid","debug","attachMediaStream","getElementById","tracks","handleClick","e","target","closest","action","getAttribute","type","stopPropagation","preventDefault","selectedTrack","getAudioTracks","shareDisplay","shareCamera","processStream","cameraInput","navigator","mediaDevices","getUserMedia","audio","displayInput","getDisplayMedia","audiotransceiver","getTransceiver","videotransceiver","getVideoTracks","addEventListener","videoroom","replaceTracks","capture","error","push","recv","querySelector","length","createOffer","success","jsep","send","message","request","alert","VideoTime","VideoTimeBase","initialize","token","peerid","elementId","instance","getRoom","socket","Socket","iceservers","JSON","parse","server","String","iceServers","control","subscribe","getFeed","restart","subscribeTo","addListeners","url","URL","Config","wwwroot","data","searchParams","set","fetch","ok","exeption","json","removeEventListener","source","remoteFeed","creatingSubscription","current","setTimeout","Subscribe","remoteVideo","remoteAudio","muteAudio","startConnection","img","update","unsubscribe","audioTrack","SubscribeBase","attachAudio","audioStream","attachVideo"],"mappings":"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"} \ No newline at end of file diff --git a/plugin/live/amd/src/videotime.js b/plugin/live/amd/src/videotime.js index 9a3f996c..12fd29ec 100644 --- a/plugin/live/amd/src/videotime.js +++ b/plugin/live/amd/src/videotime.js @@ -8,6 +8,7 @@ */ import Ajax from "core/ajax"; +import Config from "core/config"; import VideoTimeBase from "mod_videotime/videotime"; import Janus from 'block_deft/janus-gateway'; import Log from "core/log"; @@ -16,7 +17,8 @@ import PublishBase from "block_deft/publish"; import SubscribeBase from "block_deft/subscribe"; import Socket from "videotimeplugin_live/socket"; -var rooms = {}; +var rooms = {}, + wstoken; class Publish extends PublishBase { /** @@ -287,8 +289,6 @@ class Publish extends PublishBase { currentDisplay.then(videoStream => { if (videoStream) { videoStream.getTracks().forEach(track => { - Log.debug('stop track'); - Log.debug(track); track.stop(); }); } @@ -399,53 +399,96 @@ export default class VideoTime extends VideoTimeBase { this.contextid = contextid; this.peerid = peerid; - Ajax.call([{ - methodname: 'videotimeplugin_live_get_room', - args: {contextid: contextid}, - done: (response) => { - const socket = new Socket(contextid, token); - - this.iceservers = JSON.parse(response.iceservers); - this.roomid = response.roomid; - this.server = response.server; - - rooms[String(contextid)] = { - contextid: contextid, - peerid: peerid, - roomid: response.roomid, - server: response.server, - iceServers: JSON.parse(response.iceservers) - }; - this.roomid = response.roomid; - - document.querySelector('[data-contextid="' + this.contextid + '"] .videotime-control').classList.remove('hidden'); - - socket.subscribe(() => { - Ajax.call([{ - methodname: 'videotimeplugin_live_get_feed', - args: {contextid: contextid}, - done: (response) => { - const room = rooms[String(contextid)]; - if (room.publish && room.publish.restart) { - if (response.feed == peerid) { - this.unpublish(); - } - room.publish = null; - } - this.subscribeTo(Number(response.feed)); - }, - fail: Notification.exception - }]); - }); - }, - fail: Notification.exception - }]); + if (this.instance.token) { + wstoken = this.instance.token; + } + + this.getRoom().then(response => { + const socket = new Socket(contextid, token); + + this.iceservers = JSON.parse(response.iceservers); + this.roomid = response.roomid; + this.server = response.server; + + rooms[String(contextid)] = { + contextid: contextid, + peerid: peerid, + roomid: response.roomid, + server: response.server, + iceServers: JSON.parse(response.iceservers) + }; + this.roomid = response.roomid; + + document.querySelectorAll('[data-contextid="' + this.contextid + '"] .videotime-control').forEach(control => { + control.classList.remove('hidden'); + }); + + socket.subscribe(() => { + this.getFeed().then(response => { + const room = rooms[String(contextid)]; + if (room.publish && room.publish.restart) { + if (response.feed == peerid) { + this.unpublish(); + } + room.publish = null; + } + this.subscribeTo(Number(response.feed)); + }).catch(Notification.exception); + }); + }).catch(Notification.exception); this.addListeners(); return true; } + getRoom() { + if (wstoken) { + const url = new URL(Config.wwwroot + '/webservice/rest/server.php'), + data = url.searchParams; + data.set('wstoken', wstoken); + data.set('moodlewsrestformat', 'json'); + data.set('wsfunction', 'videotimeplugin_live_get_room'); + data.set('contextid', this.contextid); + + return fetch(url).then((response) => { + if (!response.ok) { + Notification.exeption('Web service error'); + } + return response.json(); + }); + } + + return Ajax.call([{ + methodname: 'videotimeplugin_live_get_room', + args: {contextid: this.contextid}, + fail: Notification.exception + }])[0]; + } + + getFeed() { + if (wstoken) { + const url = new URL(Config.wwwroot + '/webservice/rest/server.php'), + data = url.searchParams; + data.set('wstoken', wstoken); + data.set('moodlewsrestformat', 'json'); + data.set('wsfunction', 'videotimeplugin_live_get_feed'); + data.set('contextid', this.contextid); + + return fetch(url).then((response) => { + if (!response.ok) { + Notification.exeption('Web service error'); + } + return response.json(); + }); + } + + return Ajax.call([{ + methodname: 'videotimeplugin_live_get_feed', + args: {contextid: this.contextid}, + fail: Notification.exception + }])[0]; + } /** * Register player events to respond to user interaction and play progress. */ @@ -461,7 +504,6 @@ export default class VideoTime extends VideoTimeBase { * @param {int} source Feed to subscribe */ subscribeTo(source) { - Log.debug(source); const room = rooms[String(this.contextid)]; document.querySelectorAll('[data-contextid="' + this.contextid + '"][data-action="publish"]').forEach(button => { if (source == Number(this.peerid)) { @@ -477,7 +519,6 @@ export default class VideoTime extends VideoTimeBase { button.classList.remove('hidden'); } }); - Log.debug(source); if (this.remoteFeed && !this.remoteFeed.creatingSubscription && !this.remoteFeed.restart) { const update = { @@ -512,7 +553,6 @@ export default class VideoTime extends VideoTimeBase { this.remoteFeed.handleClose(); this.remoteFeed = null; } - Log.debug('[data-contextid="' + this.contextid + '"] img.poster-img'); if (Number(source)) { document.querySelectorAll( '[data-contextid="' + this.contextid + '"] .videotime-embed img.poster-img' @@ -624,6 +664,26 @@ class Subscribe extends SubscribeBase { */ register(pluginHandle) { // Try a registration + if (wstoken) { + const url = new URL(Config.wwwroot + '/webservice/rest/server.php'), + data = url.searchParams; + data.set('wstoken', wstoken); + data.set('moodlewsrestformat', 'json'); + data.set('wsfunction', 'videotimeplugin_live_join_room'); + data.set('handle', pluginHandle.getId()); + data.set('id', Number(this.contextid)); + data.set('plugin', pluginHandle.plugin); + data.set('room', this.roomid); + data.set('feed', this.feed); + data.set('session', pluginHandle.session.getSessionId()); + return fetch(url).then((response) => { + if (!response.ok) { + Notification.exeption('Web service error'); + } + return response.json(); + }).catch(Notification.exception); + } + return Ajax.call([{ args: { handle: pluginHandle.getId(),