зеркало из https://github.com/nextcloud/spreed.git
Merge pull request #227 from nextcloud/screensharing
Add screensharing support.
This commit is contained in:
Коммит
d88480378f
|
@ -146,6 +146,9 @@
|
||||||
background-position-y: 8px !important;
|
background-position-y: 8px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Video styles
|
||||||
|
*/
|
||||||
|
|
||||||
#videos {
|
#videos {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -264,6 +267,14 @@ video {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.participants-1 #video-fullscreen {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participants-1 #toggleScreensharing {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* big speaker video */
|
/* big speaker video */
|
||||||
.participants-1 .videoContainer,
|
.participants-1 .videoContainer,
|
||||||
.participants-2 .videoContainer,
|
.participants-2 .videoContainer,
|
||||||
|
@ -313,10 +324,23 @@ video {
|
||||||
#app-content.participants-7,
|
#app-content.participants-7,
|
||||||
#app-content.participants-8,
|
#app-content.participants-8,
|
||||||
#app-content.participants-9,
|
#app-content.participants-9,
|
||||||
#app-content.participants-10 {
|
#app-content.participants-10,
|
||||||
|
#app-content.screensharing {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#app-content.screensharing .videoContainer video {
|
||||||
|
max-height: 200px;
|
||||||
|
background-color: transparent;
|
||||||
|
box-shadow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-content.screensharing #localScreenContainer {
|
||||||
|
height: calc(100% - 200px);
|
||||||
|
overflow: scroll;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.nameIndicator {
|
.nameIndicator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
@ -327,7 +351,7 @@ video {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.videoView .nameIndicator {
|
.videoView .nameIndicator {
|
||||||
|
@ -348,6 +372,17 @@ video {
|
||||||
padding: 12px 35%;
|
padding: 12px 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#video-fullscreen {
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
z-index: 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
#video-fullscreen.public {
|
||||||
|
top: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#video-fullscreen,
|
||||||
.nameIndicator button {
|
.nameIndicator button {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -355,8 +390,10 @@ video {
|
||||||
height: 44px;
|
height: 44px;
|
||||||
background-size: 25px;
|
background-size: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nameIndicator button.audio-disabled,
|
.nameIndicator button.audio-disabled,
|
||||||
.nameIndicator button.video-disabled {
|
.nameIndicator button.video-disabled,
|
||||||
|
.nameIndicator button.screensharing-disabled {
|
||||||
opacity: .7;
|
opacity: .7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
70
js/app.js
70
js/app.js
|
@ -155,6 +155,11 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initialize button tooltips
|
||||||
|
$('[data-toggle="tooltip"]').tooltip({trigger: 'hover'}).click(function() {
|
||||||
|
$(this).tooltip('hide');
|
||||||
|
});
|
||||||
|
|
||||||
$('#hideVideo').click(function() {
|
$('#hideVideo').click(function() {
|
||||||
if(!OCA.SpreedMe.app.videoWasEnabledAtLeastOnce) {
|
if(!OCA.SpreedMe.app.videoWasEnabledAtLeastOnce) {
|
||||||
// don't allow clicking the video toggle
|
// don't allow clicking the video toggle
|
||||||
|
@ -173,6 +178,7 @@
|
||||||
localStorage.setItem("videoDisabled", true);
|
localStorage.setItem("videoDisabled", true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#mute').click(function() {
|
$('#mute').click(function() {
|
||||||
if (OCA.SpreedMe.webrtc.webrtc.isAudioEnabled()) {
|
if (OCA.SpreedMe.webrtc.webrtc.isAudioEnabled()) {
|
||||||
OCA.SpreedMe.app.disableAudio();
|
OCA.SpreedMe.app.disableAudio();
|
||||||
|
@ -197,6 +203,7 @@
|
||||||
} else if (fullscreenElem.msRequestFullscreen) {
|
} else if (fullscreenElem.msRequestFullscreen) {
|
||||||
fullscreenElem.msRequestFullscreen();
|
fullscreenElem.msRequestFullscreen();
|
||||||
}
|
}
|
||||||
|
$(this).attr('data-original-title', 'Exit fullscreen');
|
||||||
} else {
|
} else {
|
||||||
if (document.exitFullscreen) {
|
if (document.exitFullscreen) {
|
||||||
document.exitFullscreen();
|
document.exitFullscreen();
|
||||||
|
@ -207,6 +214,60 @@
|
||||||
} else if (document.msExitFullscreen) {
|
} else if (document.msExitFullscreen) {
|
||||||
document.msExitFullscreen();
|
document.msExitFullscreen();
|
||||||
}
|
}
|
||||||
|
$(this).attr('data-original-title', 'Fullscreen');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var screensharingStopped = function() {
|
||||||
|
console.log("Screensharing now stopped");
|
||||||
|
$('#toggleScreensharing').attr('data-original-title', 'Enable screensharing')
|
||||||
|
.addClass('screensharing-disabled icon-screen-off-white')
|
||||||
|
.removeClass('icon-screen-white');
|
||||||
|
};
|
||||||
|
|
||||||
|
OCA.SpreedMe.webrtc.on('localScreenStopped', function() {
|
||||||
|
screensharingStopped();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#toggleScreensharing').click(function() {
|
||||||
|
var webrtc = OCA.SpreedMe.webrtc;
|
||||||
|
if (!webrtc.capabilities.supportScreenSharing) {
|
||||||
|
OC.Notification.showTemporary(t('spreed', 'Screensharing is not supported by your browser.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webrtc.getLocalScreen()) {
|
||||||
|
webrtc.stopScreenShare();
|
||||||
|
screensharingStopped();
|
||||||
|
} else {
|
||||||
|
webrtc.shareScreen(function(err) {
|
||||||
|
if (!err) {
|
||||||
|
OC.Notification.showTemporary(t('spreed', 'Screensharing is about to start…'));
|
||||||
|
$('#toggleScreensharing').attr('data-original-title', 'Stop screensharing')
|
||||||
|
.removeClass('screensharing-disabled icon-screen-off-white')
|
||||||
|
.addClass('icon-screen-white');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (err.name) {
|
||||||
|
case "HTTPS_REQUIRED":
|
||||||
|
OC.Notification.showTemporary(t('spreed', 'Screensharing requires the page to be loaded through HTTPS.'));
|
||||||
|
break;
|
||||||
|
case "PERMISSION_DENIED":
|
||||||
|
case "NotAllowedError":
|
||||||
|
case "CEF_GETSCREENMEDIA_CANCELED": // Experimental, may go away in the future.
|
||||||
|
OC.Notification.showTemporary(t('spreed', 'The screensharing request has been cancelled.'));
|
||||||
|
break;
|
||||||
|
case "EXTENSION_UNAVAILABLE":
|
||||||
|
// TODO(fancycode): Show popup with links to Chrome/Firefox extensions.
|
||||||
|
OC.Notification.showTemporary(t('spreed', 'An extension is required to start screensharing.'));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OC.Notification.showTemporary(t('spreed', 'An error occurred while starting screensharing.'));
|
||||||
|
console.log("Could not start screensharing", err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -446,7 +507,7 @@
|
||||||
},
|
},
|
||||||
enableAudio: function() {
|
enableAudio: function() {
|
||||||
OCA.SpreedMe.webrtc.unmute();
|
OCA.SpreedMe.webrtc.unmute();
|
||||||
$('#mute').data('title', 'Mute audio')
|
$('#mute').attr('data-original-title', 'Mute audio')
|
||||||
.removeClass('audio-disabled icon-audio-off-white')
|
.removeClass('audio-disabled icon-audio-off-white')
|
||||||
.addClass('icon-audio-white');
|
.addClass('icon-audio-white');
|
||||||
|
|
||||||
|
@ -454,7 +515,7 @@
|
||||||
},
|
},
|
||||||
disableAudio: function() {
|
disableAudio: function() {
|
||||||
OCA.SpreedMe.webrtc.mute();
|
OCA.SpreedMe.webrtc.mute();
|
||||||
$('#mute').data('title', 'Enable audio')
|
$('#mute').attr('data-original-title', 'Enable audio')
|
||||||
.addClass('audio-disabled icon-audio-off-white')
|
.addClass('audio-disabled icon-audio-off-white')
|
||||||
.removeClass('icon-audio-white');
|
.removeClass('icon-audio-white');
|
||||||
|
|
||||||
|
@ -466,9 +527,10 @@
|
||||||
var localVideo = $hideVideoButton.closest('.videoView').find('#localVideo');
|
var localVideo = $hideVideoButton.closest('.videoView').find('#localVideo');
|
||||||
|
|
||||||
OCA.SpreedMe.webrtc.resumeVideo();
|
OCA.SpreedMe.webrtc.resumeVideo();
|
||||||
$hideVideoButton.data('title', 'Disable video')
|
$hideVideoButton.attr('data-original-title', 'Disable video')
|
||||||
.removeClass('video-disabled icon-video-off-white')
|
.removeClass('video-disabled icon-video-off-white')
|
||||||
.addClass('icon-video-white');
|
.addClass('icon-video-white');
|
||||||
|
|
||||||
avatarContainer.hide();
|
avatarContainer.hide();
|
||||||
localVideo.show();
|
localVideo.show();
|
||||||
|
|
||||||
|
@ -479,7 +541,7 @@
|
||||||
var avatarContainer = $hideVideoButton.closest('.videoView').find('.avatar-container');
|
var avatarContainer = $hideVideoButton.closest('.videoView').find('.avatar-container');
|
||||||
var localVideo = $hideVideoButton.closest('.videoView').find('#localVideo');
|
var localVideo = $hideVideoButton.closest('.videoView').find('#localVideo');
|
||||||
|
|
||||||
$hideVideoButton.data('title', 'Enable video')
|
$hideVideoButton.attr('data-original-title', 'Enable video')
|
||||||
.addClass('video-disabled icon-video-off-white')
|
.addClass('video-disabled icon-video-off-white')
|
||||||
.removeClass('icon-video-white');
|
.removeClass('icon-video-white');
|
||||||
|
|
||||||
|
|
|
@ -3976,23 +3976,15 @@
|
||||||
mediaSource: 'window'
|
mediaSource: 'window'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getUserMedia(constraints, function (err, stream) {
|
// Notify extension to add domain to whitelist and defer actual
|
||||||
callback(err, stream);
|
// getUserMedia call until extension finished adding the domain.
|
||||||
// workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1045810
|
var pending = window.setTimeout(function () {
|
||||||
if (!err) {
|
error = new Error('NavigatorUserMediaError');
|
||||||
var lastTime = stream.currentTime;
|
error.name = 'EXTENSION_UNAVAILABLE';
|
||||||
var polly = window.setInterval(function () {
|
return callback(error);
|
||||||
if (!stream) window.clearInterval(polly);
|
}, 1000);
|
||||||
if (stream.currentTime == lastTime) {
|
cache[pending] = [callback, constraints];
|
||||||
window.clearInterval(polly);
|
window.postMessage({ type: 'webrtcStartScreensharing', id: pending }, '*');
|
||||||
if (stream.onended) {
|
|
||||||
stream.onended();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastTime = stream.currentTime;
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
error = new Error('NavigatorUserMediaError');
|
error = new Error('NavigatorUserMediaError');
|
||||||
error.name = 'EXTENSION_UNAVAILABLE'; // does not make much sense but...
|
error.name = 'EXTENSION_UNAVAILABLE'; // does not make much sense but...
|
||||||
|
@ -4001,7 +3993,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
typeof window !== 'undefined' && window.addEventListener('message', function (event) {
|
typeof window !== 'undefined' && window.addEventListener('message', function (event) {
|
||||||
if (event.origin != window.location.origin) {
|
if (event.origin != window.location.origin && !event.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.data.type == 'gotScreen' && cache[event.data.id]) {
|
if (event.data.type == 'gotScreen' && cache[event.data.id]) {
|
||||||
|
@ -4032,6 +4024,33 @@
|
||||||
}
|
}
|
||||||
} else if (event.data.type == 'getScreenPending') {
|
} else if (event.data.type == 'getScreenPending') {
|
||||||
window.clearTimeout(event.data.id);
|
window.clearTimeout(event.data.id);
|
||||||
|
} else if (event.data.type == 'webrtcScreensharingWhitelisted' && cache[event.data.id]) {
|
||||||
|
var data = cache[event.data.id];
|
||||||
|
window.clearTimeout(event.data.id);
|
||||||
|
var constraints = data[1];
|
||||||
|
var callback = data[0];
|
||||||
|
delete cache[event.data.id];
|
||||||
|
|
||||||
|
getUserMedia(constraints, function (err, stream) {
|
||||||
|
// Notify extension to remove domain from whitelist.
|
||||||
|
window.postMessage({ type: 'webrtcStopScreensharing' }, '*');
|
||||||
|
callback(err, stream);
|
||||||
|
if (err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1045810
|
||||||
|
var lastTime = stream.currentTime;
|
||||||
|
var polly = window.setInterval(function () {
|
||||||
|
if (!stream) window.clearInterval(polly);
|
||||||
|
if (stream.currentTime == lastTime) {
|
||||||
|
window.clearInterval(polly);
|
||||||
|
if (stream.onended) {
|
||||||
|
stream.onended();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastTime = stream.currentTime;
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17739,6 +17758,9 @@
|
||||||
mLine.iceTransport.addRemoteCandidate({});
|
mLine.iceTransport.addRemoteCandidate({});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (message.type === 'unshareScreen') {
|
||||||
|
this.parent.emit('unshareScreen', {id: message.from});
|
||||||
|
this.end();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18317,7 +18339,11 @@
|
||||||
if (this.getLocalScreen()) {
|
if (this.getLocalScreen()) {
|
||||||
this.webrtc.stopScreenShare();
|
this.webrtc.stopScreenShare();
|
||||||
}
|
}
|
||||||
|
// Notify peers were sending to.
|
||||||
this.webrtc.peers.forEach(function (peer) {
|
this.webrtc.peers.forEach(function (peer) {
|
||||||
|
if (peer.type === 'screen' && peer.sharemyscreen) {
|
||||||
|
peer.send('unshareScreen');
|
||||||
|
}
|
||||||
if (peer.broadcaster) {
|
if (peer.broadcaster) {
|
||||||
peer.end();
|
peer.end();
|
||||||
}
|
}
|
||||||
|
@ -18478,6 +18504,17 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.on('unshareScreen', function(message) {
|
||||||
|
// End peers we were receiving the screensharing stream from.
|
||||||
|
var peers = self.getPeers(message.from, 'screen');
|
||||||
|
peers.forEach(function(peer) {
|
||||||
|
if (!peer.sharemyscreen) {
|
||||||
|
peer.end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// log events in debug mode
|
// log events in debug mode
|
||||||
if (this.config.debug) {
|
if (this.config.debug) {
|
||||||
this.on('*', function (event, val1, val2) {
|
this.on('*', function (event, val1, val2) {
|
||||||
|
|
88
js/webrtc.js
88
js/webrtc.js
|
@ -37,10 +37,34 @@ var spreedMappingTable = [];
|
||||||
|
|
||||||
var appContentElement = $('#app-content'),
|
var appContentElement = $('#app-content'),
|
||||||
participantsClass = 'participants-' + currentUsersNo;
|
participantsClass = 'participants-' + currentUsersNo;
|
||||||
if (!appContentElement.hasClass(participantsClass)) {
|
if (!appContentElement.hasClass(participantsClass) && !appContentElement.hasClass('screensharing')) {
|
||||||
appContentElement.attr('class', '').addClass(participantsClass);
|
appContentElement.attr('class', '').addClass(participantsClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Send shared screen to new participants
|
||||||
|
var webrtc = OCA.SpreedMe.webrtc;
|
||||||
|
if (webrtc.getLocalScreen()) {
|
||||||
|
var newUsers = currentUsersInRoom.diff(previousUsersInRoom);
|
||||||
|
var currentUser = webrtc.connection.getSessionid();
|
||||||
|
newUsers.forEach(function(user) {
|
||||||
|
if (user !== currentUser) {
|
||||||
|
var peer = webrtc.webrtc.createPeer({
|
||||||
|
id: user,
|
||||||
|
type: 'screen',
|
||||||
|
sharemyscreen: true,
|
||||||
|
enableDataChannels: false,
|
||||||
|
receiveMedia: {
|
||||||
|
offerToReceiveAudio: 0,
|
||||||
|
offerToReceiveVideo: 0
|
||||||
|
},
|
||||||
|
broadcaster: currentUser,
|
||||||
|
});
|
||||||
|
webrtc.emit('createdPeer', peer);
|
||||||
|
peer.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var disconnectedUsers = previousUsersInRoom.diff(currentUsersInRoom);
|
var disconnectedUsers = previousUsersInRoom.diff(currentUsersInRoom);
|
||||||
disconnectedUsers.forEach(function(user) {
|
disconnectedUsers.forEach(function(user) {
|
||||||
console.log('XXX Remove peer', user);
|
console.log('XXX Remove peer', user);
|
||||||
|
@ -130,6 +154,17 @@ var spreedMappingTable = [];
|
||||||
|
|
||||||
var spreedListofSpeakers = {};
|
var spreedListofSpeakers = {};
|
||||||
var latestSpeakerId = null;
|
var latestSpeakerId = null;
|
||||||
|
var screenSharingActive = false;
|
||||||
|
|
||||||
|
window.addEventListener('resize', function() {
|
||||||
|
if (screenSharingActive) {
|
||||||
|
$('#localScreenContainer').children('video').each(function() {
|
||||||
|
$(this).width('100%');
|
||||||
|
$(this).height($('#localScreenContainer').height());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
OCA.SpreedMe.speakers = {
|
OCA.SpreedMe.speakers = {
|
||||||
showStatus: function() {
|
showStatus: function() {
|
||||||
var data = [];
|
var data = [];
|
||||||
|
@ -155,6 +190,10 @@ var spreedMappingTable = [];
|
||||||
return '#container_' + sanitizedId + '_video_incoming';
|
return '#container_' + sanitizedId + '_video_incoming';
|
||||||
},
|
},
|
||||||
switchVideoToId: function(id) {
|
switchVideoToId: function(id) {
|
||||||
|
if (screenSharingActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var newContainer = $(OCA.SpreedMe.speakers.getContainerId(id));
|
var newContainer = $(OCA.SpreedMe.speakers.getContainerId(id));
|
||||||
if(newContainer.find('video').length === 0) {
|
if(newContainer.find('video').length === 0) {
|
||||||
console.warn('promote: no video found for ID', id);
|
console.warn('promote: no video found for ID', id);
|
||||||
|
@ -179,6 +218,14 @@ var spreedMappingTable = [];
|
||||||
|
|
||||||
latestSpeakerId = id;
|
latestSpeakerId = id;
|
||||||
},
|
},
|
||||||
|
unpromoteLatestSpeaker: function() {
|
||||||
|
if (latestSpeakerId) {
|
||||||
|
var oldContainer = $(OCA.SpreedMe.speakers.getContainerId(latestSpeakerId));
|
||||||
|
oldContainer.removeClass('promoted');
|
||||||
|
latestSpeakerId = null;
|
||||||
|
$('.videoContainer-dummy').remove();
|
||||||
|
}
|
||||||
|
},
|
||||||
updateVideoContainerDummy: function(id) {
|
updateVideoContainerDummy: function(id) {
|
||||||
var newContainer = $(OCA.SpreedMe.speakers.getContainerId(id));
|
var newContainer = $(OCA.SpreedMe.speakers.getContainerId(id));
|
||||||
|
|
||||||
|
@ -347,6 +394,11 @@ var spreedMappingTable = [];
|
||||||
|
|
||||||
OCA.SpreedMe.webrtc.on('videoAdded', function(video, peer) {
|
OCA.SpreedMe.webrtc.on('videoAdded', function(video, peer) {
|
||||||
console.log('video added', peer);
|
console.log('video added', peer);
|
||||||
|
if (peer.type === 'screen') {
|
||||||
|
OCA.SpreedMe.webrtc.emit('localScreenAdded', video);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var remotes = document.getElementById('videos');
|
var remotes = document.getElementById('videos');
|
||||||
if (remotes) {
|
if (remotes) {
|
||||||
// Indicator for username
|
// Indicator for username
|
||||||
|
@ -465,6 +517,14 @@ var spreedMappingTable = [];
|
||||||
|
|
||||||
// a peer was removed
|
// a peer was removed
|
||||||
OCA.SpreedMe.webrtc.on('videoRemoved', function(video, peer) {
|
OCA.SpreedMe.webrtc.on('videoRemoved', function(video, peer) {
|
||||||
|
if (video.dataset.screensharing) {
|
||||||
|
// SimpleWebRTC notifies about stopped screensharing through
|
||||||
|
// the generic "videoRemoved" API, but the stream must be
|
||||||
|
// handled differently.
|
||||||
|
OCA.SpreedMe.webrtc.emit('localScreenRemoved', video);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// a removed peer can't speak anymore ;)
|
// a removed peer can't speak anymore ;)
|
||||||
OCA.SpreedMe.speakers.remove(peer, true);
|
OCA.SpreedMe.speakers.remove(peer, true);
|
||||||
|
|
||||||
|
@ -489,6 +549,32 @@ var spreedMappingTable = [];
|
||||||
OCA.SpreedMe.webrtc.sendDirectlyToAll('videoOff');
|
OCA.SpreedMe.webrtc.sendDirectlyToAll('videoOff');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Local screen added.
|
||||||
|
OCA.SpreedMe.webrtc.on('localScreenAdded', function (video) {
|
||||||
|
var initialHeight = $('#app-content').height() - 200;
|
||||||
|
|
||||||
|
video.style.width = '100%';
|
||||||
|
video.style.height = initialHeight + 'px';
|
||||||
|
|
||||||
|
OCA.SpreedMe.speakers.unpromoteLatestSpeaker();
|
||||||
|
|
||||||
|
screenSharingActive = true;
|
||||||
|
$('#app-content').attr('class', '').addClass('screensharing');
|
||||||
|
|
||||||
|
video.dataset.screensharing = true;
|
||||||
|
document.getElementById('localScreenContainer').appendChild(video);
|
||||||
|
});
|
||||||
|
// Local screen removed.
|
||||||
|
OCA.SpreedMe.webrtc.on('localScreenRemoved', function (video) {
|
||||||
|
document.getElementById('localScreenContainer').removeChild(video);
|
||||||
|
OCA.SpreedMe.webrtc.emit('localScreenStopped');
|
||||||
|
|
||||||
|
if (!document.getElementById('localScreenContainer').hasChildNodes()) {
|
||||||
|
screenSharingActive = false;
|
||||||
|
$('#app-content').removeClass('screensharing');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Peer changed nick
|
// Peer changed nick
|
||||||
OCA.SpreedMe.webrtc.on('nick', function(data) {
|
OCA.SpreedMe.webrtc.on('nick', function(data) {
|
||||||
var el = document.getElementById('container_' + OCA.SpreedMe.webrtc.getDomId({
|
var el = document.getElementById('container_' + OCA.SpreedMe.webrtc.getDomId({
|
||||||
|
|
|
@ -24,7 +24,7 @@ script(
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div id="app" data-roomId="<?php p($_['roomId']) ?>">
|
<div id="app" class="nc-enable-screensharing-extension" data-roomId="<?php p($_['roomId']) ?>">
|
||||||
<div id="app-content" class="participants-1">
|
<div id="app-content" class="participants-1">
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
|
@ -49,6 +49,8 @@ script(
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<button id="video-fullscreen" class="icon-fullscreen-white public" data-placement="bottom" data-toggle="tooltip" data-original-title="<?php p($l->t('Fullscreen')) ?>"></button>
|
||||||
|
|
||||||
<div id="video-speaking">
|
<div id="video-speaking">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,13 +61,14 @@ script(
|
||||||
<div class="avatar"></div>
|
<div class="avatar"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="nameIndicator">
|
<div class="nameIndicator">
|
||||||
<button id="mute" class="icon-audio-white" data-title="<?php p($l->t('Mute audio')) ?>"></button>
|
<button id="mute" class="icon-audio-white" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Mute audio')) ?>"></button>
|
||||||
<button id="hideVideo" class="icon-video-white" data-title="<?php p($l->t('Pause video')) ?>"></button>
|
<button id="hideVideo" class="icon-video-white" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Disable video')) ?>"></button>
|
||||||
<button id="video-fullscreen" class="icon-fullscreen-white" data-title="<?php p($l->t('Fullscreen')) ?>"></button>
|
<button id="toggleScreensharing" class="icon-screen-off-white screensharing-disabled" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Share screen')) ?>"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="localScreenContainer"></div>
|
||||||
|
|
||||||
<div id="emptycontent">
|
<div id="emptycontent">
|
||||||
<div id="emptycontent-icon" class="icon-video"></div>
|
<div id="emptycontent-icon" class="icon-video"></div>
|
||||||
|
|
|
@ -24,7 +24,7 @@ script(
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div id="app" data-roomId="<?php p($_['roomId']) ?>">
|
<div id="app" class="nc-enable-screensharing-extension" data-roomId="<?php p($_['roomId']) ?>">
|
||||||
<div id="app-navigation" class="icon-loading">
|
<div id="app-navigation" class="icon-loading">
|
||||||
<form id="oca-spreedme-add-room">
|
<form id="oca-spreedme-add-room">
|
||||||
<input id="edit-roomname" type="text" placeholder="<?php p($l->t('Choose person …')) ?>"/>
|
<input id="edit-roomname" type="text" placeholder="<?php p($l->t('Choose person …')) ?>"/>
|
||||||
|
@ -35,6 +35,8 @@ script(
|
||||||
|
|
||||||
<div id="app-content" class="participants-1">
|
<div id="app-content" class="participants-1">
|
||||||
|
|
||||||
|
<button id="video-fullscreen" class="icon-fullscreen-white" data-placement="bottom" data-toggle="tooltip" data-original-title="<?php p($l->t('Fullscreen')) ?>"></button>
|
||||||
|
|
||||||
<div id="video-speaking">
|
<div id="video-speaking">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,13 +47,14 @@ script(
|
||||||
<div class="avatar"></div>
|
<div class="avatar"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="nameIndicator">
|
<div class="nameIndicator">
|
||||||
<button id="mute" class="icon-audio-white" data-title="<?php p($l->t('Mute audio')) ?>"></button>
|
<button id="mute" class="icon-audio-white" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Mute audio')) ?>"></button>
|
||||||
<button id="hideVideo" class="icon-video-white" data-title="<?php p($l->t('Pause video')) ?>"></button>
|
<button id="hideVideo" class="icon-video-white" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Disable video')) ?>"></button>
|
||||||
<button id="video-fullscreen" class="icon-fullscreen-white" data-title="<?php p($l->t('Fullscreen')) ?>"></button>
|
<button id="toggleScreensharing" class="icon-screen-off-white screensharing-disabled" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Share screen')) ?>"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="localScreenContainer"></div>
|
||||||
|
|
||||||
<div id="emptycontent">
|
<div id="emptycontent">
|
||||||
<div id="emptycontent-icon" class="icon-video"></div>
|
<div id="emptycontent-icon" class="icon-video"></div>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче