diff --git a/conf/settings.ini.dist b/conf/settings.ini.dist index 485ae1e..7d0a3e2 100644 --- a/conf/settings.ini.dist +++ b/conf/settings.ini.dist @@ -20,6 +20,11 @@ ; the realm used for turn accounts. Must match the realm of your turn server ;realm = 'vroom' +[video] +; Define the max frame rate for video +; higher will produce better quality streams, but will also require more bandwidth and CPU power +;frame_rate = 15 + [email] ; Address set in the From field of email sent by VROOM ;from = 'no-reply@example.com' diff --git a/lib/Vroom/Constants.pm b/lib/Vroom/Constants.pm index cd6b13f..8dd8234 100644 --- a/lib/Vroom/Constants.pm +++ b/lib/Vroom/Constants.pm @@ -122,10 +122,11 @@ use constant API_ACTIONS => { get_room_conf => 1, get_peer_role => 1, join => 1, - get_padd_session => 1 + get_padd_session => 1, + get_rtc_conf => 1 }, anonymous => { - create_room => 1 + create_room => 1 } }; diff --git a/lib/Vroom/I18N/en.pm b/lib/Vroom/I18N/en.pm index 813f099..015047c 100644 --- a/lib/Vroom/I18N/en.pm +++ b/lib/Vroom/I18N/en.pm @@ -229,6 +229,8 @@ our %Lexicon = ( "CLICK_IF_NO_WEBCAM" => "If you don't have a webcam, click the following link, you'll be able to join the room with audio only", "CONNECTION_LOST" => "You have been disconnected", "CHECK_INTERNET_ACCESS" => "Please, check your Internet connection, then refresh this page", + "CONNECTING" => "Connecting", + "CONNECTING_PLEASE_WAIT" => "Please wait while establishing the connection", "HOME" => "Home", "HELP" => "Help", "ABOUT" => "About", diff --git a/lib/Vroom/I18N/fr.pm b/lib/Vroom/I18N/fr.pm index a45c954..1100c2e 100644 --- a/lib/Vroom/I18N/fr.pm +++ b/lib/Vroom/I18N/fr.pm @@ -238,6 +238,8 @@ our %Lexicon = ( "en audio uniquement", "CONNECTION_LOST" => "Vous avez été déconnecté", "CHECK_INTERNET_ACCESS" => "Vérifiez votre connexion, et raffraîchissez cette page ensuite", + "CONNECTING" => "Connexion en cours", + "CONNECTING_PLEASE_WAIT" => "Veuillez patienter le temps d'établir la connexion", "HOME" => "Accueil", "HELP" => "Aide", "ABOUT" => "À propos", diff --git a/public/img/connecting.gif b/public/img/connecting.gif new file mode 100644 index 0000000..c3e9d00 Binary files /dev/null and b/public/img/connecting.gif differ diff --git a/public/js/vroom.js b/public/js/vroom.js index e2bd0cb..4461585 100644 --- a/public/js/vroom.js +++ b/public/js/vroom.js @@ -21,6 +21,9 @@ var locale = {}; // When pagination is done, how many item per page var itemPerPage = 20; +// Will store the global webrtc object +var webrtc = undefined; + // Localize the strings we need $.ajax({ url: rootUrl + 'localize/' + currentLang, @@ -575,6 +578,30 @@ function initAdmin(){ }); } +function initJoin(room){ + $.ajax({ + data: { + req: JSON.stringify({ + action: 'get_rtc_conf', + param: { + room: room, + } + }) + }, + error: function(data){ + showApiError(data); + }, + success: function(data){ + if (!video){ + data.config.media.video = false; + } + data.config.localVideoEl = 'webRTCVideoLocal'; + webrtc = new SimpleWebRTC(data.config); + initVroom(room); + } + }); +} + // This is the main function called when you join a room function initVroom(room) { @@ -876,7 +903,7 @@ function initVroom(room) { // color can be sent through the signaling channel peer.send('peer_color', {color: peers.local.color}); // if we don't have a video, just signal it to this peer - peer.send('media_info', {video: !!videoConstraints}); + peer.send('media_info', {video: !!video}); // We don't have chat history yet ? Lets ask to this new peer if(!peers.local.hasHistory && chatIndex == 0){ peer.sendDirectly('vroom', 'getHistory', ''); @@ -1515,11 +1542,14 @@ function initVroom(room) { if (data.msg){ $.notify(data.msg, 'success'); } + $('#videoLocalContainer').show(200); + $('#timeCounterXs,#timeCounter').tinyTimer({ from: new Date }); + setTimeout(function(){ + $('#connecting').modal('hide'); + }, 200); } }); checkMoh(); - $('#videoLocalContainer').show(200); - $('#timeCounterXs,#timeCounter').tinyTimer({ from: new Date }); }); // Handle new video stream added: someone joined the room @@ -1764,7 +1794,7 @@ function initVroom(room) { }); // Disable suspend webcam button if no webcam - if (!videoConstraints){ + if (!video){ $('.btn-suspend-cam').addClass('disabled'); } diff --git a/templates/default/join.html.ep b/templates/default/join.html.ep index ce2f63e..e758369 100644 --- a/templates/default/join.html.ep +++ b/templates/default/join.html.ep @@ -377,6 +377,24 @@ + %=include 'invite_modal' %=include 'configure_modal' %=include 'auth_modal' @@ -432,7 +450,6 @@ %= include 'footer' diff --git a/vroom.pl b/vroom.pl index e94213f..b951c4a 100755 --- a/vroom.pl +++ b/vroom.pl @@ -36,6 +36,7 @@ $config->{'turn.turn_server'} ||= undef; $config->{'turn.turn_user'} ||= undef; $config->{'turn.turn_password'} ||= undef; $config->{'turn.realm'} ||= 'vroom'; +$config->{'video.frame_rate'} ||= 15; $config->{'email.from '} ||= 'vroom@example.com'; $config->{'email.contact'} ||= 'admin@example.com'; $config->{'email.sendmail'} ||= '/sbin/sendmail'; @@ -1262,6 +1263,7 @@ any '/api' => sub { } ); } + # And here anonymous method, which do not require an API Key elsif ($req->{action} eq 'create_room'){ $req->{param}->{room} ||= $self->get_random_name(); $req->{param}->{room} = lc $req->{param}->{room}; @@ -1601,6 +1603,53 @@ any '/api' => sub { status => 403 ); } + # Return configuration for SimpleWebRTC + elsif ($req->{action} eq 'get_rtc_conf'){ + my $resp = { + url => $config->{'signaling.uri'}, + peerConnectionConfig => { + iceServers => [{ + url => $config->{'turn.stun_server'} + }] + }, + autoRequestMedia => Mojo::JSON::true, + enableDataChannels => Mojo::JSON::true, + debug => Mojo::JSON::false, + detectSpeakingEvents => Mojo::JSON::true, + adjustPeerVolume => Mojo::JSON::false, + autoAdjustMic => Mojo::JSON::false, + harkOptions => { + interval => 300, + threshold => -20 + }, + media => { + audio => Mojo::JSON::true, + video => { + mandatory => { + maxFrameRate => $config->{'video.frame_rate'} + } + } + } + }; + # TODO: Support several TURN server in config + if ($config->{'turn.turn_server'}){ + my $turn = { url => $config->{'turn.turn_server'} }; + if ($config->{'turn.turn_user'} && $config->{'turn.turn_password'}){ + $turn->{username} = $config->{'turn.turn_user'}; + $turn->{credential} = $config->{'turn.turn_password'}; + } + else{ + $turn->{username} = $room->{name}; + $turn->{credential} = $room->{token}; + } + push @{$resp->{peerConnectionConfig}->{iceServers}}, $turn; + } + return $self->render( + json => { + config => $resp + } + ); + } # Return just room config elsif ($req->{action} eq 'get_room_conf'){ return $self->render(