2020-04-28 22:49:45 +00:00
// DISABLE RIGHTCLICK
document . addEventListener ( 'contextmenu' , event => event . preventDefault ( ) ) ;
2020-04-21 08:57:28 +00:00
const options = {
2020-04-23 15:40:39 +00:00
serviceUrl : 'https://meet.theater.digital/http-bind' ,
2020-04-21 08:57:28 +00:00
hosts : {
2020-04-21 11:36:03 +00:00
domain : 'meet.theater.digital' ,
2020-04-23 15:40:39 +00:00
muc : 'conference.meet.theater.digital'
}
2020-04-21 08:57:28 +00:00
} ;
const confOptions = {
openBridgeChannel : true
} ;
2020-04-23 15:40:39 +00:00
const videoSize = {
2020-04-27 12:57:01 +00:00
width : 624 ,
height : 351
2020-04-23 15:40:39 +00:00
} ;
2020-04-21 08:57:28 +00:00
let connection = null ;
let room = null ;
2020-12-26 20:19:59 +00:00
let muted = false ;
2020-04-21 08:57:28 +00:00
2020-04-23 15:40:39 +00:00
// zu mappende namen.
2020-04-28 22:29:29 +00:00
let remoteMappingName = new Array ( 9 ) ;
// alle verfügbaren tracks mit id -> {audio: track, video: track, position: number}
2020-04-23 15:40:39 +00:00
let tracks = { } ;
2020-12-26 16:21:36 +00:00
let useLocalVideo = false ;
let isJoined = false ;
2020-04-28 17:13:07 +00:00
2020-12-26 20:03:14 +00:00
/ * *
* HTML Builder
* a bit hacky . . but hey , i needed it fast .
* /
function initHtml ( rows , cols ) {
2020-12-26 21:01:13 +00:00
// calculate video element sizes
2020-12-26 21:22:43 +00:00
let windowHeight = window . innerHeight ;
let windowWidth = window . innerWidth ;
2020-12-26 21:01:13 +00:00
console . log ( windowHeight ) ;
2020-12-26 21:22:43 +00:00
let margin = 6 ; // 3px margin on each side
2020-12-26 21:01:13 +00:00
2020-12-26 21:37:44 +00:00
let maxWidth = ( windowWidth - 12 ) / cols - margin
let maxHeight = ( windowHeight - 12 ) / rows - margin - 24 - 28 - 6 ; // 24 -> size added for nametag; 28px per row for control elements; idontknow where the 6px appear xD
2020-12-26 21:01:13 +00:00
2020-12-26 21:22:43 +00:00
if ( maxWidth / 16 * 9 <= maxHeight ) {
2020-12-26 21:01:13 +00:00
videoSize . width = maxWidth ;
videoSize . height = maxWidth / 16 * 9 ;
} else {
videoSize . width = maxHeight * 16 / 9 ;
videoSize . height = maxHeight ;
}
// clear video container
2020-12-26 20:03:14 +00:00
let rootElem = $ ( '#video-container' )
rootElem . empty ( ) ;
2020-12-26 21:01:13 +00:00
let elemCounter = 0 // for the element container id's
// populate video elements
2020-12-26 20:03:14 +00:00
for ( let i = 0 ; i < rows ; i ++ ) {
2020-12-26 21:01:13 +00:00
let rowElem = $ ( document . createElement ( "div" ) ) ;
rowElem . addClass ( "video-row" ) ;
2020-12-26 20:03:14 +00:00
for ( let j = 0 ; j < cols ; j ++ ) {
2020-12-26 21:01:13 +00:00
let colElem = $ ( document . createElement ( "div" ) ) ;
colElem . addClass ( ` video video- ${ elemCounter ++ } ` ) ;
2020-12-26 21:22:43 +00:00
colElem . width ( videoSize . width + margin ) ;
colElem . height ( videoSize . height + margin + 24 ) ;
2020-12-26 21:01:13 +00:00
colElem . css ( "display" , "inline-block" ) ;
2020-12-26 20:03:14 +00:00
colElem . append ( `
2020-12-26 21:01:13 +00:00
< video autoplay = 'autoplay' width = "${videoSize.width}" height = "${videoSize.height}" > < / v i d e o >
2020-12-26 20:03:14 +00:00
< audio autoplay = 'autoplay' > < / a u d i o >
< span class = "name" > < / s p a n >
` )
rowElem . append ( colElem )
}
rootElem . append ( rowElem )
}
2020-12-26 21:01:13 +00:00
// populate audio controls
2020-12-26 20:03:14 +00:00
elemCounter = 0 ;
for ( let i = 0 ; i < rows ; i ++ ) {
let rowElem = $ ( document . createElement ( "div" ) )
rowElem . addClass ( "row" ) ;
for ( let j = 0 ; j < cols ; j ++ ) {
let colElem = $ ( document . createElement ( "div" ) )
colElem . addClass ( "volume-slider col volume-" + elemCounter ) ;
colElem . append ( `
< span class = "volume" > 70 % < / s p a n >
< input type = "range" min = "0" max = "1" step = "0.01" value = "0.7" oninput = "setLevel(${elemCounter}, this.value)" >
< input type = "text" onchange = "setName(${elemCounter}, this.value)" placeholder = "username1" >
< button onclick = "reload(${elemCounter})" > Reload < / b u t t o n >
` )
elemCounter ++ ;
rowElem . append ( colElem ) ;
}
rootElem . append ( rowElem ) ;
}
rootElem . append ( `
< button onclick = "leave()" > Leave Conference < / b u t t o n >
< p class = "available-users" > < / p >
` )
}
2020-04-28 13:42:06 +00:00
/ * *
*
* MIDI SECTION
* /
let midi , data ;
// start talking to MIDI controller
if ( navigator . requestMIDIAccess ) {
navigator . requestMIDIAccess ( {
sysex : false
} ) . then ( onMIDISuccess ) ;
} else {
console . warn ( "No MIDI support in your browser" )
}
// on success
function onMIDISuccess ( midiData ) {
// this is all our MIDI data
midi = midiData ;
let allInputs = midi . inputs . values ( ) ;
// loop over all available inputs and listen for any MIDI input
for ( let input = allInputs . next ( ) ; input && ! input . done ; input = allInputs . next ( ) ) {
// when a MIDI value is received call the onMIDIMessage function
input . value . onmidimessage = ( messageData ) => {
2020-04-28 15:19:28 +00:00
if ( messageData . data [ 0 ] != 176 ) return ;
2020-04-28 16:23:49 +00:00
if ( messageData . data [ 1 ] > 7 ) messageData . data [ 1 ] -= 8 ;
2020-04-28 22:29:29 +00:00
setLevel ( messageData . data [ 1 ] , messageData . data [ 2 ] / 127 ) ;
2020-04-28 13:42:06 +00:00
} ;
}
}
/ * *
*
* END MIDI SECTION
*
* /
/ * *
* Selects all shown participants to receive high quality video . Otherwise Jitsi will only show thumbnail size video to the Streamer
* /
2020-04-27 15:34:48 +00:00
function selectParticipants ( ) {
let part = [ ] ;
2020-04-28 22:29:29 +00:00
for ( let i in tracks ) {
if ( tracks . hasOwnProperty ( i ) ) {
if ( tracks [ i ] . position >= 0 ) {
part . push ( i )
}
2020-04-27 15:34:48 +00:00
}
}
room . selectParticipants ( part ) ;
}
2020-04-21 08:57:28 +00:00
/ * *
* Handles remote tracks
* @ param track JitsiTrack object
* /
function onRemoteTrack ( track ) {
if ( track . isLocal ( ) ) {
return ;
}
const participant = track . getParticipantId ( ) ;
2020-04-29 00:16:15 +00:00
if ( tracks [ participant ] == null )
return ;
2020-04-23 15:40:39 +00:00
tracks [ participant ] [ track . getType ( ) ] = track ;
2020-04-29 00:16:15 +00:00
console . log ( ` mapping ${ track . getType ( ) } track from ${ participant } ` ) ;
2020-04-29 18:45:20 +00:00
let displayName = room . getParticipantById ( participant ) . getDisplayName ( ) ? room . getParticipantById ( participant ) . getDisplayName ( ) . toLowerCase ( ) : undefined ;
if ( ! displayName ) {
return ;
}
let desiredPosition = remoteMappingName . indexOf ( displayName ) ;
if ( tracks [ participant ] . audio && tracks [ participant ] . video && desiredPosition >= 0 ) {
attachUser ( participant , desiredPosition ) ;
2020-04-29 00:16:15 +00:00
}
2020-04-23 15:40:39 +00:00
}
2020-04-21 08:57:28 +00:00
2020-04-23 15:40:39 +00:00
/ * *
* Event wenn ein Mediastream entfernt wurde .
* Räumt die Track tracker objekte auf und entfernt - wenn vorhanden - die entsprechende zuordnung zum media element
* @ param track
* /
function onRemoteTrackRemove ( track ) {
const participant = track . getParticipantId ( ) ;
const type = track . getType ( ) ;
2020-04-28 22:29:29 +00:00
if ( tracks [ participant ] != null && tracks [ participant ] [ type ] ) {
2020-04-23 15:40:39 +00:00
console . log ( ` detaching ${ type } track from ${ participant } ` ) ;
2020-04-28 22:29:29 +00:00
tracks [ participant ] [ type ] . detach ( $ ( ` .video- ${ tracks [ participant ] . position } ${ type } ` ) [ 0 ] ) ;
2020-04-21 08:57:28 +00:00
}
2020-04-27 14:38:31 +00:00
delete tracks [ participant ] [ type ] ;
2020-04-21 08:57:28 +00:00
}
/ * *
*
* @ param id
2020-04-23 15:40:39 +00:00
* @ param user
* /
function onUserJoin ( id , user ) {
2020-04-29 18:45:20 +00:00
let displayName = user . getDisplayName ( ) ? user . getDisplayName ( ) . toLowerCase ( ) : undefined ;
console . log ( ` user join - ${ displayName } ` ) ;
2020-04-29 00:16:15 +00:00
tracks [ id ] = { position : - 1 } ;
console . log ( tracks [ id ] ) ;
2020-04-29 18:45:20 +00:00
if ( displayName && remoteMappingName . indexOf ( displayName ) >= 0 ) {
2020-04-27 15:34:48 +00:00
selectParticipants ( ) ;
2020-04-23 15:40:39 +00:00
}
2020-04-28 18:07:25 +00:00
updateParticipantList ( ) ;
2020-04-23 15:40:39 +00:00
}
/ * *
* Event für Namensänderungen , ordnet den user korrekt an .
* @ param participant
* @ param displayName
* /
function onNameChange ( participant , displayName ) {
// detach this user from current position
detachUser ( participant ) ;
2020-04-29 19:03:22 +00:00
let position = - 1 ;
if ( displayName ) {
position = remoteMappingName . indexOf ( displayName . toLowerCase ( ) ) ;
}
2020-04-23 15:40:39 +00:00
if ( position >= 0 && tracks [ participant ] ) {
// detach user in the new position
2020-04-28 22:29:29 +00:00
for ( let i in tracks ) {
if ( tracks [ i ] . position === position ) {
2020-04-23 15:40:39 +00:00
detachUser ( i ) ;
2020-04-27 15:34:48 +00:00
break ;
2020-04-23 15:40:39 +00:00
}
}
2020-04-27 12:57:01 +00:00
attachUser ( participant , position )
2020-04-23 15:40:39 +00:00
}
2020-04-28 18:07:25 +00:00
selectParticipants ( ) ;
updateParticipantList ( ) ;
2020-04-23 15:40:39 +00:00
}
/ * *
* Event wenn ein User den Raum verlässt
* Entfernt die Verbindung der Tracks mit den Mediaelementen wenn vorhanden und räumt die Track tracker objekte auf .
* @ param id
2020-04-21 08:57:28 +00:00
* /
function onUserLeft ( id ) {
console . log ( 'user left' ) ;
2020-04-23 15:40:39 +00:00
detachUser ( id ) ;
delete tracks [ id ] ;
2020-04-28 18:07:25 +00:00
updateParticipantList ( ) ;
2020-04-27 15:34:48 +00:00
selectParticipants ( )
2020-04-23 15:40:39 +00:00
}
2020-04-21 08:57:28 +00:00
2020-04-28 22:29:29 +00:00
/ * *
* Detaches the Tracks of participant with ID from it ' s position .
* @ param id
* /
2020-04-23 15:40:39 +00:00
function detachUser ( id ) {
2020-04-28 22:29:29 +00:00
if ( tracks [ id ] != null ) {
2020-04-23 15:40:39 +00:00
console . log ( "detaching user " + id ) ;
2020-04-28 22:29:29 +00:00
if ( tracks [ id ] . video ) {
tracks [ id ] . video . detach ( $ ( ` .video- ${ tracks [ id ] . position } video ` ) [ 0 ] ) ;
2020-04-23 15:40:39 +00:00
}
2020-04-28 22:29:29 +00:00
if ( tracks [ id ] . audio ) {
tracks [ id ] . audio . detach ( $ ( ` .video- ${ tracks [ id ] . position } audio ` ) [ 0 ] ) ;
2020-04-23 15:40:39 +00:00
}
2020-04-28 22:29:29 +00:00
tracks [ id ] . position = - 1 ;
2020-04-21 08:57:28 +00:00
}
}
2020-04-28 22:29:29 +00:00
/ * *
* Attaches participant with ID to POSITION
* @ param id
* @ param position
* /
2020-04-27 12:57:01 +00:00
function attachUser ( id , position ) {
2020-04-28 22:29:29 +00:00
// check if track exists, and is not attached to another element already.
2020-05-02 11:50:17 +00:00
if ( tracks [ id ] != null && ( tracks [ id ] . position < 0 || tracks [ id ] . position === position ) ) {
2020-04-27 14:38:31 +00:00
console . log ( ` attaching user ${ id } to ${ position } ` ) ;
2020-04-28 22:29:29 +00:00
// check if there is already some participant attached to this position and detach the tracks
2020-05-02 11:50:17 +00:00
if ( tracks [ id ] . position !== position ) {
for ( let i in tracks ) {
if ( tracks . hasOwnProperty ( i ) && tracks [ i ] . position === position ) {
detachUser ( i ) ;
}
2020-04-28 22:29:29 +00:00
}
2020-05-02 11:50:17 +00:00
tracks [ id ] . position = position ;
2020-04-28 22:29:29 +00:00
}
// finally attach new participant to position
2020-05-02 11:50:17 +00:00
if ( tracks [ id ] . video && tracks [ id ] . video . containers . length === 0 ) {
console . log ( ` attaching video from user ${ id } to ${ position } ` ) ;
2020-04-28 22:29:29 +00:00
tracks [ id ] . video . attach ( $ ( ` .video- ${ tracks [ id ] . position } video ` ) [ 0 ] ) ;
2020-04-27 12:57:01 +00:00
}
2020-05-02 11:50:17 +00:00
if ( tracks [ id ] . audio && tracks [ id ] . audio . containers . length === 0 ) {
console . log ( ` attaching audio from user ${ id } to ${ position } ` ) ;
2020-04-28 22:29:29 +00:00
tracks [ id ] . audio . attach ( $ ( ` .video- ${ tracks [ id ] . position } audio ` ) [ 0 ] ) ;
2020-04-27 12:57:01 +00:00
}
}
}
2020-04-21 08:57:28 +00:00
/ * *
2020-04-27 14:38:31 +00:00
* Enables the connect button , so that we can join a room
2020-04-21 08:57:28 +00:00
* /
function onConnectionSuccess ( ) {
2020-04-27 14:38:31 +00:00
$ ( '#room-name-button' ) . prop ( 'disabled' , false ) ;
2020-04-21 08:57:28 +00:00
}
/ * *
2020-04-27 14:38:31 +00:00
* Resizes the video element according to maximum available width and height . Respects input aspect ratio .
2020-04-21 08:57:28 +00:00
* /
2020-04-23 15:40:39 +00:00
function onVideoResize ( event ) {
2020-12-26 21:52:34 +00:00
console . log ( event )
2020-04-23 15:40:39 +00:00
const video = $ ( event . target ) [ 0 ] ;
2020-12-26 21:52:34 +00:00
console . log ( video )
2020-04-23 15:40:39 +00:00
const width = video . videoWidth ;
const height = video . videoHeight ;
2020-12-26 21:52:34 +00:00
console . log ( "video sizes" , width , height )
2020-04-23 15:40:39 +00:00
2020-04-27 12:57:01 +00:00
let targetWidth = videoSize . width ;
2020-12-26 21:52:34 +00:00
let targetHeight = videoSize . height ;
console . log ( "target sizes" , targetWidth , targetHeight )
2020-04-23 15:40:39 +00:00
if ( width > videoSize . width ) {
targetHeight *= videoSize . width / width
}
if ( height > targetHeight ) {
targetWidth *= targetHeight / height
}
video . width = targetWidth ;
video . height = targetHeight ;
2020-04-21 08:57:28 +00:00
}
/ * *
2020-04-27 14:38:31 +00:00
* This function is called when we disconnect . It removes the Listeners .
2020-04-21 08:57:28 +00:00
* /
function disconnect ( ) {
console . log ( 'disconnect!' ) ;
connection . removeEventListener (
JitsiMeetJS . events . connection . CONNECTION _ESTABLISHED ,
onConnectionSuccess ) ;
connection . removeEventListener (
JitsiMeetJS . events . connection . CONNECTION _DISCONNECTED ,
disconnect ) ;
}
2020-04-27 14:38:31 +00:00
/ * *
* Connects the interface to a conference room , sets up the listeners . .
* /
2020-04-28 16:23:49 +00:00
function connect ( e ) {
2020-04-28 17:13:07 +00:00
e . preventDefault ( ) ;
2020-04-27 14:38:31 +00:00
const roomName = $ ( '#room-name' ) . val ( ) ;
2020-04-27 12:57:01 +00:00
2020-12-26 16:21:36 +00:00
if ( $ ( '#use-local-video' ) . is ( ":checked" ) ) {
useLocalVideo = true
} else {
useLocalVideo = false
}
2020-12-26 20:03:14 +00:00
initHtml ( $ ( '#rows' ) . val ( ) , $ ( '#cols' ) . val ( ) )
2020-12-26 16:21:36 +00:00
2020-04-27 12:57:01 +00:00
room = connection . initJitsiConference ( roomName , confOptions ) ;
room . setDisplayName ( "Streamer" ) ;
room . on ( JitsiMeetJS . events . conference . TRACK _ADDED , onRemoteTrack ) ;
room . on ( JitsiMeetJS . events . conference . TRACK _REMOVED , onRemoteTrackRemove ) ;
room . on ( JitsiMeetJS . events . conference . USER _JOINED , onUserJoin ) ;
room . on ( JitsiMeetJS . events . conference . USER _LEFT , onUserLeft ) ;
2020-12-26 16:21:36 +00:00
room . on ( JitsiMeetJS . events . conference . CONFERENCE _JOINED , onConferenceJoined ) ;
2020-04-27 12:57:01 +00:00
room . on ( JitsiMeetJS . events . conference . DISPLAY _NAME _CHANGED , onNameChange ) ;
2020-04-27 14:38:31 +00:00
room . join ( $ ( '#room-password' ) . val ( ) ) ;
$ ( '#room-selector' ) . hide ( ) ;
2020-04-27 12:57:01 +00:00
$ ( '#room' ) . show ( ) ;
2020-04-27 14:38:31 +00:00
2020-04-28 22:49:45 +00:00
// initiaize fields with values
for ( let i = 0 ; i < remoteMappingName . length ; i ++ ) {
$ ( '.volume-' + i + ' input[type="text"]' ) . val ( remoteMappingName [ i ] ) ;
2020-04-28 16:35:50 +00:00
$ ( '.volume-' + i + ' input[type="range"]' ) . val ( 0.7 ) ;
2020-04-28 22:49:45 +00:00
$ ( '.video-' + i + ' video' ) . on ( 'resize' , onVideoResize ) . width ( videoSize . width ) . height ( videoSize . height ) ;
$ ( '.video-' + i + ' span' ) . text ( remoteMappingName [ i ] ) ;
2020-04-27 14:38:31 +00:00
}
2020-04-27 12:57:01 +00:00
}
2020-12-26 16:21:36 +00:00
function onConferenceJoined ( ) {
isJoined = true ;
for ( let i = 0 ; i < localTracks . length ; i ++ ) {
addLocalTrack ( localTracks [ i ] ) ;
}
}
2020-04-21 08:57:28 +00:00
/ * *
2020-04-27 14:38:31 +00:00
* Disconnects everything
2020-04-21 08:57:28 +00:00
* /
function unload ( ) {
room . leave ( ) ;
connection . disconnect ( ) ;
2020-12-26 20:03:41 +00:00
return null ;
2020-04-21 08:57:28 +00:00
}
2020-04-27 14:38:31 +00:00
/ * *
* Sets the Outputlevel of an audio source
* @ param id
* @ param level
* /
2020-04-23 15:40:39 +00:00
function setLevel ( id , level ) {
2020-04-28 22:29:29 +00:00
if ( id < remoteMappingName . length ) {
let track = $ ( ` .video- ${ id } audio ` ) [ 0 ] ;
$ ( '.volume-' + id + ' .volume' ) . text ( Math . round ( level * 100 ) + "%" ) ;
$ ( '.volume-' + id + ' input[type="range"]' ) . val ( level ) ;
track . volume = level ;
2020-04-28 13:42:06 +00:00
}
}
2020-04-27 14:38:31 +00:00
/ * *
* Sets the name of a position
* @ param position
* @ param name
* /
2020-04-27 12:57:01 +00:00
function setName ( position , name ) {
2020-04-29 00:18:48 +00:00
name = name . toLowerCase ( ) ;
2020-04-27 12:57:01 +00:00
console . log ( ` setting name of ${ position } to ${ name } ` ) ;
2020-04-29 00:18:48 +00:00
remoteMappingName [ position ] = name ;
2020-04-28 16:35:50 +00:00
$ ( '.video-' + position + ' .name' ) . text ( name ) ;
2020-04-28 22:29:29 +00:00
for ( let i in tracks ) {
if ( tracks . hasOwnProperty ( i ) && tracks [ i ] . position === position ) {
2020-04-27 14:38:31 +00:00
detachUser ( i ) ;
break ;
2020-04-27 12:57:01 +00:00
}
}
2020-04-28 18:07:25 +00:00
let participants = room . getParticipants ( ) ;
for ( let i = 0 ; i < participants . length ; i ++ ) {
2020-04-29 18:45:20 +00:00
if ( participants [ i ] . getDisplayName ( ) && participants [ i ] . getDisplayName ( ) . toLowerCase ( ) === name ) {
2020-04-28 18:07:25 +00:00
attachUser ( participants [ i ] . getId ( ) , position ) ;
break ;
}
2020-04-27 12:57:01 +00:00
}
2020-04-28 22:49:45 +00:00
selectParticipants ( ) ;
window . localStorage . setItem ( 'remoteMappingName' , JSON . stringify ( remoteMappingName ) ) ;
}
function reload ( position ) {
for ( let i in tracks ) {
if ( tracks . hasOwnProperty ( i ) && tracks [ i ] . position === position ) {
2020-04-29 00:16:15 +00:00
detachUser ( i ) ;
2020-04-28 22:49:45 +00:00
attachUser ( i , position ) ;
}
}
2020-04-27 12:57:01 +00:00
}
2020-04-28 18:07:25 +00:00
2020-04-29 00:27:31 +00:00
function leave ( ) {
room . leave ( ) ;
2020-12-26 16:21:36 +00:00
isJoined = false ;
2020-04-29 00:27:31 +00:00
$ ( '#room' ) . hide ( ) ;
$ ( '#room-selector' ) . show ( ) ;
2020-12-26 18:13:45 +00:00
for ( let i in localTracks ) {
room . removeTrack ( localTracks [ i ] ) ;
}
2020-04-29 00:27:31 +00:00
}
2020-12-26 20:19:59 +00:00
function toggleMute ( ) {
let audioElems = $ ( "audio" ) ;
muted = ! muted ;
audioElems . prop ( "muted" , muted )
if ( muted ) {
$ ( '#muted-status' ) . text ( "Muted" )
} else {
$ ( '#muted-status' ) . text ( "Unmuted" )
}
}
2020-04-28 18:07:25 +00:00
function updateParticipantList ( ) {
2020-04-29 19:03:22 +00:00
$ ( '.available-users' ) . text ( room . getParticipants ( ) . map ( p => p . getDisplayName ( ) || 'Fellow Jitster' ) . join ( ', ' ) ) ;
2020-04-28 18:07:25 +00:00
}
2020-04-21 08:57:28 +00:00
/ * *
2020-04-27 14:38:31 +00:00
* Sets the output to the selected outputsource
2020-04-21 08:57:28 +00:00
* @ param selected
* /
function changeAudioOutput ( selected ) { // eslint-disable-line no-unused-vars
JitsiMeetJS . mediaDevices . setAudioOutputDevice ( selected . value ) ;
}
2020-12-26 20:03:41 +00:00
window . onbeforeunload = unload ;
2020-04-21 08:57:28 +00:00
2020-05-02 11:50:58 +00:00
JitsiMeetJS . setLogLevel ( JitsiMeetJS . logLevels . WARN ) ;
2020-04-21 08:57:28 +00:00
2020-04-27 14:38:31 +00:00
JitsiMeetJS . init ( { } ) ;
2020-04-21 08:57:28 +00:00
connection = new JitsiMeetJS . JitsiConnection ( null , null , options ) ;
connection . addEventListener (
JitsiMeetJS . events . connection . CONNECTION _ESTABLISHED ,
onConnectionSuccess ) ;
connection . addEventListener (
JitsiMeetJS . events . connection . CONNECTION _DISCONNECTED ,
disconnect ) ;
connection . connect ( ) ;
if ( JitsiMeetJS . mediaDevices . isDeviceChangeAvailable ( 'output' ) ) {
JitsiMeetJS . mediaDevices . enumerateDevices ( devices => {
const audioOutputDevices
= devices . filter ( d => d . kind === 'audiooutput' ) ;
if ( audioOutputDevices . length > 1 ) {
$ ( '#audioOutputSelect' ) . html (
audioOutputDevices
. map (
d =>
` <option value=" ${ d . deviceId } "> ${ d . label } </option> ` )
. join ( '\n' ) ) ;
$ ( '#audioOutputSelectWrapper' ) . show ( ) ;
}
} ) ;
}
2020-04-28 22:49:45 +00:00
if ( window . localStorage . getItem ( 'remoteMappingName' ) !== null ) {
remoteMappingName = JSON . parse ( window . localStorage . getItem ( 'remoteMappingName' ) ) ;
}
2020-12-26 16:21:36 +00:00
let localTracks = [ ] ;
function onLocalTracks ( tracks ) {
localTracks = tracks ;
for ( let i = 0 ; i < localTracks . length ; i ++ ) {
if ( localTracks [ i ] . getType ( ) === 'video' ) {
localTracks [ i ] . attach ( $ ( ` #localVideo ` ) [ 0 ] ) ;
}
if ( isJoined ) {
addLocalTrack ( localTracks [ i ] ) ;
}
}
}
2020-12-26 22:44:58 +00:00
let camera = "" ;
navigator . mediaDevices . enumerateDevices ( )
. then ( function ( devices ) {
devices . forEach ( function ( device ) {
console . log ( device . kind + ": " + device . label +
" id = " + device . deviceId ) ;
if ( device . label . indexOf ( "NDI" ) != - 1 ) {
camera = device . deviceId ;
}
} ) ;
} )
. catch ( function ( err ) {
console . log ( err . name + ": " + err . message ) ;
} ) ;
2020-12-26 16:21:36 +00:00
2020-12-26 22:44:58 +00:00
JitsiMeetJS . createLocalTracks ( { devices : [ 'video' ] , cameraDeviceId : camera } )
2020-12-26 16:21:36 +00:00
. then ( onLocalTracks )
. catch ( error => {
throw error ;
} ) ;
function addLocalTrack ( track ) {
if ( useLocalVideo ) {
room . addTrack ( track ) ;
}
2020-12-26 22:44:58 +00:00
}