janusweb 1.5.50 → 1.5.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/janusweb.css +7 -0
- package/media/assets/webui/apps/avatar/avatar.js +49 -15
- package/media/assets/webui/apps/comms/comms.js +12 -1
- package/media/assets/webui/apps/comms/external/naf-shim.js +7 -2
- package/media/assets/webui/apps/comms/status.html +2 -2
- package/media/assets/webui/apps/comms/voip.css +53 -8
- package/media/assets/webui/apps/comms/voip.js +193 -77
- package/media/assets/webui/apps/editor/editor.css +5 -0
- package/media/assets/webui/apps/editor/editor.js +12 -1
- package/media/assets/webui/apps/locomotion/teleporter.js +4 -3
- package/media/assets/webui/apps/settings/settings.js +1 -1
- package/media/assets/webui/themes/default.css +93 -2
- package/package.json +1 -1
- package/scripts/client.js +42 -19
- package/scripts/elements/linesegments.js +1 -1
- package/scripts/external/JanusClientConnection.js +5 -2
- package/scripts/external/JanusFireboxParser.js +1 -0
- package/scripts/janusbase.js +8 -1
- package/scripts/janusghost.js +15 -25
- package/scripts/januslight.js +4 -1
- package/scripts/janusparticle.js +1 -0
- package/scripts/janusplayer.js +47 -20
- package/scripts/multiplayermanager.js +2 -0
- package/scripts/object.js +2 -2
- package/scripts/parts.js +5 -1
- package/scripts/portal.js +1 -0
- package/scripts/room.js +45 -5
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
let sfus = {};
|
|
3
|
+
|
|
1
4
|
elation.elements.define('janus-voip-client', class extends elation.elements.base {
|
|
5
|
+
init() {
|
|
6
|
+
super.init();
|
|
7
|
+
this.defineAttribute('spatialized', { type: 'boolean', default: false, set: this.updateSpatialization });
|
|
8
|
+
}
|
|
2
9
|
create() {
|
|
3
10
|
this.localuser = document.createElement('janus-voip-localuser');
|
|
4
11
|
this.appendChild(this.localuser);
|
|
@@ -10,7 +17,6 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
|
|
|
10
17
|
let datapath = elation.config.get('janusweb.datapath', '/media/janusweb'),
|
|
11
18
|
assetpath = datapath + 'assets/webui/apps/comms/';
|
|
12
19
|
|
|
13
|
-
|
|
14
20
|
janus.assetpack.loadJSON([
|
|
15
21
|
{ "assettype":"sound", "name":"voip_ui_enter", "src":"assets/webui/apps/comms/sounds/ui_casual_pops_confirm.wav" },
|
|
16
22
|
{ "assettype":"sound", "name":"voip_ui_mic", "src":"assets/webui/apps/comms/sounds/ui_casual_pops_back.wav" },
|
|
@@ -20,7 +26,7 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
|
|
|
20
26
|
elation.events.add(janus._target, 'room_change', (ev) => {
|
|
21
27
|
if (!room.loaded) {
|
|
22
28
|
room.addEventListener('room_load_processed', async () => {
|
|
23
|
-
console.log('changed room', room.voipid, ev);
|
|
29
|
+
console.log('[voip-client] changed room', room.voipid, ev);
|
|
24
30
|
this.setRoom(room);
|
|
25
31
|
});
|
|
26
32
|
} else {
|
|
@@ -44,14 +50,16 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
|
|
|
44
50
|
let roomid = newroom.voipid || newroom.id;
|
|
45
51
|
|
|
46
52
|
if (this.currentroom) { // && this.rooms[roomid] !== this.currentroom) {
|
|
53
|
+
console.log('[voip-client] setRoom called, disconnect from existing room', this.currentroom);
|
|
47
54
|
if (this.currentroom.disconnect) {
|
|
48
|
-
this.currentroom.disconnect();
|
|
55
|
+
//this.currentroom.disconnect();
|
|
56
|
+
this.currentroom.leave();
|
|
49
57
|
}
|
|
50
58
|
this.removeChild(this.currentroom);
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
if (newroom.private) {
|
|
54
|
-
console.log('Room is private, don\'t connect to VOIP server');
|
|
62
|
+
console.log('[voip-client] Room is private, don\'t connect to VOIP server');
|
|
55
63
|
this.currentroom = false;
|
|
56
64
|
return;
|
|
57
65
|
}
|
|
@@ -62,6 +70,7 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
|
|
|
62
70
|
append: this,
|
|
63
71
|
roomid: roomid,
|
|
64
72
|
});
|
|
73
|
+
console.log('[voip-client] create new voip-client', voiptype, roomid, this.rooms[roomid]);
|
|
65
74
|
|
|
66
75
|
if (this.inputstream) {
|
|
67
76
|
this.rooms[roomid].setInputStream(this.inputstream);
|
|
@@ -72,6 +81,7 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
|
|
|
72
81
|
elation.events.fire({type: 'init', element: this});
|
|
73
82
|
});
|
|
74
83
|
} else {
|
|
84
|
+
console.log('[voip-client] voip client for room already exists', roomid, this.rooms[roomid]);
|
|
75
85
|
this.appendChild(this.rooms[roomid]);
|
|
76
86
|
this.rooms[roomid].connect();
|
|
77
87
|
}
|
|
@@ -85,7 +95,6 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
|
|
|
85
95
|
this.localuser.setData(null);
|
|
86
96
|
}
|
|
87
97
|
handleUserChat(ev) {
|
|
88
|
-
console.log('got a chat', ev.data);
|
|
89
98
|
let msg = ev.data.message;
|
|
90
99
|
let m = msg.data.match(/📞 (.*$)/);
|
|
91
100
|
if (m) {
|
|
@@ -99,55 +108,103 @@ elation.elements.define('janus-voip-client', class extends elation.elements.base
|
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
}
|
|
111
|
+
updateSpatialization() {
|
|
112
|
+
if (this.spatialized) {
|
|
113
|
+
requestAnimationFrame(() => this.spatialize());
|
|
114
|
+
} else {
|
|
115
|
+
remoteusers.forEach(user => {
|
|
116
|
+
if (user.spatialized) user.spatialized = false;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
spatialize() {
|
|
121
|
+
let remoteusers = this.querySelectorAll('janus-voip-remoteuser');
|
|
122
|
+
remoteusers.forEach(user => {
|
|
123
|
+
if (!user.spatialized) user.spatialized = true;
|
|
124
|
+
user.spatialize();
|
|
125
|
+
});
|
|
126
|
+
if (this.spatialized) {
|
|
127
|
+
requestAnimationFrame(() => this.spatialize());
|
|
128
|
+
}
|
|
129
|
+
}
|
|
102
130
|
});
|
|
103
131
|
elation.elements.define('janus-voip-client-janus', class extends elation.elements.base {
|
|
132
|
+
init() {
|
|
133
|
+
super.init();
|
|
134
|
+
this.defineAttribute('roomid', { type: 'string' });
|
|
135
|
+
}
|
|
104
136
|
create() {
|
|
105
137
|
this.connect();
|
|
106
138
|
}
|
|
107
139
|
connect() {
|
|
108
140
|
if (typeof NAF != 'undefined' && !('janus' in NAF.adapters.adapters)) {
|
|
109
|
-
console.log('NAF adapter not found, load it');
|
|
141
|
+
console.log('[voip-client-janus] NAF adapter not found, load it');
|
|
110
142
|
elation.file.get('js', janus.ui.apps.default.apps.comms.resolveFullURL('./external/naf-janus-adapter.js'), (ev) => {
|
|
143
|
+
console.log('[voip-client-janus] NAF adapter loaded, continue');
|
|
111
144
|
this.connect();
|
|
112
145
|
});
|
|
113
146
|
return;
|
|
114
147
|
}
|
|
115
|
-
let sfu = new JanusNAF(player.getNetworkUsername()); //'testclient-' + Math.floor(Math.random() * 1e6));
|
|
116
|
-
this.sfu = sfu;
|
|
117
148
|
|
|
118
149
|
let voipserver = room.voipserver || 'voip.janusxr.org';
|
|
119
150
|
|
|
120
|
-
|
|
151
|
+
let roomid = this.roomid || room.voipid || room.url;
|
|
152
|
+
let sfu = sfus[voipserver];
|
|
153
|
+
if (!sfu) {
|
|
154
|
+
sfu = new JanusNAF(player.getNetworkUsername()); //'testclient-' + Math.floor(Math.random() * 1e6));
|
|
155
|
+
sfu.connect('wss://' + voipserver + '/', 'default', roomid, true);
|
|
156
|
+
sfus[voipserver] = sfu;
|
|
157
|
+
} else {
|
|
158
|
+
sfu.setRoom(roomid);
|
|
159
|
+
}
|
|
160
|
+
this.sfu = sfu;
|
|
161
|
+
|
|
121
162
|
|
|
122
163
|
this.localuser = this.parentNode.localuser;
|
|
123
164
|
//this.localuser = document.createElement('janus-voip-localuser');
|
|
124
165
|
//this.appendChild(this.localuser);
|
|
125
166
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
sfu.
|
|
149
|
-
|
|
150
|
-
|
|
167
|
+
if (!this.remoteusers) {
|
|
168
|
+
this.remoteusers = {};
|
|
169
|
+
}
|
|
170
|
+
let remoteusers = this.remoteusers;
|
|
171
|
+
if (!this.sfueventsregistered) {
|
|
172
|
+
sfu.addEventListener('voip-media-change', (ev) => {
|
|
173
|
+
console.log('[voip-client-janus] got some media', ev.detail);
|
|
174
|
+
this.localuser.setData(ev.detail.stream);
|
|
175
|
+
});
|
|
176
|
+
sfu.addEventListener('voip-user-connect', (ev) => {
|
|
177
|
+
console.log('[voip-client-janus] user connected', ev);
|
|
178
|
+
if (!this.remoteusers[ev.detail.id]) {
|
|
179
|
+
let el = document.createElement('janus-voip-remoteuser');
|
|
180
|
+
el.setUserData(ev.detail);
|
|
181
|
+
this.appendChild(el);
|
|
182
|
+
this.remoteusers[ev.detail.id] = el;
|
|
183
|
+
} else {
|
|
184
|
+
let el = this.remoteusers[ev.detail.id];
|
|
185
|
+
el.setUserData(ev.detail);
|
|
186
|
+
this.appendChild(el);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
sfu.addEventListener('voip-user-disconnect', (ev) => {
|
|
190
|
+
console.log('[voip-client-janus] user disconnected', ev);
|
|
191
|
+
let userid = ev.detail.id,
|
|
192
|
+
user = remoteusers[userid];
|
|
193
|
+
if (user) {
|
|
194
|
+
user.destroy();
|
|
195
|
+
setTimeout(() => { if (user.parentNode === this) this.removeChild(user); }, 250);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
document.addEventListener('voip-picker-select', ev => {
|
|
199
|
+
let localStream = ev.detail;
|
|
200
|
+
if (localStream) {
|
|
201
|
+
sfu.adapter.setLocalMediaStream(localStream);
|
|
202
|
+
}
|
|
203
|
+
sfu.dispatchEvent(new CustomEvent('voip-media-change', {detail: { stream: localStream }}));
|
|
204
|
+
});
|
|
205
|
+
elation.events.add(player._target, 'username_change', (ev) => this.handleUsernameChange(ev));
|
|
206
|
+
this.sfueventsregistered = true;
|
|
207
|
+
}
|
|
151
208
|
if (this.inputstream) {
|
|
152
209
|
sfu.adapter.setLocalMediaStream(this.inputstream);
|
|
153
210
|
}
|
|
@@ -186,7 +243,6 @@ console.log('leave room and remove all occupants', this.room);
|
|
|
186
243
|
});
|
|
187
244
|
*/
|
|
188
245
|
// FIXME - player proxy should expose .addEventListener()
|
|
189
|
-
elation.events.add(player._target, 'username_change', (ev) => this.handleUsernameChange(ev));
|
|
190
246
|
elation.events.fire({type: 'init', element: this});
|
|
191
247
|
}
|
|
192
248
|
disconnect() {
|
|
@@ -194,12 +250,17 @@ console.log('leave room and remove all occupants', this.room);
|
|
|
194
250
|
this.sfu.adapter.disconnect();
|
|
195
251
|
}
|
|
196
252
|
}
|
|
253
|
+
leave() {
|
|
254
|
+
if (this.sfu && this.sfu.adapter && this.sfu.adapter.publisher) {
|
|
255
|
+
this.sfu.adapter.sendLeave(this.sfu.adapter.publisher.handle);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
197
258
|
initRoom(room) {
|
|
198
259
|
let sfu = this.sfu;
|
|
199
260
|
if (!room.private) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
sfu.adapter.
|
|
261
|
+
let roomid = room.voipid || room.url;
|
|
262
|
+
sfu.setRoom(roomid)
|
|
263
|
+
console.log('[voip-client-janus] room is now', sfu.adapter.room);
|
|
203
264
|
/*
|
|
204
265
|
let handle = sfu.adapter.publisher.handle;
|
|
205
266
|
sfu.adapter.sendJoin(handle, {
|
|
@@ -208,7 +269,7 @@ console.log('leave room and remove all occupants', this.room);
|
|
|
208
269
|
});
|
|
209
270
|
*/
|
|
210
271
|
} else {
|
|
211
|
-
console.log('new room is private, disconnect');
|
|
272
|
+
console.log('[voip-client-janus] new room is private, disconnect');
|
|
212
273
|
setTimeout(() => {
|
|
213
274
|
sfu.adapter.disconnect();
|
|
214
275
|
}, 0);
|
|
@@ -220,7 +281,9 @@ console.log('leave room and remove all occupants', this.room);
|
|
|
220
281
|
setInputStream(stream) {
|
|
221
282
|
if (this.sfu) {
|
|
222
283
|
this.inputstream = stream;
|
|
223
|
-
|
|
284
|
+
if (stream) {
|
|
285
|
+
this.sfu.adapter.setLocalMediaStream(stream);
|
|
286
|
+
}
|
|
224
287
|
} else {
|
|
225
288
|
this.connect();
|
|
226
289
|
}
|
|
@@ -445,7 +508,7 @@ elation.elements.define('janus-voip-localuser', class extends elation.elements.b
|
|
|
445
508
|
video.srcObject = data;
|
|
446
509
|
this.appendChild(video);
|
|
447
510
|
video.muted = true;
|
|
448
|
-
video.play().then(() => console.log('playing', video)).catch(e => console.log('Failed to start video', e, video));
|
|
511
|
+
video.play().then(() => console.log('[voip-localuser] playing', video)).catch(e => console.log('[voip-localuser] Failed to start video', e, video));
|
|
449
512
|
this.video = video;
|
|
450
513
|
}
|
|
451
514
|
|
|
@@ -544,53 +607,85 @@ elation.elements.define('janus-voip-remoteuser', class extends elation.elements.
|
|
|
544
607
|
create() {
|
|
545
608
|
this.defineAttributes({
|
|
546
609
|
'muted': { type: 'boolean', default: false },
|
|
610
|
+
'active': { type: 'boolean', default: false },
|
|
547
611
|
'hasaudio': { type: 'boolean', default: false },
|
|
548
612
|
'hasvideo': { type: 'boolean', default: false },
|
|
549
613
|
'averagevolume': { type: 'float', default: 0 },
|
|
550
614
|
'speaking': { type: 'boolean', default: false },
|
|
551
615
|
'threshold': { type: 'float', default: .2 },
|
|
616
|
+
'spatialized': { type: 'bool', default: false },
|
|
552
617
|
});
|
|
553
618
|
this.lastposition = V();
|
|
554
|
-
setTimeout(() => this.setAttribute('active', true), 100);
|
|
555
619
|
}
|
|
556
620
|
setUserData(data) {
|
|
621
|
+
if (!this.created) {
|
|
622
|
+
setTimeout(() => this.setUserData(data), 10);
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
557
625
|
this.id = data.id;
|
|
558
|
-
console.log('got a remote voip user', data);
|
|
626
|
+
console.log('[voip-remoteuser] got a remote voip user', data);
|
|
627
|
+
this.active = true;
|
|
559
628
|
|
|
560
629
|
if (!this.label) {
|
|
561
630
|
let label = document.createElement('h2');
|
|
562
|
-
label.innerText = this.id;
|
|
563
631
|
this.appendChild(label);
|
|
564
632
|
this.label = label;
|
|
565
633
|
}
|
|
634
|
+
this.label.innerText = this.id;
|
|
566
635
|
|
|
567
636
|
if (data.media.video) {
|
|
568
637
|
let track = data.media.video.getVideoTracks()[0];
|
|
569
|
-
data.media.video.addEventListener('addtrack', (ev) => console.log('a track was added', ev));
|
|
570
|
-
data.media.video.addEventListener('removetrack', (ev) => console.log('a track was
|
|
571
|
-
let video =
|
|
638
|
+
data.media.video.addEventListener('addtrack', (ev) => console.log('[voip-remoteuser] a track was added', ev));
|
|
639
|
+
data.media.video.addEventListener('removetrack', (ev) => console.log('[voip-remoteuser] a track was removed', ev));
|
|
640
|
+
let video = this.video;
|
|
641
|
+
if (!video) {
|
|
642
|
+
video = document.createElement('video');
|
|
643
|
+
video.addEventListener('resize', (ev) => { console.log('[voip-remoteuser] video resized', video.videoWidth, video.videoHeight, video, this); this.updateVideo(); });
|
|
644
|
+
}
|
|
572
645
|
video.muted = true;
|
|
573
646
|
video.srcObject = data.media.video;
|
|
574
647
|
this.appendChild(video);
|
|
575
|
-
console.log('remote user call play', video);
|
|
648
|
+
console.log('[voip-remoteuser] remote user call play', video);
|
|
576
649
|
video.play()
|
|
577
|
-
.then(() => {
|
|
578
|
-
|
|
650
|
+
.then(() => {
|
|
651
|
+
console.log('[voip-remoteuser] remote user video playing', video, this);
|
|
652
|
+
this.updateVideo();
|
|
653
|
+
|
|
654
|
+
let frametimer = false;
|
|
655
|
+
let detectStoppedVideo = (frame) => {
|
|
656
|
+
video.requestVideoFrameCallback(detectStoppedVideo);
|
|
657
|
+
if (frametimer) clearTimeout(frametimer);
|
|
658
|
+
frametimer = setTimeout(() => {
|
|
659
|
+
// FIXME - when video stops, we still display the last frame indefinitely. The below code clears the video frame,
|
|
660
|
+
// but prevents video from resuming if the remote player reenables their camera
|
|
661
|
+
//video.srcObject = new MediaStream(video.srcObject.getAudioTracks());
|
|
662
|
+
this.hasvideo = false;
|
|
663
|
+
}, 2000);
|
|
664
|
+
if (frame && !this.hasvideo) {
|
|
665
|
+
this.hasvideo = true;
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
detectStoppedVideo(false);
|
|
669
|
+
})
|
|
670
|
+
.catch(e => { console.log('[voip-remoteuser] failed to play remote video', video, e, this); });
|
|
579
671
|
this.video = video;
|
|
580
|
-
|
|
581
|
-
this.updateVideo();
|
|
582
|
-
this.hasvideo = true;
|
|
672
|
+
//this.hasvideo = true;
|
|
583
673
|
} else {
|
|
584
|
-
this.hasvideo = false;
|
|
674
|
+
//this.hasvideo = false;
|
|
585
675
|
}
|
|
586
676
|
|
|
587
677
|
// audio
|
|
588
678
|
if (data.media.audio) {
|
|
589
|
-
let audio = document.createElement('audio');
|
|
679
|
+
let audio = this.audio || document.createElement('audio');
|
|
590
680
|
audio.srcObject = data.media.audio;
|
|
591
681
|
this.audio = audio;
|
|
592
682
|
this.appendChild(audio);
|
|
593
|
-
|
|
683
|
+
|
|
684
|
+
audio.play()
|
|
685
|
+
.then(() => {
|
|
686
|
+
console.log('[voip-remoteuser] remote user audio playing', audio, this);
|
|
687
|
+
this.hasaudio = true;
|
|
688
|
+
});
|
|
594
689
|
|
|
595
690
|
let listener = player.engine.systems.sound.getRealListener();
|
|
596
691
|
let context = listener.context;
|
|
@@ -620,7 +715,7 @@ console.log('got a remote voip user', data);
|
|
|
620
715
|
let remoteuser = janus.network.remoteplayers[this.id];
|
|
621
716
|
|
|
622
717
|
if (!this.controlpanel) {
|
|
623
|
-
this.controlpanel = elation.elements.create('ui-panel', { bottom:
|
|
718
|
+
this.controlpanel = elation.elements.create('ui-panel', { bottom: true, append: this });
|
|
624
719
|
this.mutebutton = elation.elements.create('ui-button', { label: 'Mute', name: "mutebutton", append: this.controlpanel });
|
|
625
720
|
this.volume = elation.elements.create('ui-slider', { name: "volume", min: 0, max: 200, value: this.video.volume * 100, append: this.controlpanel, snap: 1 });
|
|
626
721
|
|
|
@@ -699,10 +794,10 @@ console.log('got a remote voip user', data);
|
|
|
699
794
|
});
|
|
700
795
|
}
|
|
701
796
|
|
|
702
|
-
console.log('got remote media', data, remoteuser);
|
|
797
|
+
console.log('[voip-remoteuser] got remote media', data, remoteuser);
|
|
703
798
|
}
|
|
704
799
|
destroy() {
|
|
705
|
-
console.log('stop media', this.id);
|
|
800
|
+
console.log('[voip-remoteuser] stop media', this.id);
|
|
706
801
|
if (this.video) {
|
|
707
802
|
//this.video.pause();
|
|
708
803
|
}
|
|
@@ -711,7 +806,7 @@ console.log('got a remote voip user', data);
|
|
|
711
806
|
let tracks = this.audio.srcObject.getTracks();
|
|
712
807
|
//tracks.forEach(track => { console.log('stop track', track); track.stop(); });
|
|
713
808
|
}
|
|
714
|
-
this.
|
|
809
|
+
this.active = false;
|
|
715
810
|
if (this.parentNode) {
|
|
716
811
|
this.parentNode.removeChild(this);
|
|
717
812
|
}
|
|
@@ -720,18 +815,20 @@ console.log('got a remote voip user', data);
|
|
|
720
815
|
let video = this.video;
|
|
721
816
|
if (video) {
|
|
722
817
|
let hasclass = elation.html.hasclass(video, 'active');
|
|
723
|
-
if (video.videoWidth >
|
|
818
|
+
if (video.videoWidth > 2 && video.videoHeight > 2 && !hasclass) {
|
|
724
819
|
this.hasvideo = true;
|
|
725
820
|
elation.html.addclass(video, 'active');
|
|
726
|
-
} else if (hasclass && (video.videoWidth
|
|
821
|
+
} else if (hasclass && (video.videoWidth <= 2 || video.videoHeight <= 2)) {
|
|
727
822
|
this.hasvideo = false;
|
|
728
823
|
elation.html.removeclass(video, 'active');
|
|
729
824
|
}
|
|
825
|
+
} else {
|
|
826
|
+
this.hasvideo = false;
|
|
730
827
|
}
|
|
731
828
|
}
|
|
732
829
|
toggleMute() {
|
|
733
830
|
this.muted = !this.muted;
|
|
734
|
-
console.log('mute?', this.muted, this);
|
|
831
|
+
console.log('[voip-remoteuser] mute?', this.muted, this);
|
|
735
832
|
let remoteuser = janus.network.remoteplayers[this.id];
|
|
736
833
|
if (this.muted) {
|
|
737
834
|
this.mutebutton.addclass('muted');
|
|
@@ -759,14 +856,31 @@ console.log('mute?', this.muted, this);
|
|
|
759
856
|
this.colorreset = setTimeout(() => {
|
|
760
857
|
this.speaking = false;
|
|
761
858
|
this.colorreset = false;
|
|
859
|
+
this.video.style.removeProperty('box-shadow');
|
|
762
860
|
}, 200);
|
|
861
|
+
let shadowsize = 2 + (3 * this.averagevolume);
|
|
862
|
+
this.video.style.boxShadow = '0 0 2px ' + shadowsize + 'px rgba(0,255,0,.8)';
|
|
863
|
+
} else {
|
|
864
|
+
this.video.style.removeProperty('box-shadow');
|
|
763
865
|
}
|
|
866
|
+
this.hasaudio = this.averagevolume > 0;
|
|
764
867
|
|
|
765
868
|
if (this.label3d) {
|
|
766
869
|
this.label3d.setAudioVolume(this.averagevolume);
|
|
767
870
|
this.remoteuser.setSpeakingVolume(this.averagevolume);
|
|
768
871
|
}
|
|
769
872
|
}
|
|
873
|
+
spatialize() {
|
|
874
|
+
if (!this.relativepos) this.relativepos = V();
|
|
875
|
+
let remoteuser = janus.network.remoteplayers[this.id];
|
|
876
|
+
if (remoteuser) {
|
|
877
|
+
let relativepos = player.worldToLocal(remoteuser.localToWorld(this.relativepos.set(0, 0, 0)));
|
|
878
|
+
let angle = Math.PI - Math.atan2(relativepos.x, relativepos.z),
|
|
879
|
+
len = .4 * window.innerHeight;
|
|
880
|
+
this.style.top = ( window.innerHeight / 2 - len * Math.cos(angle) - (this.offsetHeight / 2)) + 'px';
|
|
881
|
+
this.style.left = (len * Math.sin(angle) + window.innerWidth / 2 - (this.offsetWidth / 2)) + 'px';
|
|
882
|
+
}
|
|
883
|
+
}
|
|
770
884
|
});
|
|
771
885
|
elation.elements.define('janus-voip-picker', class extends elation.elements.base {
|
|
772
886
|
create() {
|
|
@@ -791,10 +905,10 @@ elation.elements.define('janus-voip-picker', class extends elation.elements.base
|
|
|
791
905
|
// We should use a session cookie-based timeout in addition to the localStorage settings
|
|
792
906
|
this.handleSelectAudio({detail: 1});
|
|
793
907
|
}
|
|
794
|
-
console.log('voip picker loaded config', this.voipconfig);
|
|
908
|
+
console.log('[voip-picker] voip picker loaded config', this.voipconfig);
|
|
795
909
|
}
|
|
796
910
|
handleSelectNone() {
|
|
797
|
-
console.log('selected none');
|
|
911
|
+
console.log('[voip-picker] selected none');
|
|
798
912
|
//janus.engine.systems.sound.enableSound();
|
|
799
913
|
if (this.subpicker && this.subpicker.parentNode) {
|
|
800
914
|
this.subpicker.parentNode.removeChild(this.subpicker);
|
|
@@ -802,21 +916,23 @@ elation.elements.define('janus-voip-picker', class extends elation.elements.base
|
|
|
802
916
|
this.dispatchEvent(new CustomEvent('select', { detail: false }));
|
|
803
917
|
document.dispatchEvent(new CustomEvent('voip-picker-select', { detail: false }));
|
|
804
918
|
player.setSetting('voip', false);
|
|
805
|
-
this.subpicker
|
|
919
|
+
if (this.subpicker) {
|
|
920
|
+
this.subpicker.stopUserMedia();
|
|
921
|
+
}
|
|
806
922
|
if (!this.elements.none.active) this.elements.none.activate();
|
|
807
923
|
this.elements.audio.deactivate();
|
|
808
924
|
}
|
|
809
925
|
handleSelectAudio(ev) {
|
|
810
|
-
console.log('selected audio', ev.detail, this.voipconfig);
|
|
926
|
+
console.log('[voip-picker] selected audio', ev.detail, this.voipconfig);
|
|
811
927
|
//janus.engine.systems.sound.enableSound();
|
|
812
928
|
if (!this.subpicker) {
|
|
813
929
|
this.subpicker = elation.elements.create('janus-voip-picker-audio', { config: (this.voipconfig ? JSON.stringify(this.voipconfig) : false), showvideo: this.showvideo });
|
|
814
930
|
elation.events.add(this.subpicker, 'select', ev => {
|
|
815
|
-
console.log('SELECTED', ev.detail);
|
|
931
|
+
console.log('[voip-picker] SELECTED', ev.detail);
|
|
816
932
|
document.dispatchEvent(new CustomEvent('voip-picker-select', { detail: ev.detail }));
|
|
817
933
|
this.dispatchEvent(new CustomEvent('select', { detail: ev.detail }));
|
|
818
934
|
let voipsettings = this.subpicker.getSettings();
|
|
819
|
-
console.log('update voip settings', voipsettings);
|
|
935
|
+
console.log('[voip-picker] update voip settings', voipsettings);
|
|
820
936
|
player.setSetting('voip', voipsettings);
|
|
821
937
|
});
|
|
822
938
|
}
|
|
@@ -826,7 +942,7 @@ console.log('SELECTED', ev.detail);
|
|
|
826
942
|
this.elements.none.deactivate();
|
|
827
943
|
}
|
|
828
944
|
handleSelectVideo() {
|
|
829
|
-
console.log('selected video');
|
|
945
|
+
console.log('[voip-picker] selected video');
|
|
830
946
|
this.dispatchEvent(new CustomEvent('select', { detail: 'video' }));
|
|
831
947
|
}
|
|
832
948
|
});
|
|
@@ -871,7 +987,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
871
987
|
this.elements = elation.elements.fromString(tplstr, this);
|
|
872
988
|
|
|
873
989
|
if (this.config) {
|
|
874
|
-
console.log('I have a config!', this.config);
|
|
990
|
+
console.log('[voip-picker-audio] I have a config!', this.config);
|
|
875
991
|
this.setSettings(JSON.parse(this.config));
|
|
876
992
|
}
|
|
877
993
|
|
|
@@ -894,7 +1010,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
894
1010
|
this.updateButton();
|
|
895
1011
|
});
|
|
896
1012
|
elation.events.add(this.elements.webcamEnabled, 'toggle', (ev) => {
|
|
897
|
-
console.log('toggled', ev.data, ev);
|
|
1013
|
+
console.log('[voip-picker-audio] toggled', ev.data, ev);
|
|
898
1014
|
if (ev.data) {
|
|
899
1015
|
this.getUserMedia({video: true});
|
|
900
1016
|
}
|
|
@@ -946,7 +1062,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
946
1062
|
this.elements.webcamEnabled.hide();
|
|
947
1063
|
this.elements.videoDevice.show();
|
|
948
1064
|
} else {
|
|
949
|
-
console.log('NO WEBCAM PERMISSION');
|
|
1065
|
+
console.log('[voip-picker-audio] NO WEBCAM PERMISSION');
|
|
950
1066
|
this.elements.webcamEnabled.show();
|
|
951
1067
|
this.elements.videoDevice.hide();
|
|
952
1068
|
}
|
|
@@ -978,11 +1094,11 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
978
1094
|
constraints.audio.autoGainControl = { ideal: false };
|
|
979
1095
|
|
|
980
1096
|
if (this.elements.inputDevice.value && this.elements.inputDevice.value != 'default') {
|
|
981
|
-
console.log('input!', this.elements.inputDevice.value);
|
|
1097
|
+
console.log('[voip-picker-audio] input!', this.elements.inputDevice.value);
|
|
982
1098
|
constraints.audio.deviceId = { ideal: this.elements.inputDevice.value };
|
|
983
1099
|
}
|
|
984
1100
|
if (this.elements.videoDevice && this.elements.videoDevice.value && this.elements.videoDevice.value != 'none') {
|
|
985
|
-
console.log('video!', this.elements.videoDevice.value);
|
|
1101
|
+
console.log('[voip-picker-audio] video!', this.elements.videoDevice.value);
|
|
986
1102
|
constraints.video = {
|
|
987
1103
|
deviceId: { ideal: this.elements.videoDevice.value },
|
|
988
1104
|
height: 256,
|
|
@@ -1023,7 +1139,7 @@ elation.elements.define('janus-voip-picker-audio', class extends elation.element
|
|
|
1023
1139
|
this.elements.error.hide();
|
|
1024
1140
|
this.updateButton();
|
|
1025
1141
|
}).catch(err => {
|
|
1026
|
-
console.log('OH NO!', err);
|
|
1142
|
+
console.log('[voip-picker-audio] OH NO!', err);
|
|
1027
1143
|
this.elements.error.innerHTML = err;
|
|
1028
1144
|
this.elements.error.show();
|
|
1029
1145
|
});
|
|
@@ -1212,7 +1328,7 @@ elation.elements.define('janus-voip-picker-videotest', class extends elation.ele
|
|
|
1212
1328
|
}
|
|
1213
1329
|
video.srcObject = stream;
|
|
1214
1330
|
video.muted = true;
|
|
1215
|
-
video.play().then(() => console.log('playing', video));
|
|
1331
|
+
video.play().then(() => console.log('[voip-picker-videotest] playing', video));
|
|
1216
1332
|
} else if (video && video.parentNode) {
|
|
1217
1333
|
video.parentNode.removeChild(video);
|
|
1218
1334
|
}
|
|
@@ -656,6 +656,7 @@ console.log('set translation snap', ev.data, ev);
|
|
|
656
656
|
}
|
|
657
657
|
editObjectUpdate() {
|
|
658
658
|
var obj = this.roomedit.object;
|
|
659
|
+
if (!obj) return;
|
|
659
660
|
var bbox = this.roomedit.objectBoundingBox;
|
|
660
661
|
|
|
661
662
|
var point = this.roomedit.objectPosition || this.roomedit.object.position;
|
|
@@ -1627,6 +1628,11 @@ elation.elements.define('janus.ui.editor.source', class extends elation.elements
|
|
|
1627
1628
|
//let roomtab = elation.elements.create('ui-tab', { append: this.tabs, label: 'Room Markup' });
|
|
1628
1629
|
let roomedit = elation.elements.create('janus-ui-editor-source-file', { append: this.tabs, label: 'Room Markup', source: room.getRoomSource(), hints: this.jmlhints });
|
|
1629
1630
|
|
|
1631
|
+
let refreshbutton = elation.elements.create('ui-button', { append: this, label: '↻', title: "Refresh room source", name: "refresh" });
|
|
1632
|
+
refreshbutton.addEventListener('click', ev => {
|
|
1633
|
+
roomedit.source = room.getRoomSource();
|
|
1634
|
+
});
|
|
1635
|
+
|
|
1630
1636
|
if (room.roomassets.script) {
|
|
1631
1637
|
for (let k in room.roomassets.script) {
|
|
1632
1638
|
let scriptasset = room.roomassets.script[k];
|
|
@@ -1880,7 +1886,7 @@ elation.elements.define('janus.ui.editor.source.file', class extends elation.ele
|
|
|
1880
1886
|
init() {
|
|
1881
1887
|
super.init();
|
|
1882
1888
|
this.defineAttributes({
|
|
1883
|
-
source: { type: 'string' },
|
|
1889
|
+
source: { type: 'string', set: this.updateSource },
|
|
1884
1890
|
filename: { type: 'string', default: 'New File' },
|
|
1885
1891
|
mode: { type: 'string', default: 'xml' },
|
|
1886
1892
|
hints: { type: 'object' },
|
|
@@ -1984,6 +1990,11 @@ console.log('editor hints', this.hints);
|
|
|
1984
1990
|
this.updatetimer = false;
|
|
1985
1991
|
}, 500);
|
|
1986
1992
|
}
|
|
1993
|
+
updateSource() {
|
|
1994
|
+
if (this.source != this.codemirror.getValue()) {
|
|
1995
|
+
this.codemirror.setValue(this.source);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1987
1998
|
});
|
|
1988
1999
|
|
|
1989
2000
|
class ColorTransform extends THREE.Object3D {
|
|
@@ -18,7 +18,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
18
18
|
shadow: false,
|
|
19
19
|
shadow_cast: false,
|
|
20
20
|
shadow_receive: false,
|
|
21
|
-
renderorder:
|
|
21
|
+
renderorder: 501,
|
|
22
22
|
depth_test: false,
|
|
23
23
|
depth_write: false,
|
|
24
24
|
});
|
|
@@ -29,9 +29,10 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
29
29
|
collidable: false,
|
|
30
30
|
pickable: false,
|
|
31
31
|
shadow: false,
|
|
32
|
+
opacity: .1,
|
|
32
33
|
shadow_cast: false,
|
|
33
34
|
shadow_receive: false,
|
|
34
|
-
renderorder:
|
|
35
|
+
renderorder: 500,
|
|
35
36
|
});
|
|
36
37
|
this.pointer = this.marker.createObject('Object', {
|
|
37
38
|
id: 'pyramid',
|
|
@@ -44,7 +45,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
44
45
|
shadow: false,
|
|
45
46
|
shadow_cast: false,
|
|
46
47
|
shadow_receive: false,
|
|
47
|
-
renderorder:
|
|
48
|
+
renderorder: 502,
|
|
48
49
|
});
|
|
49
50
|
/*
|
|
50
51
|
this.light = this.createObject('Light', {
|
|
@@ -147,7 +147,7 @@ elation.elements.define('janus.username.picker', class extends elation.elements.
|
|
|
147
147
|
create() {
|
|
148
148
|
this.elements = elation.elements.fromString(`
|
|
149
149
|
<form name="usernameform">
|
|
150
|
-
<ui-input label="${this.label}" name="clientid"></ui-input>
|
|
150
|
+
<ui-input type="text" label="${this.label}" name="clientid"></ui-input>
|
|
151
151
|
<input type="submit" name="submit" value="${this.confirm ? this.confirmlabel : this.buttonlabel}">
|
|
152
152
|
</form>
|
|
153
153
|
`, this);
|