Browse Source

Merge branch 'release-0.24'

pull/230/head v0.24.5
Simon Eisenmann 10 years ago
parent
commit
c3c9347e00
  1. 14
      debian/changelog
  2. 30
      doc/APACHE.txt
  3. 91
      doc/NGINX.txt
  4. 4
      src/app/spreed-webrtc-server/room_manager_test.go
  5. 2
      static/js/controllers/uicontroller.js
  6. 551
      static/js/libs/ua-parser.js
  7. 6
      static/js/mediastream/peercall.js
  8. 15
      static/js/mediastream/peerconnection.js
  9. 77
      static/js/mediastream/usermedia.js
  10. 3
      static/js/services/appdata.js

14
debian/changelog vendored

@ -1,3 +1,17 @@ @@ -1,3 +1,17 @@
spreed-webrtc-server (0.24.5) trusty; urgency=medium
* Updated ua-parser to 0.7.9.
* Fixed errors in unit tests.
* Added Apache HTTPD example configuration.
* Fixed a problem where Firefox did not release media permissions.
* More use of track API instead of stream API.
* SignalingState changes are now triggered as event.
* Fixed a problem where Firefox did not start the call when media permission was denied.
* Fixed a problem where streams could not be started when they were disabled when call was started and server has renegotiation disabled.
* Fixed a problem where the renegotiation shrine was ignored.
-- Simon Eisenmann <simon@struktur.de> Fri, 07 Aug 2015 16:08:14 +0200
spreed-webrtc-server (0.24.4) precise; urgency=low
* Updated German translations.

30
doc/APACHE.txt

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
## Apache HTTP Server configuration for Spreed WebRTC
Apache supports websocket proxy starting with 2.4.5.
Make sure you have the module mod_proxy_wstunnel enabled. In addition proxy,
proxy_http and headers modules have to be enabled. On Ubuntu this goes like
this: `a2enmod proxy proxy_http proxy_wstunnel headers`
Then add the following lines to your VirtualHost section:
<Location />
ProxyPass http://127.0.0.1:8080/
ProxyPassReverse /
</Location>
<Location /ws>
ProxyPass ws://127.0.0.1:8080/ws
</Location>
ProxyVia On
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
Thats it.
--
(c)2015 struktur AG

91
doc/NGINX.txt

@ -1,49 +1,48 @@ @@ -1,49 +1,48 @@
A few notes on Nginx configuration
In general Nginx with websocket support is required
(I am using Nginx 1.4). It should work with Nginx 1.3 too.
Add the following to your Nginx server section:
location / {
proxy_pass http://localhost:8090;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
This is using a map to provide the Upgrade and Connection
headers to the backend server. You need to add this map to
the http section of your server:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
Also make sure that you have the general proxy configuration
like this in place:
proxy_buffering on;
proxy_ignore_client_abort off;
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
Thats it.
--
(c)2013 struktur AG
## Nginx HTTP server configuration for Spreed WebRTC
In general Nginx with websocket support is required (Nginx >= 1.3).
Add the following to your Nginx server section:
location / {
proxy_pass http://localhost:8090;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
This is using a map to provide the Upgrade and Connection
headers to the backend server. You need to add this map to
the http section of your server:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
Also make sure that you have the general proxy configuration
like this in place:
proxy_buffering on;
proxy_ignore_client_abort off;
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
And thats it.
--
(c)2013 struktur AG

4
src/app/spreed-webrtc-server/room_manager_test.go

@ -26,7 +26,9 @@ import ( @@ -26,7 +26,9 @@ import (
)
func NewTestRoomManager() (RoomManager, *Config) {
config := &Config{}
config := &Config{
roomTypeDefault: "Room",
}
return NewRoomManager(config, nil), config
}

2
static/js/controllers/uicontroller.js

@ -454,7 +454,7 @@ define(['jquery', 'underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'web @@ -454,7 +454,7 @@ define(['jquery', 'underscore', 'bigscreen', 'moment', 'sjcl', 'modernizr', 'web
var reconnect = function() {
if (appData.flags.connected && appData.flags.autoreconnect) {
if (appData.flags.resurrect === null) {
// Storage data at the resurrection shrine.
// Store data at the resurrection shrine.
appData.flags.resurrect = {
status: $scope.getStatus(),
id: $scope.id

551
static/js/libs/ua-parser.js

@ -1,9 +1,11 @@ @@ -1,9 +1,11 @@
// UAParser.js v0.7.0
// Lightweight JavaScript-based User-Agent string parser
// https://github.com/faisalman/ua-parser-js
//
// Copyright © 2012-2013 Faisalman <fyzlman@gmail.com>
// Dual licensed under GPLv2 & MIT
/**
* UAParser.js v0.7.9
* Lightweight JavaScript-based User-Agent string parser
* https://github.com/faisalman/ua-parser-js
*
* Copyright © 2012-2015 Faisal Salman <fyzlman@gmail.com>
* Dual licensed under GPLv2 & MIT
*/
(function (window, undefined) {
@ -14,12 +16,14 @@ @@ -14,12 +16,14 @@
/////////////
var EMPTY = '',
var LIBVERSION = '0.7.9',
EMPTY = '',
UNKNOWN = '?',
FUNC_TYPE = 'function',
UNDEF_TYPE = 'undefined',
OBJ_TYPE = 'object',
MAJOR = 'major',
STR_TYPE = 'string',
MAJOR = 'major', // deprecated
MODEL = 'model',
NAME = 'name',
TYPE = 'type',
@ -29,7 +33,9 @@ @@ -29,7 +33,9 @@
CONSOLE = 'console',
MOBILE = 'mobile',
TABLET = 'tablet',
SMARTTV = 'smarttv';
SMARTTV = 'smarttv',
WEARABLE = 'wearable',
EMBEDDED = 'embedded';
///////////
@ -38,13 +44,26 @@ @@ -38,13 +44,26 @@
var util = {
extend : function (regexes, extensions) {
for (var i in extensions) {
if ("browser cpu device engine os".indexOf(i) !== -1 && extensions[i].length % 2 === 0) {
regexes[i] = extensions[i].concat(regexes[i]);
}
}
return regexes;
},
has : function (str1, str2) {
if (typeof str1 === "string") {
return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;
} else {
return false;
}
},
lowerize : function (str) {
return str.toLowerCase();
},
major : function (version) {
return typeof(version) === STR_TYPE ? version.split(".")[0] : undefined;
}
};
@ -58,18 +77,20 @@ @@ -58,18 +77,20 @@
rgx : function () {
var result, i = 0, j, k, p, q, matches, match, args = arguments;
// loop through all regexes maps
for (var result, i = 0, j, k, p, q, matches, match, args = arguments; i < args.length; i += 2) {
while (i < args.length && !matches) {
var regex = args[i], // even sequence (0,2,4,..)
props = args[i + 1]; // odd sequence (1,3,5,..)
// construct object barebones
if (typeof(result) === UNDEF_TYPE) {
if (typeof result === UNDEF_TYPE) {
result = {};
for (p in props) {
q = props[p];
if (typeof(q) === OBJ_TYPE) {
if (typeof q === OBJ_TYPE) {
result[q[0]] = undefined;
} else {
result[q] = undefined;
@ -78,16 +99,17 @@ @@ -78,16 +99,17 @@
}
// try matching uastring with regexes
for (j = k = 0; j < regex.length; j++) {
matches = regex[j].exec(this.getUA());
j = k = 0;
while (j < regex.length && !matches) {
matches = regex[j++].exec(this.getUA());
if (!!matches) {
for (p = 0; p < props.length; p++) {
match = matches[++k];
q = props[p];
// check if given property is actually array
if (typeof(q) === OBJ_TYPE && q.length > 0) {
if (typeof q === OBJ_TYPE && q.length > 0) {
if (q.length == 2) {
if (typeof(q[1]) == FUNC_TYPE) {
if (typeof q[1] == FUNC_TYPE) {
// assign modified match
result[q[0]] = q[1].call(this, match);
} else {
@ -96,7 +118,7 @@ @@ -96,7 +118,7 @@
}
} else if (q.length == 3) {
// check whether function or regex
if (typeof(q[1]) === FUNC_TYPE && !(q[1].exec && q[1].test)) {
if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
// call function (usually string mapper)
result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
} else {
@ -110,11 +132,9 @@ @@ -110,11 +132,9 @@
result[q] = match ? match : undefined;
}
}
break;
}
}
if(!!matches) break; // break the loop immediately if match found
i += 2;
}
return result;
},
@ -123,7 +143,7 @@ @@ -123,7 +143,7 @@
for (var i in map) {
// check if array
if (typeof(map[i]) === OBJ_TYPE && map[i].length > 0) {
if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
for (var j = 0; j < map[i].length; j++) {
if (util.has(map[i][j], str)) {
return (i === UNKNOWN) ? undefined : i;
@ -147,11 +167,6 @@ @@ -147,11 +167,6 @@
browser : {
oldsafari : {
major : {
'1' : ['/8', '/1', '/3'],
'2' : '/4',
'?' : '/'
},
version : {
'1.0' : '/8',
'1.2' : '/1',
@ -166,6 +181,11 @@ @@ -166,6 +181,11 @@
},
device : {
amazon : {
model : {
'Fire Phone' : ['SD', 'KF']
}
},
sprint : {
model : {
'Evo Shift 4G' : '7373KT'
@ -189,6 +209,7 @@ @@ -189,6 +209,7 @@
'7' : 'NT 6.1',
'8' : 'NT 6.2',
'8.1' : 'NT 6.3',
'10' : ['NT 6.4', 'NT 10.0'],
'RT' : 'ARM'
}
}
@ -205,96 +226,115 @@ @@ -205,96 +226,115 @@
browser : [[
/APP-([\w\s-\d]+)\/((\d+)?[\w\.]+)/i // KTA App
], [NAME, VERSION, MAJOR], [
// Presto based
/(opera\smini)\/((\d+)?[\w\.-]+)/i, // Opera Mini
/(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i, // Opera Mobi/Tablet
/(opera).+version\/((\d+)?[\w\.]+)/i, // Opera > 9.80
/(opera)[\/\s]+((\d+)?[\w\.]+)/i // Opera < 9.80
/(opera\smini)\/([\w\.-]+)/i, // Opera Mini
/(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet
/(opera).+version\/([\w\.]+)/i, // Opera > 9.80
/(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/\s(opr)\/((\d+)?[\w\.]+)/i // Opera Webkit
], [[NAME, 'Opera'], VERSION, MAJOR], [
/\s(opr)\/([\w\.]+)/i // Opera Webkit
], [[NAME, 'Opera'], VERSION], [
// Mixed
/(kindle)\/((\d+)?[\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,
/(kindle)\/([\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i,
// Lunascape/Maxthon/Netfront/Jasmine/Blazer
// Trident based
/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i,
/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i,
// Avant/IEMobile/SlimBrowser/Baidu
/(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i, // Internet Explorer
/(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based
/(rekonq)((?:\/)[\w\.]+)*/i, // Rekonq
/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i
// Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron
], [NAME, VERSION, MAJOR], [
/(rekonq)\/([\w\.]+)*/i, // Rekonq
/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium)\/([\w\.-]+)/i
// Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium
], [NAME, VERSION], [
/(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i // IE11
], [[NAME, 'IE'], VERSION, MAJOR], [
/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11
], [[NAME, 'IE'], VERSION], [
/(edge)\/((\d+)?[\w\.]+)/i // Microsoft Edge
], [NAME, VERSION], [
/(yabrowser)\/((\d+)?[\w\.]+)/i // Yandex
], [[NAME, 'Yandex'], VERSION, MAJOR], [
/(yabrowser)\/([\w\.]+)/i // Yandex
], [[NAME, 'Yandex'], VERSION], [
/(comodo_dragon)\/((\d+)?[\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION, MAJOR], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [
/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i
/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i,
// Chrome/OmniWeb/Arora/Tizen/Nokia
], [NAME, VERSION, MAJOR], [
/(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i
// UCBrowser/QQBrowser
], [NAME, VERSION], [
/(dolfin)\/([\w\.]+)/i // Dolphin
], [[NAME, 'Dolphin'], VERSION], [
/((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
], [[NAME, 'Chrome'], VERSION], [
/(dolfin)\/((\d+)?[\w\.]+)/i // Dolphin
], [[NAME, 'Dolphin'], VERSION, MAJOR], [
/XiaoMi\/MiuiBrowser\/([\w\.]+)/i // MIUI Browser
], [VERSION, [NAME, 'MIUI Browser']], [
/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i // Chrome for Android/iOS
], [[NAME, 'Chrome'], VERSION, MAJOR], [
/android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i // Android Browser
], [VERSION, [NAME, 'Android Browser']], [
/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari
], [VERSION, MAJOR, [NAME, 'Mobile Safari']], [
/FBAV\/([\w\.]+);/i // Facebook App for iOS
], [VERSION, [NAME, 'Facebook']], [
/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile
], [VERSION, MAJOR, NAME], [
/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari
], [VERSION, [NAME, 'Mobile Safari']], [
/webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i // Safari < 3.0
], [NAME, [MAJOR, mapper.str, maps.browser.oldsafari.major], [VERSION, mapper.str, maps.browser.oldsafari.version]], [
/version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile
], [VERSION, NAME], [
/(konqueror)\/((\d+)?[\w\.]+)/i, // Konqueror
/(webkit|khtml)\/((\d+)?[\w\.]+)/i
], [NAME, VERSION, MAJOR], [
/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [
/(konqueror)\/([\w\.]+)/i, // Konqueror
/(webkit|khtml)\/([\w\.]+)/i
], [NAME, VERSION], [
// Gecko based
/(navigator|netscape)\/((\d+)?[\w\.-]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION, MAJOR], [
/(navigator|netscape)\/([\w\.-]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION], [
/fxios\/([\w\.-]+)/i // Firefox for iOS
], [VERSION, [NAME, 'Firefox']], [
/(swiftfox)/i, // Swiftfox
/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,
/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i,
/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i,
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla
/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla
// Other
/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i,
// UCBrowser/Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/QQBrowser
/(links)\s\(((\d+)?[\w\.]+)/i, // Links
/(gobrowser)\/?((\d+)?[\w\.]+)*/i, // GoBrowser
/(ice\s?browser)\/v?((\d+)?[\w\._]+)/i, // ICE Browser
/(mosaic)[\/\s]((\d+)?[\w\.]+)/i // Mosaic
], [NAME, VERSION, MAJOR], [
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i,
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf
/(links)\s\(([\w\.]+)/i, // Links
/(gobrowser)\/?([\w\.]+)*/i, // GoBrowser
/(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser
/(mosaic)[\/\s]([\w\.]+)/i // Mosaic
], [NAME, VERSION]
/* /////////////////////
// Media players BEGIN
////////////////////////
, [
/(apple(?:coremedia|))\/((\d+)[\w\._]+)/i, // Generic Apple CoreMedia
/(coremedia) v((\d+)[\w\._]+)/i
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(aqualung|lyssna|bsplayer)\/((\d+)?[\w\.-]+)/i // Aqualung/Lyssna/BSPlayer
], [NAME, VERSION], [
/(ares|ossproxy)\s((\d+)[\w\.-]+)/i // Ares/OSSProxy
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/((\d+)[\w\.-]+)/i,
// Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
@ -302,12 +342,12 @@ @@ -302,12 +342,12 @@
/(clementine|music player daemon)\s((\d+)[\w\.-]+)/i, // Clementine/MPD
/(lg player|nexplayer)\s((\d+)[\d\.]+)/i,
/player\/(nexplayer|lg player)\s((\d+)[\w\.-]+)/i // NexPlayer/LG Player
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(nexplayer)\s((\d+)[\w\.-]+)/i // Nexplayer
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(flrp)\/((\d+)[\w\.-]+)/i // Flip Player
], [[NAME, 'Flip Player'], VERSION, MAJOR], [
], [[NAME, 'Flip Player'], VERSION], [
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
@ -315,23 +355,23 @@ @@ -315,23 +355,23 @@
/(gstreamer) souphttpsrc (?:\([^\)]+\)){0,1} libsoup\/((\d+)[\w\.-]+)/i
// Gstreamer
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(htc streaming player)\s[\w_]+\s\/\s((\d+)[\d\.]+)/i, // HTC Streaming Player
/(java|python-urllib|python-requests|wget|libcurl)\/((\d+)[\w\.-_]+)/i,
// Java/urllib/requests/wget/cURL
/(lavf)((\d+)[\d\.]+)/i // Lavf (FFMPEG)
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(htc_one_s)\/((\d+)[\d\.]+)/i, // HTC One S
], [[NAME, /_/g, ' '], VERSION, MAJOR], [
/(htc_one_s)\/((\d+)[\d\.]+)/i // HTC One S
], [[NAME, /_/g, ' '], VERSION], [
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+){0,1})/i,
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+){0,1})/i
// MPlayer SVN
], [NAME, VERSION], [
/(mplayer)(?:\s|\/|[unkow-]+)((\d+)[\w\.-]+)/i, // MPlayer
], [NAME, VERSION, MAJOR], [
/(mplayer)(?:\s|\/|[unkow-]+)((\d+)[\w\.-]+)/i // MPlayer
], [NAME, VERSION], [
/(mplayer)/i, // MPlayer (no other info)
/(yourmuze)/i, // YourMuze
@ -339,18 +379,18 @@ @@ -339,18 +379,18 @@
], [NAME], [
/(nero (?:home|scout))\/((\d+)[\w\.-]+)/i // Nero Home/Nero Scout
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(nokia\d+)\/((\d+)[\w\.-]+)/i // Nokia
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/\s(songbird)\/((\d+)[\w\.-]+)/i // Songbird/Philips-Songbird
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(winamp)3 version ((\d+)[\w\.-]+)/i, // Winamp
/(winamp)\s((\d+)[\w\.-]+)/i,
/(winamp)mpeg\/((\d+)[\w\.-]+)/i
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
// inlight radio
@ -359,32 +399,36 @@ @@ -359,32 +399,36 @@
/(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/((\d+)[\w\.-]+)/i
// QuickTime/RealMedia/RadioApp/RadioClientApplication/
// SoundTap/Totem/Stagefright/Streamium
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(smp)((\d+)[\d\.]+)/i // SMP
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(vlc) media player - version ((\d+)[\w\.]+)/i, // VLC Videolan
/(vlc)\/((\d+)[\w\.-]+)/i,
/(xbmc|gvfs|xine|xmms|irapp)\/((\d+)[\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp
/(foobar2000)\/((\d+)[\d\.]+)/i, // Foobar2000
/(itunes)\/((\d+)[\d\.]+)/i // iTunes
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(wmplayer)\/((\d+)[\w\.-]+)/i, // Windows Media Player
/(windows-media-player)\/((\d+)[\w\.-]+)/i
], [[NAME, /-/g, ' '], VERSION, MAJOR], [
], [[NAME, /-/g, ' '], VERSION], [
/windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i,
/windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i
// Windows Media Server
], [VERSION, MAJOR, [NAME, 'Windows']], [
], [VERSION, [NAME, 'Windows']], [
/(com\.riseupradioalarm)\/((\d+)[\d\.]*)/i // RiseUP Radio Alarm
], [NAME, VERSION, MAJOR], [
], [NAME, VERSION], [
/(rad.io)\s((\d+)[\d\.]+)/i, // Rad.io
/(radio.(?:de|at|fr))\s((\d+)[\d\.]+)/i
], [[NAME, 'rad.io'], VERSION, MAJOR]
], [[NAME, 'rad.io'], VERSION]
//////////////////////
// Media players END
////////////////////*/
],
@ -409,9 +453,9 @@ @@ -409,9 +453,9 @@
/(sun4\w)[;\)]/i // SPARC
], [[ARCHITECTURE, 'sparc']], [
/(ia64(?=;)|68k(?=\))|arm(?=v\d+;)|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i
// IA64, 68K, ARM, IRIX, MIPS, SPARC, PA-RISC
], [ARCHITECTURE, util.lowerize]
/((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
], [[ARCHITECTURE, util.lowerize]]
],
device : [[
@ -425,14 +469,17 @@ @@ -425,14 +469,17 @@
/(apple\s{0,1}tv)/i // Apple TV
], [[MODEL, 'Apple TV'], [VENDOR, 'Apple']], [
/(archos)\s(gamepad2?)/i, // Archos
/(hp).+(touchpad)/i, // HP TouchPad
/(kindle)\/([\w\.]+)/i, // Kindle
/\s(nook)[\w\s]+build\/(\w+)/i, // Nook
/(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak
], [VENDOR, MODEL, [TYPE, TABLET]], [
/(kf[A-z]+)\sbuild\/[\w\.]+.*silk\//i, // Kindle Fire HD
/(kf[A-z]+)\sbuild\/[\w\.]+.*silk\//i // Kindle Fire HD
], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
/(sd|kf)[0349hijorstuw]+\sbuild\/[\w\.]+.*silk\//i // Fire Phone
], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [
/\((ip[honed|\s\w*]+);.+(apple)/i // iPod/iPhone
], [MODEL, VENDOR, [TYPE, MOBILE]], [
@ -440,76 +487,178 @@ @@ -440,76 +487,178 @@
], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [
/(blackberry)[\s-]?(\w+)/i, // BlackBerry
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola)[\s_-]?([\w-]+)*/i,
// BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Huawei/Meizu/Motorola
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola|polytron)[\s_-]?([\w-]+)*/i,
// BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Huawei/Meizu/Motorola/Polytron
/(hp)\s([\w\s]+\w)/i, // HP iPAQ
/(asus)-?(\w+)/i // Asus
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/\((bb10);\s(\w+)/i // BlackBerry 10
], [[VENDOR, 'BlackBerry'], MODEL, [TYPE, MOBILE]], [
/\(bb10;\s(\w+)/i // BlackBerry 10
], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [
// Asus Tablets
/android.+((transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7))/i
], [[VENDOR, 'Asus'], MODEL, [TYPE, TABLET]], [
/android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7)/i
], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [
/(sony)\s(tablet\s[ps])/i // Sony Tablets
], [VENDOR, MODEL, [TYPE, TABLET]], [
/(sony)\s(tablet\s[ps])\sbuild\//i, // Sony
/(sony)?(?:sgp.+)\sbuild\//i
], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [
/(?:sony)?(?:(?:(?:c|d)\d{4})|(?:so[-l].+))\sbuild\//i
], [[VENDOR, 'Sony'], [MODEL, 'Xperia Phone'], [TYPE, MOBILE]], [
/\s(ouya)\s/i, // Ouya
/(nintendo)\s([wids3u]+)/i // Nintendo
], [VENDOR, MODEL, [TYPE, CONSOLE]], [
/((playstation)\s[3portablevi]+)/i // Playstation
], [[VENDOR, 'Sony'], MODEL, [TYPE, CONSOLE]], [
/android.+;\s(shield)\sbuild/i // Nvidia
], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
/(playstation\s[3portablevi]+)/i // Playstation
], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [
/(sprint\s(\w+))/i // Sprint Phones
], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [
/(lenovo)\s?(S(?:5000|6000)+(?:[-][\w+]))/i // Lenovo tablets
], [VENDOR, MODEL, [TYPE, TABLET]], [
/(htc)[;_\s-]+([\w\s]+(?=\))|\w+)*/i, // HTC
/(zte)-(\w+)*/i, // ZTE
/(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]+)*/i
// Alcatel/GeeksPhone/Huawei/Lenovo/Nexian/Panasonic/Sony
], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
/(nexus\s9)/i // HTC Nexus 9
], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
// Motorola
/\s((milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?))[\w\s]+build\//i,
/(mot)[\s-]?(\w+)*/i
], [[VENDOR, 'Motorola'], MODEL, [TYPE, MOBILE]], [
/android.+\s((mz60\d|xoom[\s2]{0,2}))\sbuild\//i
], [[VENDOR, 'Motorola'], MODEL, [TYPE, TABLET]], [
/[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox
], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [
/(kin\.[onetw]{3})/i // Microsoft Kin
], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [
/android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9|nexus 10))/i
// Motorola
/\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i,
/mot[\s-]?(\w+)*/i,
/(XT\d{3,4}) build\//i
], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [
/android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i
], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [
/android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9|nexus 10))/i,
/((SM-T\w+))/i
], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung
/((s[cgp]h-\w+|gt-\w+|galaxy\snexus))/i,
/((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-n900))/i,
/(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i,
/sec-((sgh\w+))/i
], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [
/(sie)-(\w+)*/i // Siemens
], [[VENDOR, 'Siemens'], MODEL, [TYPE, MOBILE]], [
/(samsung);smarttv/i
], [VENDOR, MODEL, [TYPE, SMARTTV]], [
/\(dtv[\);].+(aquos)/i // Sharp
], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
/sie-(\w+)*/i // Siemens
], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
/(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia
/(nokia)[\s_-]?([\w-]+)*/i
], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [
/android\s3\.[\s\w-;]{10}((a\d{3}))/i // Acer
], [[VENDOR, 'Acer'], MODEL, [TYPE, TABLET]], [
/android\s3\.[\s\w;-]{10}(a\d{3})/i // Acer
], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
/android\s3\.[\s\w-;]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet
/android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet
], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [
/(lg) netcast\.tv/i // LG SmartTV
], [VENDOR, [TYPE, SMARTTV]], [
/((nexus\s[45]))/i, // LG
/(lg)[e;\s-\/]+(\w+)*/i
], [[VENDOR, 'LG'], MODEL, [TYPE, MOBILE]], [
/android.+((ideatab[a-z0-9\-\s]+))/i // Lenovo
], [[VENDOR, 'Lenovo'], MODEL, [TYPE, TABLET]], [
], [VENDOR, MODEL, [TYPE, SMARTTV]], [
/(nexus\s[45])/i, // LG
/lg[e;\s\/-]+(\w+)*/i
], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [
/android.+(ideatab[a-z0-9\-\s]+)/i // Lenovo
], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
/linux;.+((jolla));/i // Jolla
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/((pebble))app\/[\d\.]+\s/i // Pebble
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
/android.+;\s(glass)\s\d/i // Google Glass
], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [
/android.+(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
/android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi
/android.+(mi[\s\-_]*(?:one|one[\s_]plus)?[\s_]*(?:\d\w)?)\s+build/i // Xiaomi Mi
], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [
/(mobile|tablet);.+rv\:.+gecko\//i // Unidentifiable
], [TYPE, VENDOR, MODEL]
], [[TYPE, util.lowerize], VENDOR, MODEL]
/*//////////////////////////
// TODO: move to string map
////////////////////////////
/(C6603)/i // Sony Xperia Z C6603
], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [
/(C6903)/i // Sony Xperia Z 1
], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [
/(SM-G900[F|H])/i // Samsung Galaxy S5
], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
/(SM-G7102)/i // Samsung Galaxy Grand 2
], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
/(SM-G530H)/i // Samsung Galaxy Grand Prime
], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
/(SM-G313HZ)/i // Samsung Galaxy V
], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
/(SM-T805)/i // Samsung Galaxy Tab S 10.5
], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [
/(SM-G800F)/i // Samsung Galaxy S5 Mini
], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
/(SM-T311)/i // Samsung Galaxy Tab 3 8.0
], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [
/(R1001)/i // Oppo R1001
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
/(X9006)/i // Oppo Find 7a
], [[MODEL, 'Find 7a'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [
/(R2001)/i // Oppo YOYO R2001
], [[MODEL, 'Yoyo R2001'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [
/(R815)/i // Oppo Clover R815
], [[MODEL, 'Clover R815'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [
/(U707)/i // Oppo Find Way S
], [[MODEL, 'Find Way S'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [
/(T3C)/i // Advan Vandroid T3C
], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [
/(ADVAN T1J\+)/i // Advan Vandroid T1J+
], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [
/(ADVAN S4A)/i // Advan Vandroid S4A
], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [
/(V972M)/i // ZTE V972M
], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
/(i-mobile)\s(IQ\s[\d\.]+)/i // i-mobile IQ
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(IQ6.3)/i // i-mobile IQ IQ 6.3
], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [
/(i-mobile)\s(i-style\s[\d\.]+)/i // i-mobile i-STYLE
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(i-STYLE2.1)/i // i-mobile i-STYLE 2.1
], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [
/(mobiistar touch LAI 512)/i // mobiistar touch LAI 512
], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [
/////////////
// END TODO
///////////*/
],
engine : [[
/APP-([\w\s-\d]+)\/((\d+)?[\w\.]+)/i // KTA App
], [[NAME, 'Mobile-App'], VERSION], [
/windows.+\sedge\/([\w\.]+)/i // EdgeHTML
], [VERSION, [NAME, 'EdgeHTML']], [
/(presto)\/([\w\.]+)/i, // Presto
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m
@ -524,7 +673,7 @@ @@ -524,7 +673,7 @@
os : [[
// Windows based
/microsoft\s(windows)\s(vista|xp)/i, // Windows (iTunes)
/microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes)
], [NAME, VERSION], [
/(windows)\snt\s6\.2;\s(arm)/i, // Windows RT
/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
@ -536,12 +685,15 @@ @@ -536,12 +685,15 @@
/\((bb)(10);/i // BlackBerry 10
], [[NAME, 'BlackBerry'], VERSION], [
/(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry
/(tizen)\/([\w\.]+)/i, // Tizen
/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i
// Android/WebOS/Palm/QNX/Bada/RIM/MeeGo
/(tizen)[\/\s]([\w\.]+)/i, // Tizen
/(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i,
// Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki
/linux;.+(sailfish);/i // Sailfish OS
], [NAME, VERSION], [
/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian
], [[NAME, 'Symbian'], VERSION],[
], [[NAME, 'Symbian'], VERSION], [
/\((series40);/i // Series 40
], [NAME], [
/mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS
], [[NAME, 'Firefox OS'], VERSION], [
@ -550,9 +702,10 @@ @@ -550,9 +702,10 @@
// GNU/Linux based
/(mint)[\/\s\(]?(\w+)*/i, // Mint
/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,
/(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux
/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i,
// Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
// Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk
// Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus
/(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux
/(gnu)\s?([\w\.]+)*/i // GNU
], [NAME, VERSION], [
@ -571,14 +724,16 @@ @@ -571,14 +724,16 @@
/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS
], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [
/(mac\sos\sx)\s?([\w\s\.]+\w)*/i // Mac OS
], [NAME, [VERSION, /_/g, '.']], [
/(mac\sos\sx)\s?([\w\s\.]+\w)*/i,
/(macintosh|mac(?=_powerpc)\s)/i // Mac OS
], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
// Other
/((?:open)?solaris)[\/\s-]?([\w\.]+)*/i, // Solaris
/(haiku)\s(\w+)/i, // Haiku
/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX
/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,
// Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS
/(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,
// Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS
/(unix)\s?([\w\.]+)*/i // UNIX
], [NAME, VERSION]
]
@ -590,27 +745,31 @@ @@ -590,27 +745,31 @@
////////////////
var UAParser = function (uastring) {
var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
var UAParser = function (uastring, extensions) {
if (!(this instanceof UAParser)) {
return new UAParser(uastring).getResult();
return new UAParser(uastring, extensions).getResult();
}
var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;
this.getBrowser = function () {
return mapper.rgx.apply(this, regexes.browser);
var browser = mapper.rgx.apply(this, rgxmap.browser);
browser.major = util.major(browser.version);
return browser;
};
this.getCPU = function () {
return mapper.rgx.apply(this, regexes.cpu);
return mapper.rgx.apply(this, rgxmap.cpu);
};
this.getDevice = function () {
return mapper.rgx.apply(this, regexes.device);
return mapper.rgx.apply(this, rgxmap.device);
};
this.getEngine = function () {
return mapper.rgx.apply(this, regexes.engine);
return mapper.rgx.apply(this, rgxmap.engine);
};
this.getOS = function () {
return mapper.rgx.apply(this, regexes.os);
return mapper.rgx.apply(this, rgxmap.os);
};
this.getResult = function() {
return {
@ -630,6 +789,36 @@ @@ -630,6 +789,36 @@
return this;
};
this.setUA(ua);
return this;
};
UAParser.VERSION = LIBVERSION;
UAParser.BROWSER = {
NAME : NAME,
MAJOR : MAJOR, // deprecated
VERSION : VERSION
};
UAParser.CPU = {
ARCHITECTURE : ARCHITECTURE
};
UAParser.DEVICE = {
MODEL : MODEL,
VENDOR : VENDOR,
TYPE : TYPE,
CONSOLE : CONSOLE,
MOBILE : MOBILE,
SMARTTV : SMARTTV,
TABLET : TABLET,
WEARABLE: WEARABLE,
EMBEDDED: EMBEDDED
};
UAParser.ENGINE = {
NAME : NAME,
VERSION : VERSION
};
UAParser.OS = {
NAME : NAME,
VERSION : VERSION
};
@ -641,35 +830,41 @@ @@ -641,35 +830,41 @@
// check js environment
if (typeof(exports) !== UNDEF_TYPE) {
// nodejs env
if (typeof(module) !== UNDEF_TYPE && module.exports) {
if (typeof module !== UNDEF_TYPE && module.exports) {
exports = module.exports = UAParser;
}
exports.UAParser = UAParser;
} else {
// browser env
window.UAParser = UAParser;
// requirejs env (optional)
if (typeof(define) === FUNC_TYPE && define.amd) {
define(function () {
return UAParser;
});
} else {
// browser env
window.UAParser = UAParser;
}
// jQuery specific (optional)
if (typeof(window.jQuery) !== UNDEF_TYPE) {
var $ = window.jQuery;
var parser = new UAParser();
$.ua = parser.getResult();
$.ua.get = function() {
return parser.getUA();
};
$.ua.set = function (uastring) {
parser.setUA(uastring);
var result = parser.getResult();
for (var prop in result) {
$.ua[prop] = result[prop];
}
};
}
}
})(this);
// jQuery/Zepto specific (optional)
// Note:
// In AMD env the global scope should be kept clean, but jQuery is an exception.
// jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
// and we should catch that.
var $ = window.jQuery || window.Zepto;
if (typeof $ !== UNDEF_TYPE) {
var parser = new UAParser();
$.ua = parser.getResult();
$.ua.get = function() {
return parser.getUA();
};
$.ua.set = function (uastring) {
parser.setUA(uastring);
var result = parser.getResult();
for (var prop in result) {
$.ua[prop] = result[prop];
}
};
}
})(typeof window === 'object' ? window : this);

6
static/js/mediastream/peercall.js

@ -211,6 +211,12 @@ define(['jquery', 'underscore', 'mediastream/utils', 'mediastream/peerconnection @@ -211,6 +211,12 @@ define(['jquery', 'underscore', 'mediastream/utils', 'mediastream/peerconnection
}
};
PeerCall.prototype.onSignalingStateChange = function(signalingState) {
this.e.triggerHandler("signalingStateChange", [signalingState, this]);
};
PeerCall.prototype.onIceConnectionStateChange = function(iceConnectionState) {
this.e.triggerHandler("connectionStateChange", [iceConnectionState, this]);

15
static/js/mediastream/peerconnection.js

@ -82,6 +82,7 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) { @@ -82,6 +82,7 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
// implemented. This does not work together with Chrome, so we trigger negotiation
// manually when a stream is added or removed.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1017888
// https://bugzilla.mozilla.org/show_bug.cgi?id=1149838
this.negotiationNeeded = _.bind(function() {
if (this.currentcall.initiate) {
// Trigger onNegotiationNeeded once for Firefox.
@ -93,9 +94,7 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) { @@ -93,9 +94,7 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
pc.onnegotiationneeded = _.bind(this.onNegotiationNeeded, this);
}
pc.ondatachannel = _.bind(this.onDatachannel, this);
pc.onsignalingstatechange = function(event) {
console.debug("Signaling state changed", pc.signalingState);
};
pc.onsignalingstatechange = _.bind(this.onSignalingStateChange, this);
// NOTE(longsleep):
// Support old callback too (https://groups.google.com/forum/?fromgroups=#!topic/discuss-webrtc/glukq0OWwVM)
// Chrome < 27 and Firefox < 24 need this.
@ -221,10 +220,18 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) { @@ -221,10 +220,18 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
};
PeerConnection.prototype.onSignalingStateChange = function(event) {
var signalingState = event.target.signalingState;
console.debug("Connection signaling state change", signalingState, this.currentcall.id);
this.currentcall.onSignalingStateChange(signalingState);
};
PeerConnection.prototype.onIceConnectionStateChange = function(event) {
var iceConnectionState = event.target.iceConnectionState;
console.info("ICE connection state change", iceConnectionState, event, this.currentcall);
console.debug("ICE connection state change", iceConnectionState, this.currentcall.id);
this.currentcall.onIceConnectionStateChange(iceConnectionState);
};

77
static/js/mediastream/usermedia.js

@ -109,12 +109,20 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr @@ -109,12 +109,20 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr
var stopUserMediaStream = (function() {
return function(stream) {
if (stream && stream.getTracks) {
// Stop all tracks.
var tracks = stream.getTracks();
_.each(tracks, function(t) {
t.stop();
});
if (window.webrtcDetectedBrowser === "firefox") {
// Always call stop for Firefox as long as it is available.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1192170
if (stream.stop) {
stream.stop();
}
}
} else {
console.warn("MediaStream.stop is deprecated");
// MediaStream.stop is deprecated.
stream.stop();
}
}
@ -277,21 +285,26 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr @@ -277,21 +285,26 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr
}
}
if (this.renegotiation && this.audioMute && this.videoMute) {
// Fast path as nothing should be shared.
_.defer(_.bind(function() {
this.onUserMediaSuccess(new DummyStream());
}, this));
this.started = true;
return true
}
var constraints = $.extend(true, {}, mediaConstraints);
if (this.audioMute) {
constraints.audio = false;
}
if (this.videoMute) {
constraints.video = false;
if (this.renegotiation) {
if (this.audioMute && this.videoMute) {
// Fast path as nothing should be shared.
_.defer(_.bind(function() {
this.onUserMediaSuccess(new DummyStream());
}, this));
this.started = true;
return true
}
if (this.audioMute) {
constraints.audio = false;
}
if (this.videoMute) {
constraints.video = false;
}
}
try {
@ -334,22 +347,39 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr @@ -334,22 +347,39 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr
UserMedia.prototype.replaceStream = function(stream) {
var oldStream = this.localStream;
if (oldStream && oldStream.active) {
// Let old stream silently end.
oldStream.onended = function() {
var onendedsilent = function(event) {
console.log("Silently ended replaced user media stream.");
};
if (oldStream.getTracks) {
_.each(stream.getTracks(), function(t) {
t.onended = onendedsilent;
});
} else {
// Legacy api.
oldStream.onended = onendedsilent;
}
stopUserMediaStream(oldStream);
}
if (stream) {
// Get notified of end events.
stream.onended = _.bind(function(event) {
console.log("User media stream ended.");
// Catch events when streams end.
var onended = _.bind(function(event) {
if (this.started) {
console.log("Stopping user media as a stream has ended.", event);
this.stop();
}
}, this);
if (stream.getTracks) {
_.each(stream.getTracks(), function(t) {
t.onended = onended;
});
} else {
// Legacy api.
stream.onended = onended;
}
// Set new stream.
this.localStream = stream;
this.e.triggerHandler("localstream", [stream, oldStream, this]);
@ -373,6 +403,12 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr @@ -373,6 +403,12 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr
}, this), 0);
}
if (!this.renegotiation) {
// Apply mute states after we got streams.
this.applyAudioMute(this.audioMute);
this.applyVideoMute(this.videoMute);
}
};
UserMedia.prototype.stop = function() {
@ -510,6 +546,9 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr @@ -510,6 +546,9 @@ define(['jquery', 'underscore', 'audiocontext', 'mediastream/dummystream', 'webr
delete this.peerconnections[id];
}, this));
}
} else {
// Make sure to trigger renegotiation even if we have no media.
_.defer(pc.negotiationNeeded);
}
};

3
static/js/services/appdata.js

@ -62,7 +62,8 @@ define(["jquery"], function($) { @@ -62,7 +62,8 @@ define(["jquery"], function($) {
service.e = $({});
service.data = null;
service.flags = {
authorizing: false
authorizing: false,
resurrect: null
};
service.language = $window.document.getElementsByTagName("html")[0].getAttribute("lang");

Loading…
Cancel
Save