accept or reject video offers

This commit is contained in:
Connor Turland 2015-12-11 17:29:17 -05:00
parent 089528c46d
commit 3c9d722945
7 changed files with 135 additions and 68 deletions

View file

@ -5396,9 +5396,11 @@ function Peer(options) {
this.pc = new PeerConnection(this.parent.config.peerConnectionConfig, this.parent.config.peerConnectionConstraints); this.pc = new PeerConnection(this.parent.config.peerConnectionConfig, this.parent.config.peerConnectionConstraints);
this.pc.on('ice', this.onIceCandidate.bind(this)); this.pc.on('ice', this.onIceCandidate.bind(this));
this.pc.on('offer', function (offer) { this.pc.on('offer', function (offer) {
if (self.parent.config.nick) offer.nick = self.parent.config.nick;
self.send('offer', offer); self.send('offer', offer);
}); });
this.pc.on('answer', function (offer) { this.pc.on('answer', function (offer) {
if (self.parent.config.nick) offer.nick = self.parent.config.nick;
self.send('answer', offer); self.send('answer', offer);
}); });
this.pc.on('addStream', this.handleRemoteStreamAdded.bind(this)); this.pc.on('addStream', this.handleRemoteStreamAdded.bind(this));
@ -5471,6 +5473,8 @@ Peer.prototype.handleMessage = function (message) {
if (message.prefix) this.browserPrefix = message.prefix; if (message.prefix) this.browserPrefix = message.prefix;
if (message.type === 'offer') { if (message.type === 'offer') {
if (!this.nick) this.nick = message.payload.nick;
delete message.payload.nick;
// workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1064247 // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1064247
message.payload.sdp = message.payload.sdp.replace('a=fmtp:0 profile-level-id=0x42e00c;packetization-mode=1\r\n', ''); message.payload.sdp = message.payload.sdp.replace('a=fmtp:0 profile-level-id=0x42e00c;packetization-mode=1\r\n', '');
this.pc.handleOffer(message.payload, function (err) { this.pc.handleOffer(message.payload, function (err) {
@ -5483,6 +5487,8 @@ Peer.prototype.handleMessage = function (message) {
}); });
}); });
} else if (message.type === 'answer') { } else if (message.type === 'answer') {
if (!this.nick) this.nick = message.payload.nick;
delete message.payload.nick;
this.pc.handleAnswer(message.payload); this.pc.handleAnswer(message.payload);
} else if (message.type === 'candidate') { } else if (message.type === 'candidate') {
this.pc.processIce(message.payload); this.pc.processIce(message.payload);

View file

@ -1962,7 +1962,8 @@ Metamaps.Realtime = {
media: { media: {
video: true, video: true,
audio: true audio: true
} },
nick: Metamaps.Active.Mapper.id
}); });
self.webrtc.on('readyToCall', function () { self.webrtc.on('readyToCall', function () {
console.log('readyToCall'); console.log('readyToCall');
@ -1972,7 +1973,8 @@ Metamaps.Realtime = {
$('#wrapper').append(self.localVideo.view.$container); $('#wrapper').append(self.localVideo.view.$container);
} }
self.socket.emit('videoAdded', { self.socket.emit('videoAdded', {
avatar: Metamaps.Active.Mapper.get('image') avatar: Metamaps.Active.Mapper.get('image'),
username: Metamaps.Active.Mapper.get('name')
}); });
self.webrtc.webrtc.peers.forEach(function (p) { self.webrtc.webrtc.peers.forEach(function (p) {
p.pc.addStream(self.webrtc.webrtc.localStream); p.pc.addStream(self.webrtc.webrtc.localStream);
@ -2061,6 +2063,9 @@ Metamaps.Realtime = {
for (id in roomDesc.avatars) { for (id in roomDesc.avatars) {
self.webrtc.webrtc.peers.find(function(p) { return p.id === id; }).avatar = roomDesc.avatars[id]; self.webrtc.webrtc.peers.find(function(p) { return p.id === id; }).avatar = roomDesc.avatars[id];
} }
for (id in roomDesc.usernames) {
self.webrtc.webrtc.peers.find(function(p) { return p.id === id; }).username = roomDesc.usernames[id];
}
function addVideo(v) { function addVideo(v) {
// random position for now // random position for now

View file

@ -67,6 +67,10 @@ Metamaps.Views.room = (function () {
this.webrtc.webrtc.off('peerStreamAdded'); this.webrtc.webrtc.off('peerStreamAdded');
this.webrtc.webrtc.off('peerStreamRemoved'); this.webrtc.webrtc.off('peerStreamRemoved');
this.webrtc.on('peerStreamAdded', function (peer) { this.webrtc.on('peerStreamAdded', function (peer) {
var mapper = Metamaps.Realtime.mappersOnMap[peer.nick];
peer.avatar = mapper.image;
peer.username = mapper.name;
console.log(peer);
if (self.isActiveRoom) { if (self.isActiveRoom) {
self.addVideo(peer); self.addVideo(peer);
} }
@ -119,7 +123,9 @@ Metamaps.Views.room = (function () {
} }
} }
}); });
console.log(data);
peer.avatar = data.avatar; peer.avatar = data.avatar;
peer.username = data.username;
self.webrtc.emit('createdPeer', peer); self.webrtc.emit('createdPeer', peer);
peer.start(); peer.start();
@ -141,7 +147,10 @@ Metamaps.Views.room = (function () {
var var
id = this.webrtc.getDomId(peer), id = this.webrtc.getDomId(peer),
video = attachMediaStream(peer.stream); video = attachMediaStream(peer.stream);
v = new VideoView(video, null, id, false, { DOUBLE_CLICK_TOLERANCE: 200, avatar: peer.avatar });
$(video).prop('muted', true); // until the viewer accepts the viewing
var
v = new VideoView(video, null, id, false, { DOUBLE_CLICK_TOLERANCE: 200, avatar: peer.avatar, username: peer.username });
if (this._videoAdded) this._videoAdded(v); if (this._videoAdded) this._videoAdded(v);
this.videos[peer.id] = v; this.videos[peer.id] = v;
@ -150,9 +159,11 @@ Metamaps.Views.room = (function () {
room.prototype.removeVideo = function (peer) { room.prototype.removeVideo = function (peer) {
console.log('removeVideo', peer); console.log('removeVideo', peer);
var id = typeof peer == 'string' ? peer : peer.id; var id = typeof peer == 'string' ? peer : peer.id;
if (this.videos[id]) {
this.videos[id].remove(); this.videos[id].remove();
delete this.videos[id]; delete this.videos[id];
} }
}
room.prototype.sendChatMessage = function (data) { room.prototype.sendChatMessage = function (data) {
var self = this; var self = this;

View file

@ -97,6 +97,14 @@ Metamaps.Views.videoView = (function () {
} }
this.videoStatus = !this.videoStatus; this.videoStatus = !this.videoStatus;
$(document).trigger(videoView.events.videoControlClick, [this]); $(document).trigger(videoView.events.videoControlClick, [this]);
},
yesReceiveClick: function () {
this.$receiveContainer.hide();
this.$avatar.hide();
$(this.video).prop('muted', false);
},
noReceiveClick: function () {
this.$container.hide();
} }
}; };
@ -127,6 +135,17 @@ Metamaps.Views.videoView = (function () {
$vidContainer.addClass('video-cutoff'); $vidContainer.addClass('video-cutoff');
$vidContainer.append(this.video); $vidContainer.append(this.video);
if (!isMyself) {
this.$receiveContainer = $('<div class="video-receive"><div class="video-statement">' + config.username + ' is sharing their audio and video. Do you wish to receive it?</div><div class="btn-group"><button type="button" class="button btn-yes">Yes</button><button type="button" class="button btn-no">No</button></div></div>');
this.$container.append(this.$receiveContainer);
this.$container.find('.btn-yes').on('click', function (event) {
Handlers.yesReceiveClick.call(self, event);
});
this.$container.find('.btn-no').on('click', function (event) {
Handlers.noReceiveClick.call(self, event);
});
}
this.avatar = config.avatar; this.avatar = config.avatar;
this.$avatar = $('<img draggable="false" class="collaborator-video-avatar" src="' + config.avatar + '" width="150" height="150" />'); this.$avatar = $('<img draggable="false" class="collaborator-video-avatar" src="' + config.avatar + '" width="150" height="150" />');
$vidContainer.append(this.$avatar); $vidContainer.append(this.$avatar);
@ -137,7 +156,10 @@ Metamaps.Views.videoView = (function () {
Handlers.mousedown.call(self, event); Handlers.mousedown.call(self, event);
}); });
if (isMyself) Private.addControls.call(this); if (isMyself) {
this.$avatar.hide();
Private.addControls.call(this);
}
// suppress contextmenu // suppress contextmenu
this.video.oncontextmenu = function () { return false; }; this.video.oncontextmenu = function () { return false; };
@ -184,5 +206,3 @@ Metamaps.Views.videoView = (function () {
return videoView; return videoView;
})(); })();

View file

@ -6,6 +6,29 @@
cursor: default; cursor: default;
color: #FFF; color: #FFF;
} }
.collaborator-video .video-receive {
position: absolute;
width: 160px;
padding: 20px 20px 20px 170px;
background: #424242;
height: 110px;
border-top-left-radius: 75px;
border-bottom-left-radius: 75px;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
.collaborator-video .video-receive .video-statement {
margin-bottom: 10px;
}
.collaborator-video .video-receive .btn-group .btn-yes {
margin-right: 10px;
}
.collaborator-video .video-receive .btn-group .btn-no {
background-color: #c04f4f;
}
.collaborator-video .video-receive .btn-group .btn-no:hover {
background-color: #A54242;
}
.collaborator-video .video-cutoff { .collaborator-video .video-cutoff {
width: 150px; width: 150px;
height: 150px; height: 150px;
@ -31,7 +54,6 @@
-o-user-select: none; -o-user-select: none;
user-select: none; user-select: none;
-webkit-user-drag: none; -webkit-user-drag: none;
display: none;
} }
.collaborator-video .video-audio { .collaborator-video .video-audio {
position: absolute; position: absolute;

View file

@ -7,7 +7,7 @@ class User < ActiveRecord::Base
has_many :maps has_many :maps
has_many :mappings has_many :mappings
before_create :generate_code after_create :generate_code
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :registerable devise :database_authenticatable, :recoverable, :rememberable, :trackable, :registerable

View file

@ -10,11 +10,13 @@ module.exports = function(io, stunservers) {
var clients = io.sockets.clients(name); var clients = io.sockets.clients(name);
var result = { var result = {
clients: {}, clients: {},
avatars: {} avatars: {},
usernames: {}
}; };
clients.forEach(function (client) { clients.forEach(function (client) {
result.clients[client.id] = client.resources; result.clients[client.id] = client.resources;
result.avatars[client.id] = client.avatar; result.avatars[client.id] = client.avatar;
result.usernames[client.id] = client.username;
}); });
return result; return result;
} }
@ -71,9 +73,10 @@ module.exports = function(io, stunservers) {
var socketsInRoom = io.sockets.clients(client.room); var socketsInRoom = io.sockets.clients(client.room);
client.resources.video = true; client.resources.video = true;
client.avatar = data.avatar; client.avatar = data.avatar;
client.username = data.username;
socketsInRoom.forEach(function(socket) { socketsInRoom.forEach(function(socket) {
if (socket.id !== client.id) { if (socket.id !== client.id) {
socket.emit('addVideo', { id: client.id, avatar: data.avatar }); socket.emit('addVideo', { id: client.id, avatar: data.avatar, username: data.username });
} }
}); });
} }