< template >
< v -container >
< v -btn @ click = "deviceSelectDialog = true" > change < / v - b t n >
< v -btn @click ="screenShare" > share a screen < / v-btn >
< v -btn @click ="screenShareStop" v-if ="screenShareStarted" > stop screen share < / v-btn >
< v -btn @click ="sharePdf=true" > share a pdf < / v-btn >
< PdfShare v -if = " sharePdf " :username ="username" :onstop ="stopSharePdf" :opaque-id ="opaqueId" :room ="room" :janus-init ="janusInit" > < / PdfShare >
< v -dialog
v - model = "mozillaAlert"
max - width = "290"
>
< v -card >
< v -card -title class = "headline" > Share whole screen or a window ? < / v - c a r d - t i t l e >
< v -card -text >
Firefox handles screensharing in a different way : are you going to share the whole screen , or would you rather pick a single window / application to share instead ?
< / v - c a r d - t e x t >
< v -card -actions >
< v -btn @click ="shareScreenStart('screen')" > Share a screen < / v-btn >
< v -btn @click ="shareScreenStart('window')" > Share a window < / v-btn >
< / v - c a r d - a c t i o n s >
< / v - c a r d >
< / v - d i a l o g > < v - d i a l o g
v - model = "chromeAlert"
max - width = "290"
>
< v -card >
< v -card -title class = "headline" > Chrome Extension Error < / v - c a r d - t i t l e >
< v -card -text >
You 're using Chrome but don' t have the screensharing extension installed : click < b > < a href = 'https://chrome.google.com/webstore/detail/janus-webrtc-screensharin/hapfgfdkleiggjjpfpenajgdnfckjpaj' target = '_blank' > here < / a > < / b > to do so
< / v - c a r d - t e x t >
< / v - c a r d >
< / v - d i a l o g >
< v -dialog
v - model = "deviceSelectDialog"
max - width = "290"
>
< v -card >
< v -card -title class = "headline" > Configuration < / v - c a r d - t i t l e >
< v -card -text >
< v -row >
< v -col md = "12" cols = "12" >
< v -select
label = "Please select video device"
v - model = "selectedVideo"
: items = "videoDevices"
item - value = "deviceId"
item - text = "label"
> < / v - s e l e c t >
< v -checkbox label = "No Video" v-model ="noVid" > < / v-checkbox >
< / v - c o l >
< v -col md = "12" cols = "12" >
< v -select
label = "Please select audio device"
: items = "audioDevices"
v - model = "selectedAudio"
item - value = "deviceId"
item - text = "label"
> < / v - s e l e c t >
< / v - c o l >
< / v - r o w >
< / v - c a r d - t e x t >
< v -card -actions >
< v -spacer > < / v - s p a c e r >
< v -btn
color = "green darken-1"
text
@ click = "deviceSelectDialog = false"
>
Disagree
< / v - b t n >
< v -btn
color = "green darken-1"
text
@ click = "selectDevice"
>
Agree
< / v - b t n >
< / v - c a r d - a c t i o n s >
< / v - c a r d >
< / v - d i a l o g >
< v -row >
< v -col cols = "12" md = "2" >
< video ref = "ownstream" class = "rounded centered" id = "myvideo" width = "100%" height = "100%" autoplay
playsinline muted = "muted" / >
< / v - c o l >
< v -col cols = "12" md = "2" style = "display: none" >
< video ref = "ownstreamscreen" class = "rounded centered" id = "myvideo2" width = "100%" height = "100%" autoplay
playsinline muted = "muted" / >
< / v - c o l >
< v -col cols = "12" md = "2" v-for ="remoteStream in remoteStreams" :key="remoteStream.id" >
< RemoteFeed :opaqueId ="opaqueId" :mypvtid ="mypvtid" :feedid ="remoteStream.id" :remote-stream ="remoteStream" :janusInit ="janusInit" :room ="room" > < / RemoteFeed >
< / v - c o l >
< / v - r o w >
< / v - c o n t a i n e r >
< / template >
< script >
import RemoteFeed from "@/lib/RemoteFeed" ;
import PdfShare from "@/lib/PdfShare" ;
export default {
components : { PdfShare , RemoteFeed } ,
props : {
server : String ,
room : Number ,
username : String
} ,
data ( ) {
return {
janusInit : null ,
opaqueId : null ,
pluginHandle : null ,
mystream : null ,
myid : '' ,
mypvtid : '' ,
selectedVideo : null ,
selectedAudio : null ,
started : false ,
mozillaAlert : false ,
sharePdf : false ,
janusScreenShareHandle : null ,
chromeAlert : false ,
videoDevices : [ ] ,
capture : '' ,
audioDevices : [ ] ,
deviceSelectDialog : false ,
noVid : false ,
shareScreenId : null ,
remoteStreams : [ ] ,
screenShareStarted : false
}
} ,
name : "VueJanus" ,
mounted ( ) {
this . janusInit = new this . $janus ( {
success : this . janusSuccess ,
server : this . server ,
error : function ( error ) {
this . $janus . error ( error ) ;
} ,
webrtcState : this . webrtcState ,
destroyed : function ( ) {
window . location . reload ( ) ;
}
} )
} ,
methods : {
stopSharePdf ( ) {
this . sharePdf = false ;
} ,
webrtcState ( on ) {
this . pluginHandle . send ( { "message" : { "request" : "configure" , "bitrate" : 512 * 1000 } } ) ;
console . log ( on , "webrt" )
} ,
janusPluginSuccessScreen ( pluginHandle ) {
this . janusScreenShareHandle = pluginHandle
this . $janus . log ( "Plugin attached! (" + this . pluginHandle . getPlugin ( ) + ", id=" + this . pluginHandle . getId ( ) + ")" ) ;
this . $janus . log ( " -- This is a publisher/manager" ) ;
var register = { "request" : "join" , "room" : this . room , "ptype" : "publisher" , "display" : this . username + " - Share Screen" } ;
pluginHandle . send ( { "message" : register } ) ;
} ,
castStart ( jsep ) {
var publish = { "request" : "configure" , "audio" : false , "video" : true } ;
this . janusScreenShareHandle . send ( { "message" : publish , "jsep" : jsep } ) ;
} ,
janusMessageScreen ( msg , jesp ) {
var event = msg [ "videoroom" ]
console . log ( jesp )
if ( event === "joined" ) {
this . janusScreenShareHandle . createOffer (
{
media : { video : this . capture , audioSend : false , videoRecv : false } , // Screen sharing Publishers are sendonly
success : this . castStart ,
error : function ( error ) {
console . log ( "WebRTC error:" , error ) ;
// bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
} ) ;
}
if ( jesp !== undefined && jesp !== null ) {
// Janus.debug("Handling SDP as well...");
// Janus.debug(jsep);
this . janusScreenShareHandle . handleRemoteJsep ( { jsep : jesp } ) ;
}
} ,
onlocalstreamScreen ( stream ) {
this . $refs . ownstreamscreen . srcObject = stream
} ,
shareScreenStart ( capture ) {
this . capture = capture
this . janusInit . attach (
{
plugin : "janus.plugin.videoroom" ,
opaqueId : this . opaqueId ,
success : this . janusPluginSuccessScreen ,
consentDialog : this . consentDialog ,
error : this . janusPluginError ,
mediaState : this . mediaState ,
webrtcState : this . webrtcState ,
onmessage : this . janusMessageScreen ,
onlocalstream : this . onlocalstreamScreen
}
)
this . screenShareStarted = true ;
} ,
screenShareStop ( ) {
var srcObject = this . $refs . ownstreamscreen . srcObject ;
for ( const track of srcObject . getTracks ( ) ) {
track . stop ( ) ;
}
var unpublish = { request : 'unpublish' } ;
this . janusScreenShareHandle . send ( { message : unpublish } ) ;
this . janusScreenShareHandle . detach ( ) ;
this . screenShareStarted = false ;
} ,
screenShare ( ) {
if ( ! this . $janus . isExtensionEnabled ( ) ) {
this . chromeAlert = true
return ;
}
if ( navigator . mozGetUserMedia ) {
// Firefox needs a different constraint for screen and window sharing
this . mozillaAlert = true
return ;
}
this . shareScreenStart ( 'screen' )
} ,
janusPluginError ( error ) {
console . log ( error )
} ,
consentDialog ( on ) {
// this.$janus.debug("Consent dialog should be " + (on ? "on" : "off") + " now");
console . log ( on )
} ,
janusPluginSuccess ( pluginHandle ) {
this . pluginHandle = pluginHandle
this . $janus . log ( "Plugin attached! (" + this . pluginHandle . getPlugin ( ) + ", id=" + this . pluginHandle . getId ( ) + ")" ) ;
this . $janus . log ( " -- This is a publisher/manager" ) ;
this . $janus . listDevices ( this . initDevices ) ;
} ,
initDevices ( devices ) {
console . log ( devices )
devices . forEach ( device => {
if ( device . kind === 'videoinput' ) {
this . videoDevices . push ( device )
}
if ( device . kind === 'audioinput' ) {
this . audioDevices . push ( device )
}
} )
this . deviceSelectDialog = true
} ,
genRemoteFeed ( ) {
this . remoteStreams . forEach ( item => {
this . createRemoteFeed ( item )
} )
} ,
offerSend ( jsep ) {
console . log ( 'vid offer' )
var publish = { "request" : "configure" , "audio" : true , "video" : true } ;
this . pluginHandle . send ( { "message" : publish , "jsep" : jsep } ) ;
} ,
controlPublishers ( msg ) {
msg [ "publishers" ] . forEach ( item => {
var has = false
this . remoteStreams . forEach ( rm => {
if ( item . id === rm . id ) has = true
} )
if ( ! has ) {
if ( this . username + " - Share Screen" !== item . display ) this . remoteStreams . push ( item )
}
} )
} ,
janusMessage ( msg , jsep ) {
console . log ( msg ) ;
var event = msg [ "videoroom" ] ;
if ( event !== undefined ) {
if ( event === "joined" ) {
this . myid = msg [ "id" ] ;
this . mypvtid = msg [ "private_id" ] ;
this . $janus . log ( "Successfully joined room " + msg [ "room" ] + " with ID " + this . myid ) ;
this . restartDevices ( )
if ( msg [ "publishers" ] !== undefined && msg [ "publishers" ] !== null ) {
this . controlPublishers ( msg )
}
} else if ( event === "event" ) {
if ( msg [ "publishers" ] !== undefined && msg [ "publishers" ] !== null ) {
this . controlPublishers ( msg )
} else if ( msg [ "leaving" ] !== undefined && msg [ "leaving" ] !== null ) {
console . log ( "leaving" )
this . remoteStreams . forEach ( item => {
if ( item . id === msg [ 'leaving' ] ) this . remoteStreams . splice ( this . remoteStreams . indexOf ( item ) , 1 )
} )
}
}
}
if ( jsep !== undefined && jsep !== null ) {
console . log ( "Handling SDP as well..." ) ;
console . log ( jsep ) ;
this . pluginHandle . handleRemoteJsep ( { jsep : jsep } ) ;
var audio = msg [ "audio_codec" ] ;
if ( this . mystream && this . mystream . getAudioTracks ( ) && this . mystream . getAudioTracks ( ) . length > 0 && ! audio ) {
console . log ( "Our audio stream has been rejected, viewers won't hear us" ) ;
}
}
} ,
onlocalstream ( stream ) {
this . mystream = stream
console . log ( this . $refs )
console . log ( this . $refs [ "ownstream" ] )
this . $refs . ownstream . srcObject = this . mystream
} ,
restartDevices ( ) {
this . deviceSelectDialog = false
var media = {
audioRecv : false , videoRecv : false , audioSend : true , videoSend : ! this . noVid ,
audio : {
deviceId : {
exact : this . selectedAudio
}
} ,
replaceAudio : true , // This is only needed in case of a renegotiation
video : {
deviceId : {
exact : this . selectedVideo
}
} ,
replaceVideo : true ,
} ;
this . pluginHandle . createOffer (
{
media : media ,
success : this . offerSend ,
error : function ( error ) {
// An error has occurred ...
console . log ( error )
}
} )
} ,
mediaState ( medium , on ) {
this . $janus . log ( "Janus " + ( on ? "started" : "stopped" ) + " receiving our " + medium ) ;
} ,
changeDevice ( ) {
this . $refs . ownstream . setSinkId ( this . selectedVideo )
this . $refs . ownstream . setSinkId ( this . selectedAudio )
} ,
selectDevice ( ) {
if ( ! this . started ) {
console . log ( this . selectedVideo )
console . log ( this . selectedAudio )
this . started = true
var register = {
"request" : "join" ,
"room" : this . room ,
"ptype" : "publisher" ,
"display" : this . username
} ;
this . pluginHandle . send ( { "message" : register } ) ;
} else {
this . restartDevices ( )
}
} ,
janusSuccess ( ) {
this . opaqueId = "videoroomtest-" + this . $janus . randomString ( 12 ) ;
this . janusInit . attach (
{
plugin : "janus.plugin.videoroom" ,
opaqueId : this . opaqueId ,
success : this . janusPluginSuccess ,
consentDialog : this . consentDialog ,
error : this . janusPluginError ,
mediaState : this . mediaState ,
webrtcState : this . webrtcState ,
onmessage : this . janusMessage ,
onlocalstream : this . onlocalstream
}
)
}
}
}
< / script >
< style scoped >
< / style >