1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

update web components

This commit is contained in:
Luke Pulverenti 2015-12-23 12:46:01 -05:00
parent 909402537a
commit fcdd2e4f4b
114 changed files with 1611 additions and 1238 deletions

View file

@ -11,19 +11,19 @@
"license": "https://github.com/MediaBrowser/Emby.ApiClient.Javascript/blob/master/LICENSE",
"homepage": "https://github.com/MediaBrowser/Emby.ApiClient.Javascript",
"dependencies": {
"cryptojslib": "cryptojslib#^3.1.2"
"cryptojslib": "cryptojslib#^3.1.2",
"requirejs": "requirejs#^2.1.22"
},
"devDependencies": {},
"ignore": [],
"version": "1.0.3",
"_release": "1.0.3",
"version": "1.0.16",
"_release": "1.0.16",
"_resolution": {
"type": "version",
"tag": "1.0.3",
"commit": "8e6266950e05e2d032d62340cb7307a3d19a23ec"
"tag": "1.0.16",
"commit": "a454b78f6e617aef9359736c57f38ac40fcc8d61"
},
"_source": "git://github.com/MediaBrowser/Emby.ApiClient.Javascript.git",
"_target": "~1.0.3",
"_originalSource": "emby-apiclient",
"_direct": true
"_originalSource": "emby-apiclient"
}

View file

@ -1,8 +1,4 @@
(function (globalScope, JSON, WebSocket, setTimeout, devicePixelRatio, FileReader) {
if (!globalScope.MediaBrowser) {
globalScope.MediaBrowser = {};
}
define(['events'], function (Events) {
/**
* Creates a new api client instance
@ -10,17 +6,17 @@
* @param {String} clientName s
* @param {String} applicationVersion
*/
globalScope.MediaBrowser.ApiClient = function (logger, serverAddress, clientName, applicationVersion, deviceName, deviceId) {
return function (serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio) {
if (!serverAddress) {
throw new Error("Must supply a serverAddress");
}
logger.log('ApiClient serverAddress: ' + serverAddress);
logger.log('ApiClient clientName: ' + clientName);
logger.log('ApiClient applicationVersion: ' + applicationVersion);
logger.log('ApiClient deviceName: ' + deviceName);
logger.log('ApiClient deviceId: ' + deviceId);
console.log('ApiClient serverAddress: ' + serverAddress);
console.log('ApiClient clientName: ' + clientName);
console.log('ApiClient applicationVersion: ' + applicationVersion);
console.log('ApiClient deviceName: ' + deviceName);
console.log('ApiClient deviceId: ' + deviceId);
var self = this;
var webSocket;
@ -267,7 +263,7 @@
}
if (self.enableAutomaticNetworking === false || request.type != "GET") {
logger.log('Requesting url without automatic networking: ' + request.url);
console.log('Requesting url without automatic networking: ' + request.url);
return getFetchPromise(request).then(function (response) {
@ -337,7 +333,7 @@
connectionMode = switchConnectionMode(connectionMode);
var url = MediaBrowser.ServerInfo.getServerAddress(self.serverInfo(), connectionMode);
logger.log("Attempting reconnection to " + url);
console.log("Attempting reconnection to " + url);
var timeout = connectionMode == MediaBrowser.ConnectionMode.Local ? 7000 : 15000;
@ -351,7 +347,7 @@
}, timeout).then(function () {
logger.log("Reconnect succeeded to " + url);
console.log("Reconnect succeeded to " + url);
self.serverInfo().LastConnectionMode = connectionMode;
self.serverAddress(url);
@ -360,7 +356,7 @@
}, function () {
logger.log("Reconnect attempt failed to " + url);
console.log("Reconnect attempt failed to " + url);
if (currentRetryCount < 5) {
@ -388,7 +384,7 @@
self.fetchWithFailover = function (request, enableReconnection) {
logger.log("Requesting " + request.url);
console.log("Requesting " + request.url);
request.timeout = 30000;
@ -408,32 +404,32 @@
}, function (error) {
logger.log("Request failed to " + request.url);
console.log("Request failed to " + request.url);
// http://api.jquery.com/jQuery.ajax/
if (enableReconnection) {
logger.log("Attempting reconnection");
console.log("Attempting reconnection");
var previousServerAddress = self.serverAddress();
return tryReconnect().then(function () {
logger.log("Reconnect succeesed");
console.log("Reconnect succeesed");
request.url = request.url.replace(previousServerAddress, self.serverAddress());
return self.fetchWithFailover(request, false);
}, function (innerError) {
logger.log("Reconnect failed");
console.log("Reconnect failed");
onFetchFail(request.url, {});
throw innerError;
});
} else {
logger.log("Reporting request failure");
console.log("Reporting request failure");
onFetchFail(request.url, {});
throw error;
@ -496,7 +492,7 @@
throw new Error('connectionMode cannot be null');
}
logger.log('Begin updateServerInfo. connectionMode: ' + connectionMode);
console.log('Begin updateServerInfo. connectionMode: ' + connectionMode);
self.serverInfo(server);
@ -505,7 +501,7 @@
if (!serverUrl) {
throw new Error('serverUrl cannot be null. serverInfo: ' + JSON.stringify(server));
}
logger.log('Setting server address to ' + serverUrl);
console.log('Setting server address to ' + serverUrl);
self.serverAddress(serverUrl);
};
@ -536,7 +532,7 @@
webSocket.onopen = function () {
logger.log('web socket connection opened');
console.log('web socket connection opened');
setTimeout(function () {
Events.trigger(self, 'websocketopen');
}, 0);
@ -578,7 +574,7 @@
self.sendWebSocketMessage = function (name, data) {
logger.log('Sending web socket message: ' + name);
console.log('Sending web socket message: ' + name);
var msg = { MessageType: name };
@ -3412,5 +3408,4 @@
return self.getJSON(url);
};
};
})(window, window.JSON, window.WebSocket, window.setTimeout, window.devicePixelRatio, window.FileReader);
});

View file

@ -11,7 +11,8 @@
"license": "https://github.com/MediaBrowser/Emby.ApiClient.Javascript/blob/master/LICENSE",
"homepage": "https://github.com/MediaBrowser/Emby.ApiClient.Javascript",
"dependencies": {
"cryptojslib": "cryptojslib#^3.1.2"
"cryptojslib": "cryptojslib#^3.1.2",
"requirejs": "requirejs#^2.1.22"
},
"devDependencies": {

View file

@ -1,10 +1,6 @@
(function (globalScope) {
define(['events', 'apiclient'], function (Events, apiClientFactory) {
if (!globalScope.MediaBrowser) {
globalScope.MediaBrowser = {};
}
globalScope.MediaBrowser.ConnectionState = {
var ConnectionState = {
Unavailable: 0,
ServerSelection: 1,
ServerSignIn: 2,
@ -12,22 +8,22 @@
ConnectSignIn: 4
};
globalScope.MediaBrowser.ConnectionMode = {
var ConnectionMode = {
Local: 0,
Remote: 1,
Manual: 2
};
globalScope.MediaBrowser.ServerInfo = {
var ServerInfo = {
getServerAddress: function (server, mode) {
switch (mode) {
case MediaBrowser.ConnectionMode.Local:
case ConnectionMode.Local:
return server.LocalAddress;
case MediaBrowser.ConnectionMode.Manual:
case ConnectionMode.Manual:
return server.ManualAddress;
case MediaBrowser.ConnectionMode.Remote:
case ConnectionMode.Remote:
return server.RemoteAddress;
default:
return server.ManualAddress || server.LocalAddress || server.RemoteAddress;
@ -35,9 +31,9 @@
}
};
globalScope.MediaBrowser.ConnectionManager = function (logger, credentialProvider, appName, appVersion, deviceName, deviceId, capabilities) {
var ConnectionManager = function (credentialProvider, appName, appVersion, deviceName, deviceId, capabilities, devicePixelRatio) {
logger.log('Begin MediaBrowser.ConnectionManager constructor');
console.log('Begin ConnectionManager constructor');
var self = this;
var apiClients = [];
@ -55,7 +51,7 @@
function resolveFailure(resolve) {
resolve({
State: MediaBrowser.ConnectionState.Unavailable,
State: ConnectionState.Unavailable,
ConnectUser: self.connectUser()
});
}
@ -122,7 +118,7 @@
function fetchWithTimeout(url, options, timeoutMs) {
logger.log('fetchWithTimeout: timeoutMs: ' + timeoutMs + ', url: ' + url);
console.log('fetchWithTimeout: timeoutMs: ' + timeoutMs + ', url: ' + url);
return new Promise(function (resolve, reject) {
@ -131,14 +127,14 @@
fetch(url, options).then(function (response) {
clearTimeout(timeout);
logger.log('fetchWithTimeout: succeeded connecting to url: ' + url);
console.log('fetchWithTimeout: succeeded connecting to url: ' + url);
resolve(response);
}, function (error) {
clearTimeout(timeout);
logger.log('fetchWithTimeout: timed out connecting to url: ' + url);
console.log('fetchWithTimeout: timed out connecting to url: ' + url);
reject();
});
@ -168,11 +164,11 @@
request.headers = request.headers || {};
logger.log('ConnectionManager requesting url: ' + request.url);
console.log('ConnectionManager requesting url: ' + request.url);
return getFetchPromise(request).then(function (response) {
logger.log('ConnectionManager response status: ' + response.status + ', url: ' + request.url);
console.log('ConnectionManager response status: ' + response.status + ', url: ' + request.url);
if (response.status < 400) {
@ -187,7 +183,7 @@
}, function (err) {
logger.log('ConnectionManager request failed to url: ' + request.url);
console.log('ConnectionManager request failed to url: ' + request.url);
throw err;
});
}
@ -196,7 +192,7 @@
url = getEmbyServerUrl(url, "system/info/public");
logger.log('tryConnect url: ' + url);
console.log('tryConnect url: ' + url);
return ajax({
@ -296,8 +292,8 @@
var existingServer = existingServers.length ? existingServers[0] : {};
existingServer.DateLastAccessed = new Date().getTime();
existingServer.LastConnectionMode = MediaBrowser.ConnectionMode.Manual;
if (existingServer.LastConnectionMode == MediaBrowser.ConnectionMode.Local) {
existingServer.LastConnectionMode = ConnectionMode.Manual;
if (existingServer.LastConnectionMode == ConnectionMode.Local) {
existingServer.DateLastLocalConnection = new Date().getTime();
}
existingServer.ManualAddress = apiClient.serverAddress();
@ -332,7 +328,7 @@
self.clearData = function () {
logger.log('connection manager clearing data');
console.log('connection manager clearing data');
connectUser = null;
var credentials = credentialProvider.credentials();
@ -354,9 +350,9 @@
if (!apiClient) {
var url = MediaBrowser.ServerInfo.getServerAddress(server, connectionMode);
var url = ServerInfo.getServerAddress(server, connectionMode);
apiClient = new MediaBrowser.ApiClient(logger, url, appName, appVersion, deviceName, deviceId);
apiClient = new apiClientFactory(url, appName, appVersion, deviceName, deviceId, devicePixelRatio);
apiClients.push(apiClient);
@ -369,7 +365,7 @@
Events.trigger(self, 'apiclientcreated', [apiClient]);
}
logger.log('returning instance from getOrAddApiClient');
console.log('returning instance from getOrAddApiClient');
return apiClient;
}
@ -402,7 +398,7 @@
if (options.updateDateLastAccessed !== false) {
server.DateLastAccessed = new Date().getTime();
if (server.LastConnectionMode == MediaBrowser.ConnectionMode.Local) {
if (server.LastConnectionMode == ConnectionMode.Local) {
server.DateLastLocalConnection = new Date().getTime();
}
}
@ -438,14 +434,14 @@
function afterConnected(apiClient, options) {
options = options || {};
if (options.reportCapabilities !== false) {
apiClient.reportCapabilities(capabilities);
}
if (options.enableWebSocket !== false) {
if (!apiClient.isWebSocketOpenOrConnecting && apiClient.isWebSocketSupported()) {
logger.log('calling apiClient.openWebSocket');
if (!apiClient.isWebSocketOpenOrConnecting() && apiClient.isWebSocketSupported()) {
console.log('calling apiClient.openWebSocket');
apiClient.openWebSocket();
}
@ -516,7 +512,7 @@
throw new Error("credentials.ConnectUserId cannot be null");
}
var url = MediaBrowser.ServerInfo.getServerAddress(server, connectionMode);
var url = ServerInfo.getServerAddress(server, connectionMode);
url = getEmbyServerUrl(url, "Connect/Exchange?format=json&ConnectUserId=" + credentials.ConnectUserId);
@ -547,7 +543,7 @@
return new Promise(function (resolve, reject) {
var url = MediaBrowser.ServerInfo.getServerAddress(server, connectionMode);
var url = ServerInfo.getServerAddress(server, connectionMode);
ajax({
@ -675,7 +671,7 @@
self.logout = function () {
Logger.log('begin connectionManager loguot');
console.log('begin connectionManager loguot');
var promises = [];
for (var i = 0, length = apiClients.length; i < length; i++) {
@ -743,7 +739,7 @@
function getConnectServers(credentials) {
logger.log('Begin getConnectServers');
console.log('Begin getConnectServers');
return new Promise(function (resolve, reject) {
@ -801,7 +797,7 @@
self.getAvailableServers = function () {
logger.log('Begin getAvailableServers');
console.log('Begin getAvailableServers');
// Clone the array
var credentials = credentialProvider.credentials();
@ -863,7 +859,7 @@
DateLastLocalConnection: new Date().getTime()
};
info.LastConnectionMode = info.ManualAddress ? MediaBrowser.ConnectionMode.Manual : MediaBrowser.ConnectionMode.Local;
info.LastConnectionMode = info.ManualAddress ? ConnectionMode.Manual : ConnectionMode.Local;
return info;
});
@ -897,7 +893,7 @@
self.connect = function () {
logger.log('Begin connect');
console.log('Begin connect');
return new Promise(function (resolve, reject) {
@ -918,7 +914,7 @@
self.connectToServers = function (servers) {
logger.log('Begin connectToServers, with ' + servers.length + ' servers');
console.log('Begin connectToServers, with ' + servers.length + ' servers');
return new Promise(function (resolve, reject) {
@ -926,14 +922,14 @@
self.connectToServer(servers[0]).then(function (result) {
if (result.State == MediaBrowser.ConnectionState.Unavailable) {
if (result.State == ConnectionState.Unavailable) {
result.State = result.ConnectUser == null ?
MediaBrowser.ConnectionState.ConnectSignIn :
MediaBrowser.ConnectionState.ServerSelection;
ConnectionState.ConnectSignIn :
ConnectionState.ServerSelection;
}
logger.log('resolving connectToServers with result.State: ' + result.State);
console.log('resolving connectToServers with result.State: ' + result.State);
resolve(result);
});
@ -945,14 +941,14 @@
if (firstServer) {
self.connectToServer(firstServer).then(function (result) {
if (result.State == MediaBrowser.ConnectionState.SignedIn) {
if (result.State == ConnectionState.SignedIn) {
resolve(result);
} else {
resolve({
Servers: servers,
State: (!servers.length && !self.connectUser()) ? MediaBrowser.ConnectionState.ConnectSignIn : MediaBrowser.ConnectionState.ServerSelection,
State: (!servers.length && !self.connectUser()) ? ConnectionState.ConnectSignIn : ConnectionState.ServerSelection,
ConnectUser: self.connectUser()
});
}
@ -962,7 +958,7 @@
resolve({
Servers: servers,
State: (!servers.length && !self.connectUser()) ? MediaBrowser.ConnectionState.ConnectSignIn : MediaBrowser.ConnectionState.ServerSelection,
State: (!servers.length && !self.connectUser()) ? ConnectionState.ConnectSignIn : ConnectionState.ServerSelection,
ConnectUser: self.connectUser()
});
}
@ -992,9 +988,9 @@
if (server.LastConnectionMode != null) {
//tests.push(server.LastConnectionMode);
}
if (tests.indexOf(MediaBrowser.ConnectionMode.Manual) == -1) { tests.push(MediaBrowser.ConnectionMode.Manual); }
if (tests.indexOf(MediaBrowser.ConnectionMode.Local) == -1) { tests.push(MediaBrowser.ConnectionMode.Local); }
if (tests.indexOf(MediaBrowser.ConnectionMode.Remote) == -1) { tests.push(MediaBrowser.ConnectionMode.Remote); }
if (tests.indexOf(ConnectionMode.Manual) == -1) { tests.push(ConnectionMode.Manual); }
if (tests.indexOf(ConnectionMode.Local) == -1) { tests.push(ConnectionMode.Local); }
if (tests.indexOf(ConnectionMode.Remote) == -1) { tests.push(ConnectionMode.Remote); }
beginWakeServer(server);
@ -1014,24 +1010,24 @@
if (index >= tests.length) {
logger.log('Tested all connection modes. Failing server connection.');
console.log('Tested all connection modes. Failing server connection.');
resolveFailure(resolve);
return;
}
var mode = tests[index];
var address = MediaBrowser.ServerInfo.getServerAddress(server, mode);
var address = ServerInfo.getServerAddress(server, mode);
var enableRetry = false;
var skipTest = false;
var timeout = defaultTimeout;
if (mode == MediaBrowser.ConnectionMode.Local) {
if (mode == ConnectionMode.Local) {
enableRetry = true;
timeout = 8000;
}
else if (mode == MediaBrowser.ConnectionMode.Manual) {
else if (mode == ConnectionMode.Manual) {
if (stringEqualsIgnoreCase(address, server.LocalAddress) ||
stringEqualsIgnoreCase(address, server.RemoteAddress)) {
@ -1044,16 +1040,16 @@
return;
}
logger.log('testing connection mode ' + mode + ' with server ' + server.Name);
console.log('testing connection mode ' + mode + ' with server ' + server.Name);
tryConnect(address, timeout).then(function (result) {
logger.log('calling onSuccessfulConnection with connection mode ' + mode + ' with server ' + server.Name);
console.log('calling onSuccessfulConnection with connection mode ' + mode + ' with server ' + server.Name);
onSuccessfulConnection(server, result, mode, options, resolve);
}, function () {
logger.log('test failed for connection mode ' + mode + ' with server ' + server.Name);
console.log('test failed for connection mode ' + mode + ' with server ' + server.Name);
if (enableRetry) {
@ -1117,7 +1113,7 @@
if (options.updateDateLastAccessed !== false) {
server.DateLastAccessed = new Date().getTime();
if (server.LastConnectionMode == MediaBrowser.ConnectionMode.Local) {
if (server.LastConnectionMode == ConnectionMode.Local) {
server.DateLastLocalConnection = new Date().getTime();
}
}
@ -1130,13 +1126,13 @@
result.ApiClient = getOrAddApiClient(server, connectionMode);
result.State = server.AccessToken ?
MediaBrowser.ConnectionState.SignedIn :
MediaBrowser.ConnectionState.ServerSignIn;
ConnectionState.SignedIn :
ConnectionState.ServerSignIn;
result.Servers.push(server);
result.ApiClient.updateServerInfo(server, connectionMode);
if (result.State == MediaBrowser.ConnectionState.SignedIn) {
if (result.State == ConnectionState.SignedIn) {
afterConnected(result.ApiClient, options);
}
@ -1173,17 +1169,17 @@
address = normalizeAddress(address);
function onFail() {
logger.log('connectToAddress ' + address + ' failed');
console.log('connectToAddress ' + address + ' failed');
resolveFailure(resolve);
}
tryConnect(address, defaultTimeout).then(function (publicInfo) {
logger.log('connectToAddress ' + address + ' succeeded');
console.log('connectToAddress ' + address + ' succeeded');
var server = {
ManualAddress: address,
LastConnectionMode: MediaBrowser.ConnectionMode.Manual
LastConnectionMode: ConnectionMode.Manual
};
updateServerInfo(server, publicInfo);
@ -1207,9 +1203,9 @@
return;
}
require(['connectservice', 'cryptojs-md5'], function () {
require(['connectservice', 'cryptojs-md5'], function (connectservice) {
var md5 = self.getConnectPasswordHash(password);
var md5 = getConnectPasswordHash(connectservice, password);
ajax({
type: "POST",
@ -1267,9 +1263,9 @@
return;
}
require(['connectservice', 'cryptojs-md5'], function () {
require(['connectservice', 'cryptojs-md5'], function (connectservice) {
var md5 = self.getConnectPasswordHash(password);
var md5 = getConnectPasswordHash(connectservice, password);
ajax({
type: "POST",
@ -1306,12 +1302,12 @@
});
};
self.getConnectPasswordHash = function (password) {
function getConnectPasswordHash(connectService, password) {
password = globalScope.MediaBrowser.ConnectService.cleanPassword(password);
password = connectService.cleanPassword(password);
return CryptoJS.MD5(password).toString();
};
}
self.getApiClient = function (item) {
@ -1511,4 +1507,10 @@
return self;
};
})(window, window.Logger);
return {
ConnectionState: ConnectionState,
ConnectionMode: ConnectionMode,
ServerInfo: ServerInfo,
ConnectionManager: ConnectionManager
};
});

View file

@ -1,15 +1,6 @@
(function (globalScope) {
define([], function () {
if (!globalScope.MediaBrowser) {
globalScope.MediaBrowser = {};
}
function replaceAll(str, find, replace) {
return str.split(find).join(replace);
}
var connectService = {
return {
cleanPassword: function (password) {
@ -26,9 +17,5 @@
return password;
}
};
globalScope.MediaBrowser.ConnectService = connectService;
})(window);
});

View file

@ -1,10 +1,6 @@
(function (globalScope, JSON) {
define(['events'], function (Events) {
if (!globalScope.MediaBrowser) {
globalScope.MediaBrowser = {};
}
globalScope.MediaBrowser.CredentialProvider = function (key) {
return function (key) {
var self = this;
var credentials = null;
@ -16,7 +12,7 @@
var json = appStorage.getItem(key) || '{}';
Logger.log('credentials initialized with: ' + json);
console.log('credentials initialized with: ' + json);
credentials = JSON.parse(json);
credentials.Servers = credentials.Servers || [];
}
@ -127,5 +123,4 @@
}
};
};
})(window, window.JSON);
});

View file

@ -1,20 +1,61 @@
(function (globalScope) {
define([], function () {
globalScope.Events = {
function getCallbacks(obj, name) {
on: function (obj, eventName, selector, fn) {
if (!obj) {
throw new Error("obj cannot be null!");
}
jQuery(obj).on(eventName, selector, fn);
obj._callbacks = obj._callbacks || {};
var list = obj._callbacks[name];
if (!list) {
obj._callbacks[name] = [];
list = obj._callbacks[name];
}
return list;
}
return {
on: function (obj, eventName, fn) {
var list = getCallbacks(obj, eventName);
list.push(fn);
},
off: function (obj, eventName, selector, fn) {
off: function (obj, eventName, fn) {
jQuery(obj).off(eventName, selector, fn);
var list = getCallbacks(obj, eventName);
var i = list.indexOf(fn);
if (i != -1) {
list.splice(i, 1);
}
},
trigger: function (obj, eventName, params) {
jQuery(obj).trigger(eventName, params);
trigger: function (obj, eventName) {
var eventObject = {
type: eventName
};
var eventArgs = [];
eventArgs.push(eventObject);
var additionalArgs = arguments[2] || [];
for (var i = 0, length = additionalArgs.length; i < length; i++) {
eventArgs.push(additionalArgs[i]);
}
var callbacks = getCallbacks(obj, eventName).slice(0);
callbacks.forEach(function (c) {
c.apply(obj, eventArgs);
});
}
};
})(window);
});

View file

@ -1,6 +0,0 @@
var Logger = {
log: function (str) {
console.log(str);
}
};

View file

@ -21,7 +21,7 @@
photos = getFilesToUpload(photos, uploadHistory);
Logger.log('Found ' + photos.length + ' files to upload');
console.log('Found ' + photos.length + ' files to upload');
uploadNext(photos, 0, server, apiClient, deferred);
@ -91,16 +91,16 @@
api_key: apiClient.accessToken()
});
Logger.log('Uploading file to ' + url);
console.log('Uploading file to ' + url);
new MediaBrowser.FileUpload().upload(file, name, url).then(function () {
Logger.log('File upload succeeded');
console.log('File upload succeeded');
deferred.resolve();
}, function () {
Logger.log('File upload failed');
console.log('File upload failed');
deferred.reject();
});
});

View file

@ -34,7 +34,7 @@
function reportOfflineActions(apiClient, serverInfo) {
Logger.log('Begin reportOfflineActions');
console.log('Begin reportOfflineActions');
var deferred = DeferredBuilder.Deferred();
@ -65,7 +65,7 @@
function syncData(apiClient, serverInfo, syncUserItemAccess) {
Logger.log('Begin syncData');
console.log('Begin syncData');
var deferred = DeferredBuilder.Deferred();
@ -93,7 +93,7 @@
function afterSyncData(apiClient, serverInfo, enableSyncUserItemAccess, syncDataResult, deferred) {
Logger.log('Begin afterSyncData');
console.log('Begin afterSyncData');
removeLocalItems(syncDataResult, serverInfo.Id).then(function (result) {
@ -115,7 +115,7 @@
function removeLocalItems(syncDataResult, serverId) {
Logger.log('Begin removeLocalItems');
console.log('Begin removeLocalItems');
var deferred = DeferredBuilder.Deferred();
@ -144,7 +144,7 @@
function removeLocalItem(itemId, serverId) {
Logger.log('Begin removeLocalItem');
console.log('Begin removeLocalItem');
var deferred = DeferredBuilder.Deferred();
@ -162,7 +162,7 @@
function getNewMedia(apiClient, serverInfo, options) {
Logger.log('Begin getNewMedia');
console.log('Begin getNewMedia');
var deferred = DeferredBuilder.Deferred();
@ -199,7 +199,7 @@
function getNewItem(jobItem, apiClient, serverInfo, options) {
Logger.log('Begin getNewItem');
console.log('Begin getNewItem');
var deferred = DeferredBuilder.Deferred();
@ -239,7 +239,7 @@
function downloadMedia(apiClient, jobItem, localItem, options) {
Logger.log('Begin downloadMedia');
console.log('Begin downloadMedia');
var deferred = DeferredBuilder.Deferred();
require(['localassetmanager'], function () {
@ -250,7 +250,7 @@
var localPath = localItem.LocalPath;
Logger.log('Downloading media. Url: ' + url + '. Local path: ' + localPath);
console.log('Downloading media. Url: ' + url + '. Local path: ' + localPath);
options = options || {};
@ -275,7 +275,7 @@
function getImages(apiClient, jobItem, localItem) {
Logger.log('Begin getImages');
console.log('Begin getImages');
var deferred = DeferredBuilder.Deferred();
getNextImage(0, apiClient, localItem, deferred);
@ -285,7 +285,7 @@
function getNextImage(index, apiClient, localItem, deferred) {
Logger.log('Begin getNextImage');
console.log('Begin getNextImage');
if (index >= 4) {
deferred.resolve();
@ -347,7 +347,7 @@
function downloadImage(apiClient, serverId, itemId, imageTag, imageType) {
Logger.log('Begin downloadImage');
console.log('Begin downloadImage');
var deferred = DeferredBuilder.Deferred();
require(['localassetmanager'], function () {
@ -379,13 +379,13 @@
function getSubtitles(apiClient, jobItem, localItem) {
Logger.log('Begin getSubtitles');
console.log('Begin getSubtitles');
var deferred = DeferredBuilder.Deferred();
require(['localassetmanager'], function () {
if (!jobItem.Item.MediaSources.length) {
logger.Error("Cannot download subtitles because video has no media source info.");
console.log("Cannot download subtitles because video has no media source info.");
deferred.resolve();
return;
}
@ -423,7 +423,7 @@
function getItemSubtitle(file, apiClient, jobItem, localItem, mediaSource) {
Logger.log('Begin getItemSubtitle');
console.log('Begin getItemSubtitle');
var deferred = DeferredBuilder.Deferred();
var subtitleStream = mediaSource.MediaStreams.filter(function (m) {
@ -433,7 +433,7 @@
if (!subtitleStream) {
// We shouldn't get in here, but let's just be safe anyway
Logger.log("Cannot download subtitles because matching stream info wasn't found.");
console.log("Cannot download subtitles because matching stream info wasn't found.");
deferred.reject();
return;
}
@ -459,7 +459,7 @@
}
function syncUserItemAccess(syncDataResult, serverId) {
Logger.log('Begin syncUserItemAccess');
console.log('Begin syncUserItemAccess');
var deferred = DeferredBuilder.Deferred();
@ -492,7 +492,7 @@
}
function syncUserAccessForItem(itemId, syncDataResult) {
Logger.log('Begin syncUserAccessForItem');
console.log('Begin syncUserAccessForItem');
var deferred = DeferredBuilder.Deferred();

View file

@ -6,38 +6,37 @@
self.sync = function (options) {
var deferred = DeferredBuilder.Deferred();
return new Promise(function (resolve, reject) {
var servers = connectionManager.getSavedServers();
var servers = connectionManager.getSavedServers();
syncNext(servers, 0, options, deferred);
return deferred.promise();
syncNext(servers, 0, options, resolve, reject);
});
};
function syncNext(servers, index, options, deferred) {
function syncNext(servers, index, options, resolve, reject) {
var length = servers.length;
if (index >= length) {
deferred.resolve();
resolve();
return;
}
var server = servers[index];
Logger.log("Creating ServerSync to server: " + server.Id);
console.log("Creating ServerSync to server: " + server.Id);
require(['serversync'], function () {
new MediaBrowser.ServerSync(connectionManager).sync(server, options).then(function () {
syncNext(servers, index + 1, options, deferred);
syncNext(servers, index + 1, options, resolve, reject);
}, function () {
syncNext(servers, index + 1, options, deferred);
syncNext(servers, index + 1, options, resolve, reject);
});
});
}

View file

@ -6,62 +6,51 @@
self.sync = function (apiClient, server) {
var deferred = DeferredBuilder.Deferred();
return new Promise(function (resolve, reject) {
var users = server.Users || [];
syncNext(users, 0, deferred, apiClient, server);
return deferred.promise();
var users = server.Users || [];
syncNext(users, 0, resolve, reject, apiClient, server);
});
};
function syncNext(users, index, deferred, apiClient, server) {
function syncNext(users, index, resolve, reject, apiClient, server) {
var length = users.length;
if (index >= length) {
deferred.resolve();
resolve();
return;
}
syncUser(users[index], apiClient).then(function () {
var onFinish = function() {
syncNext(users, index + 1, resolve, reject, apiClient, server);
};
syncNext(users, index + 1, deferred, apiClient, server);
}, function () {
syncNext(users, index + 1, deferred, apiClient, server);
});
syncUser(users[index], apiClient).then(onFinish, onFinish);
}
function syncUser(user, apiClient) {
var deferred = DeferredBuilder.Deferred();
return new Promise(function (resolve, reject) {
apiClient.getOfflineUser(user.Id).then(function (result) {
apiClient.getOfflineUser(user.Id).then(function (result) {
require(['localassetmanager'], function () {
require(['localassetmanager'], function () {
LocalAssetManager.saveOfflineUser(result).then(function () {
deferred.resolve();
}, function () {
deferred.resolve();
LocalAssetManager.saveOfflineUser(result).then(resolve, resolve);
});
});
}, function () {
}, function () {
// TODO: We should only delete if there's a 401 response
// TODO: We should only delete if there's a 401 response
require(['localassetmanager'], function () {
require(['localassetmanager'], function () {
LocalAssetManager.deleteOfflineUser(user.Id).then(function () {
deferred.resolve();
}, function () {
deferred.resolve();
LocalAssetManager.deleteOfflineUser(user.Id).then(resolve, resolve);
});
});
});
return deferred.promise();
}
}

View file

@ -6,13 +6,13 @@
self.sync = function (server, options) {
var deferred = DeferredBuilder.Deferred();
if (!server.AccessToken && !server.ExchangeToken) {
Logger.log('Skipping sync to server ' + server.Id + ' because there is no saved authentication information.');
deferred.resolve();
return deferred.promise();
console.log('Skipping sync to server ' + server.Id + ' because there is no saved authentication information.');
return new Promise(function (resolve, reject) {
resolve();
});
}
var connectionOptions = {
@ -21,31 +21,25 @@
reportCapabilities: false
};
connectionManager.connectToServer(server, connectionOptions).then(function (result) {
return connectionManager.connectToServer(server, connectionOptions).then(function (result) {
if (result.State == MediaBrowser.ConnectionState.SignedIn) {
performSync(server, options, deferred);
return performSync(server, options);
} else {
Logger.log('Unable to connect to server id: ' + server.Id);
deferred.reject();
console.log('Unable to connect to server id: ' + server.Id);
return Promise.reject();
}
}, function () {
}, function (err) {
Logger.log('Unable to connect to server id: ' + server.Id);
deferred.reject();
console.log('Unable to connect to server id: ' + server.Id);
throw err;
});
return deferred.promise();
};
function performSync(server, options, deferred) {
function performSync(server, options) {
Logger.log("Creating ContentUploader to server: " + server.Id);
var nextAction = function () {
syncOfflineUsers(server, options, deferred);
};
console.log("Creating ContentUploader to server: " + server.Id);
options = options || {};
@ -56,70 +50,77 @@
}
if (!uploadPhotos) {
nextAction();
return;
return syncOfflineUsers(server, options);
}
require(['contentuploader'], function () {
return new Promise(function (resolve, reject) {
new MediaBrowser.ContentUploader(connectionManager).uploadImages(server).then(function () {
require(['contentuploader'], function () {
Logger.log("ContentUploaded succeeded to server: " + server.Id);
new MediaBrowser.ContentUploader(connectionManager).uploadImages(server).then(function () {
nextAction();
console.log("ContentUploaded succeeded to server: " + server.Id);
}, function () {
syncOfflineUsers(server, options).then(resolve, reject);
Logger.log("ContentUploaded failed to server: " + server.Id);
}, function () {
nextAction();
console.log("ContentUploaded failed to server: " + server.Id);
syncOfflineUsers(server, options).then(resolve, reject);
});
});
});
}
function syncOfflineUsers(server, options, deferred) {
function syncOfflineUsers(server, options) {
if (options.syncOfflineUsers === false) {
syncMedia(server, options, deferred);
return;
return syncMedia(server, options);
}
require(['offlineusersync'], function () {
return new Promise(function (resolve, reject) {
var apiClient = connectionManager.getApiClient(server.Id);
require(['offlineusersync'], function () {
new MediaBrowser.OfflineUserSync().sync(apiClient, server).then(function () {
var apiClient = connectionManager.getApiClient(server.Id);
Logger.log("OfflineUserSync succeeded to server: " + server.Id);
new MediaBrowser.OfflineUserSync().sync(apiClient, server).then(function () {
syncMedia(server, options, deferred);
console.log("OfflineUserSync succeeded to server: " + server.Id);
}, function () {
syncMedia(server, options).then(resolve, reject);
Logger.log("OfflineUserSync failed to server: " + server.Id);
}, function () {
deferred.reject();
console.log("OfflineUserSync failed to server: " + server.Id);
reject();
});
});
});
}
function syncMedia(server, options, deferred) {
function syncMedia(server, options) {
require(['mediasync'], function () {
return new Promise(function (resolve, reject) {
var apiClient = connectionManager.getApiClient(server.Id);
require(['mediasync'], function () {
new MediaBrowser.MediaSync().sync(apiClient, server, options).then(function () {
var apiClient = connectionManager.getApiClient(server.Id);
Logger.log("MediaSync succeeded to server: " + server.Id);
new MediaBrowser.MediaSync().sync(apiClient, server, options).then(function () {
deferred.resolve();
console.log("MediaSync succeeded to server: " + server.Id);
}, function () {
resolve();
Logger.log("MediaSync failed to server: " + server.Id);
}, function () {
deferred.reject();
console.log("MediaSync failed to server: " + server.Id);
reject();
});
});
});
}

View file

@ -1,20 +1,19 @@
{
"name": "hammerjs",
"version": "2.0.4",
"main": "hammer.js",
"ignore": [
"tests",
"src"
],
"homepage": "https://github.com/hammerjs/hammer.js",
"_release": "2.0.4",
"version": "2.0.5",
"_release": "2.0.5",
"_resolution": {
"type": "version",
"tag": "2.0.4",
"commit": "7fc11efb37d6f2334ce957e26e9cf53690e10fa5"
"tag": "v2.0.5",
"commit": "4ac915029353faf7cbe3ac9252d84a2621772f85"
},
"_source": "git://github.com/hammerjs/hammer.js.git",
"_target": "~2.0.4",
"_originalSource": "hammer.js",
"_direct": true
"_originalSource": "hammer.js"
}

View file

@ -1,8 +1,95 @@
{
"preset": "google",
"excludeFiles": [
"*.js",
"tests/**/assets",
"node_modules/**"
]
}
"excludeFiles": [
"*.js",
"tests/**/assets",
"node_modules/**"
],
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireOperatorBeforeLineBreak": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"maximumLineLength": {
"value": 120,
"allowComments": true,
"allowRegex": true
},
"validateIndentation": 4,
"validateQuoteMarks": "'",
"disallowMultipleLineStrings": true,
"disallowMixedSpacesAndTabs": true,
"disallowTrailingWhitespace": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"return",
"try",
"catch"
],
"requireSpaceBeforeBinaryOperators": [
"=",
"+=",
"-=",
"*=",
"/=",
"%=",
"<<=",
">>=",
">>>=",
"&=",
"|=",
"^=",
"+=",
"+",
"-",
"*",
"/",
"%",
"<<",
">>",
">>>",
"&",
"|",
"^",
"&&",
"||",
"===",
"==",
">=",
"<=",
"<",
">",
"!=",
"!=="
],
"requireSpaceAfterBinaryOperators": true,
"requireSpacesInConditionalExpression": true,
"requireSpaceBeforeBlockStatements": true,
"requireLineFeedAtFileEnd": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideObjectBrackets": "all",
"disallowSpacesInsideArrayBrackets": "all",
"disallowSpacesInsideParentheses": true,
"validateJSDoc": {
"checkParamNames": true,
"requireParamTypes": true
},
"disallowMultipleLineBreaks": true,
"disallowNewlineBeforeBlockStatements": true
}

View file

@ -2,6 +2,8 @@ language: node_js
node_js:
- "0.10"
sudo: false
before_script:
- npm install -g grunt-cli

View file

@ -19,7 +19,7 @@ module.exports = (grunt) ->
concat:
build:
src: [
'src/hammer.prefix'
'src/hammer.prefix.js'
'src/utils.js'
'src/input.js'
'src/input/*.js'
@ -29,7 +29,7 @@ module.exports = (grunt) ->
'src/hammer.js'
'src/manager.js'
'src/expose.js'
'src/hammer.suffix']
'src/hammer.suffix.js']
dest: 'hammer.js'
uglify:
@ -80,8 +80,9 @@ module.exports = (grunt) ->
jscs:
src: [
'src/**/*.js'
'tests/unit/*.js'
'src/**/*.js',
'!src/hammer.prefix.js',
'!src/hammer.suffix.js'
]
options:
config: "./.jscsrc"
@ -113,7 +114,7 @@ module.exports = (grunt) ->
grunt.loadNpmTasks 'grunt-contrib-connect'
grunt.loadNpmTasks 'grunt-string-replace'
grunt.loadNpmTasks 'grunt-banner'
grunt.loadNpmTasks 'grunt-jscs-checker'
grunt.loadNpmTasks 'grunt-jscs'
# Default task(s)
grunt.registerTask 'default', ['connect', 'watch']

View file

@ -1,6 +1,5 @@
{
"name": "hammerjs",
"version": "2.0.4",
"main": "hammer.js",
"ignore": [
"tests",

View file

@ -1,12 +1,12 @@
/*! Hammer.JS - v2.0.4 - 2014-09-28
/*! Hammer.JS - v2.0.4 - 2015-12-22
* http://hammerjs.github.io/
*
* Copyright (c) 2014 Jorik Tangelder;
* Licensed under the MIT license */
* Copyright (c) 2015 Jorik Tangelder;
* Licensed under the license */
(function(window, document, exportName, undefined) {
'use strict';
var VENDOR_PREFIXES = ['', 'webkit', 'moz', 'MS', 'ms', 'o'];
var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
var TEST_ELEMENT = document.createElement('div');
var TYPE_FUNCTION = 'function';
@ -320,8 +320,8 @@ function uniqueId() {
* @returns {DocumentView|Window}
*/
function getWindowForElement(element) {
var doc = element.ownerDocument;
return (doc.defaultView || doc.parentWindow);
var doc = element.ownerDocument || element;
return (doc.defaultView || doc.parentWindow || window);
}
var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
@ -500,9 +500,17 @@ function computeInputData(manager, input) {
computeDeltaXY(session, input);
input.offsetDirection = getDirection(input.deltaX, input.deltaY);
var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
input.overallVelocityX = overallVelocity.x;
input.overallVelocityY = overallVelocity.y;
input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;
input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);
computeIntervalInputData(session, input);
// find the correct target
@ -546,8 +554,8 @@ function computeIntervalInputData(session, input) {
velocity, velocityX, velocityY, direction;
if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
var deltaX = last.deltaX - input.deltaX;
var deltaY = last.deltaY - input.deltaY;
var deltaX = input.deltaX - last.deltaX;
var deltaY = input.deltaY - last.deltaY;
var v = getVelocity(deltaTime, deltaX, deltaY);
velocityX = v.x;
@ -652,9 +660,9 @@ function getDirection(x, y) {
}
if (abs(x) >= abs(y)) {
return x > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
}
return y > 0 ? DIRECTION_UP : DIRECTION_DOWN;
return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
}
/**
@ -697,7 +705,7 @@ function getAngle(p1, p2, props) {
* @return {Number} rotation
*/
function getRotation(start, end) {
return getAngle(end[1], end[0], PROPS_CLIENT_XY) - getAngle(start[1], start[0], PROPS_CLIENT_XY);
return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
}
/**
@ -790,7 +798,7 @@ var POINTER_ELEMENT_EVENTS = 'pointerdown';
var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
// IE10 has prefixed support, and case-sensitive
if (window.MSPointerEvent) {
if (window.MSPointerEvent && !window.PointerEvent) {
POINTER_ELEMENT_EVENTS = 'MSPointerDown';
POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
}
@ -1114,7 +1122,7 @@ TouchAction.prototype = {
value = this.compute();
}
if (NATIVE_TOUCH_ACTION) {
if (NATIVE_TOUCH_ACTION && this.manager.element.style) {
this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
}
this.actions = value.toLowerCase().trim();
@ -1165,6 +1173,23 @@ TouchAction.prototype = {
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
if (hasNone) {
//do not prevent defaults if this is a tap gesture
var isTapPointer = input.pointers.length === 1;
var isTapMovement = input.distance < 2;
var isTapTouchTime = input.deltaTime < 250;
if (isTapPointer && isTapMovement && isTapTouchTime) {
return;
}
}
if (hasPanX && hasPanY) {
// `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
return;
}
if (hasNone ||
(hasPanY && direction & DIRECTION_HORIZONTAL) ||
(hasPanX && direction & DIRECTION_VERTICAL)) {
@ -1196,9 +1221,12 @@ function cleanTouchActions(actions) {
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
// pan-x and pan-y can be combined
// if both pan-x and pan-y are set (different recognizers
// for different directions, e.g. horizontal pan but vertical swipe?)
// we need none (as otherwise with pan-x pan-y combined none of these
// recognizers will work, since the browser would handle all panning
if (hasPanX && hasPanY) {
return TOUCH_ACTION_PAN_X + ' ' + TOUCH_ACTION_PAN_Y;
return TOUCH_ACTION_NONE;
}
// pan-x OR pan-y
@ -1256,10 +1284,13 @@ var STATE_FAILED = 32;
* @param {Object} options
*/
function Recognizer(options) {
// make sure, options are copied over to a new object to prevent leaking it outside
options = extend({}, options || {});
this.id = uniqueId();
this.manager = null;
this.options = merge(options || {}, this.defaults);
this.options = merge(options, this.defaults);
// default is enable true
this.options.enable = ifUndefined(this.options.enable, true);
@ -1387,20 +1418,24 @@ Recognizer.prototype = {
var self = this;
var state = this.state;
function emit(withState) {
self.manager.emit(self.options.event + (withState ? stateStr(state) : ''), input);
function emit(event) {
self.manager.emit(event, input);
}
// 'panstart' and 'panmove'
if (state < STATE_ENDED) {
emit(true);
emit(self.options.event + stateStr(state));
}
emit(); // simple 'eventName' events
emit(self.options.event); // simple 'eventName' events
if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)
emit(input.additionalEvent);
}
// panend and pancancel
if (state >= STATE_ENDED) {
emit(true);
emit(self.options.event + stateStr(state));
}
},
@ -1665,14 +1700,15 @@ inherit(PanRecognizer, AttrRecognizer, {
},
emit: function(input) {
this.pX = input.deltaX;
this.pY = input.deltaY;
var direction = directionStr(input.direction);
if (direction) {
this.manager.emit(this.options.event + direction, input);
}
if (direction) {
input.additionalEvent = this.options.event + direction;
}
this._super.emit.call(this, input);
}
});
@ -1708,11 +1744,11 @@ inherit(PinchRecognizer, AttrRecognizer, {
},
emit: function(input) {
this._super.emit.call(this, input);
if (input.scale !== 1) {
var inOut = input.scale < 1 ? 'in' : 'out';
this.manager.emit(this.options.event + inOut, input);
input.additionalEvent = this.options.event + inOut;
}
this._super.emit.call(this, input);
}
});
@ -1737,8 +1773,8 @@ inherit(PressRecognizer, Recognizer, {
defaults: {
event: 'press',
pointers: 1,
time: 500, // minimal time of the pointer to be pressed
threshold: 5 // a minimal movement is ok, but keep it low
time: 251, // minimal time of the pointer to be pressed
threshold: 9 // a minimal movement is ok, but keep it low
},
getTouchAction: function() {
@ -1836,7 +1872,7 @@ inherit(SwipeRecognizer, AttrRecognizer, {
defaults: {
event: 'swipe',
threshold: 10,
velocity: 0.65,
velocity: 0.3,
direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
pointers: 1
},
@ -1850,21 +1886,22 @@ inherit(SwipeRecognizer, AttrRecognizer, {
var velocity;
if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
velocity = input.velocity;
velocity = input.overallVelocity;
} else if (direction & DIRECTION_HORIZONTAL) {
velocity = input.velocityX;
velocity = input.overallVelocityX;
} else if (direction & DIRECTION_VERTICAL) {
velocity = input.velocityY;
velocity = input.overallVelocityY;
}
return this._super.attrTest.call(this, input) &&
direction & input.direction &&
direction & input.offsetDirection &&
input.distance > this.options.threshold &&
input.maxPointers == this.options.pointers &&
abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
},
emit: function(input) {
var direction = directionStr(input.direction);
var direction = directionStr(input.offsetDirection);
if (direction) {
this.manager.emit(this.options.event + direction, input);
}
@ -1907,7 +1944,7 @@ inherit(TapRecognizer, Recognizer, {
taps: 1,
interval: 300, // max time between the multi-tap taps
time: 250, // max time of the pointer to be down (like finger on the screen)
threshold: 2, // a minimal movement is ok, but keep it low
threshold: 9, // a minimal movement is ok, but keep it low
posThreshold: 10 // a multi-tap can be a bit off the initial position
},
@ -1981,7 +2018,7 @@ inherit(TapRecognizer, Recognizer, {
},
emit: function() {
if (this.state == STATE_RECOGNIZED ) {
if (this.state == STATE_RECOGNIZED) {
this._input.tapCount = this.count;
this.manager.emit(this.options.event, this._input);
}
@ -1989,7 +2026,7 @@ inherit(TapRecognizer, Recognizer, {
});
/**
* Simple way to create an manager with a default set of recognizers.
* Simple way to create a manager with a default set of recognizers.
* @param {HTMLElement} element
* @param {Object} [options]
* @constructor
@ -2055,12 +2092,12 @@ Hammer.defaults = {
*/
preset: [
// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
[RotateRecognizer, { enable: false }],
[PinchRecognizer, { enable: false }, ['rotate']],
[SwipeRecognizer,{ direction: DIRECTION_HORIZONTAL }],
[PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ['swipe']],
[RotateRecognizer, {enable: false}],
[PinchRecognizer, {enable: false}, ['rotate']],
[SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],
[PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],
[TapRecognizer],
[TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']],
[TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],
[PressRecognizer]
],
@ -2127,9 +2164,9 @@ var FORCED_STOP = 2;
* @constructor
*/
function Manager(element, options) {
options = options || {};
var newOptions = options ? extend({}, options) : {};
this.options = merge(newOptions, Hammer.defaults);
this.options = merge(options, Hammer.defaults);
this.options.inputTarget = this.options.inputTarget || element;
this.handlers = {};
@ -2142,7 +2179,7 @@ function Manager(element, options) {
toggleCssProps(this, true);
each(options.recognizers, function(item) {
each(this.options.recognizers, function(item) {
var recognizer = this.add(new (item[0])(item[1]));
item[2] && recognizer.recognizeWith(item[2]);
item[3] && recognizer.requireFailure(item[3]);
@ -2290,11 +2327,19 @@ Manager.prototype = {
return this;
}
var recognizers = this.recognizers;
recognizer = this.get(recognizer);
recognizers.splice(inArray(recognizers, recognizer), 1);
this.touchAction.update();
// let's make sure this recognizer exists
if (recognizer) {
var recognizers = this.recognizers;
var index = inArray(recognizers, recognizer);
if (index !== -1) {
recognizers.splice(index, 1);
this.touchAction.update();
}
}
return this;
},
@ -2325,7 +2370,7 @@ Manager.prototype = {
if (!handler) {
delete handlers[event];
} else {
handlers[event].splice(inArray(handlers[event], handler), 1);
handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
}
});
return this;
@ -2381,6 +2426,9 @@ Manager.prototype = {
*/
function toggleCssProps(manager, add) {
var element = manager.element;
if (!element.style) {
return;
}
each(manager.options.cssProps, function(value, name) {
element.style[prefixed(element.style, name)] = add ? value : '';
});
@ -2450,7 +2498,12 @@ extend(Hammer, {
prefixed: prefixed
});
if (typeof define == TYPE_FUNCTION && define.amd) {
// this prevents errors when Hammer is loaded in the presence of an AMD
// style loader but by script tag, not by the loader.
var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
freeGlobal.Hammer = Hammer;
if (typeof define === 'function' && define.amd) {
define(function() {
return Hammer;
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2,14 +2,9 @@
"name": "hammerjs",
"title": "Hammer.JS",
"description": "A javascript library for multi-touch gestures",
"version": "2.0.4",
"version": "2.0.5",
"homepage": "http://hammerjs.github.io/",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/hammerjs/hammer.js/blob/master/LICENSE.md"
}
],
"license": "MIT",
"keywords": [
"touch",
"gestures"
@ -35,9 +30,9 @@
"grunt-contrib-qunit": "^0.5.1",
"grunt-contrib-uglify": "0.4.x",
"grunt-contrib-watch": "0.6.x",
"grunt-jscs-checker": "^0.4.1",
"grunt-jscs": "^0.8.0",
"grunt-string-replace": "^0.2.7",
"hammer-jquery": "git://github.com/hammerjs/jquery.hammer.js#master",
"jquery-hammerjs": "2.0.x",
"hammer-simulator": "git://github.com/hammerjs/simulator#master"
},
"main": "hammer.js",

View file

@ -1,6 +1,6 @@
{
"name": "hls.js",
"version": "0.3.11",
"version": "0.3.15",
"description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js",
"authors": [
@ -15,14 +15,13 @@
"test",
"tests"
],
"_release": "0.3.11",
"_release": "0.3.15",
"_resolution": {
"type": "version",
"tag": "v0.3.11",
"commit": "4e698e4adc4e1e0fa80ef9c8334a5ef382bbe347"
"tag": "v0.3.15",
"commit": "d3ecf55b89063d7ba3bd70800d5839755b0c7e63"
},
"_source": "git://github.com/dailymotion/hls.js.git",
"_target": "~0.3.11",
"_originalSource": "dailymotion/hls.js",
"_direct": true
"_originalSource": "dailymotion/hls.js"
}

View file

@ -197,7 +197,7 @@ configuration parameters could be provided to hls.js upon instantiation of Hls O
manifestLoadingRetryDelay : 500,
fpsDroppedMonitoringPeriod : 5000,
fpsDroppedMonitoringThreshold : 0.2,
appendErrorMaxRetry : 200,
appendErrorMaxRetry : 3,
loader : customLoader,
fLoader: customFragmentLoader,
pLoader: customPlaylistLoader,
@ -275,7 +275,7 @@ any I/O error will trigger retries every 500ms,1s,2s,4s,8s, ... capped to 64s (e
max nb of append retry
#### ```appendErrorMaxRetry```
(default 200)
(default 3)
max number of sourceBuffer.appendBuffer() retry upon error.
such error could happen in loop with UHD streams, when internal buffer is full. (Quota Exceeding Error will be triggered). in that case we need to wait for the browser to evict some data before being able to append buffer correctly.

View file

@ -1,6 +1,6 @@
{
"name": "hls.js",
"version": "0.3.11",
"version": "0.3.15",
"description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js",
"authors": [

View file

@ -72,8 +72,9 @@ header {
<div id="customButtons"></div>
<select id="streamSelect" class="innerControls"><option value="" selected>(Enter custom URL below)</option></select>
<input id="streamURL" class="innerControls" type=text value=""/>
<label class="innerControls"><input id="enableStream" type=checkbox checked/> Enable Streaming</label>
<label class="innerControls"><input id="enableStreaming" type=checkbox checked/> Enable Streaming</label>
<label class="innerControls"><input id="autoRecoverError" type=checkbox checked/> Auto-Recover Media Error</label>
<label class="innerControls"><input id="enableWorker" type=checkbox checked/> Enable Worker</label>
<div id="StreamPermalink" class="innerControls"></div>
<div>
<select id="videoSize" style="float:left">
@ -201,21 +202,25 @@ $(document).ready(function() {
$("#StatsDisplay").hide();
$('#metricsButtonWindow').toggle(windowSliding);
$('#metricsButtonFixed').toggle(!windowSliding);
$('#enableStream').click(function() { enableStreaming = this.checked; loadStream($('#streamURL').val());});
$('#autoRecoverError').prop( "checked", true );
$('#autoRecoverError').click(function() { autoRecoverError = this.checked; });
$('#enableStreaming').click(function() { enableStreaming = this.checked; loadStream($('#streamURL').val()); });
$('#autoRecoverError').click(function() { autoRecoverError = this.checked; updatePermalink();});
$('#enableWorker').click(function() { enableWorker = this.checked; updatePermalink();});
$('#enableStreaming').prop( "checked", enableStreaming );
$('#autoRecoverError').prop( "checked", autoRecoverError );
$('#enableWorker').prop( "checked", enableWorker );
});
'use strict';
var hls,events, stats, enableStreaming = true, autoRecoverError = true;
var hls,events, stats,
enableStreaming = JSON.parse(getURLParam('enableStreaming',true))
autoRecoverError = JSON.parse(getURLParam('autoRecoverError',true)),
enableWorker = JSON.parse(getURLParam('enableWorker',true));
var video = $('#video')[0];
video.volume = 0.05;
var manifest = decodeURIComponent(location.search.split('src=')[1]);
if(manifest === 'undefined') {
manifest = 'http://www.streambox.fr/playlists/x36xhzz/x36xhzz.m3u8';
}
loadStream(manifest);
loadStream(decodeURIComponent(getURLParam('src','http://www.streambox.fr/playlists/x36xhzz/x36xhzz.m3u8')));
function loadStream(url) {
hideCanvas();
@ -230,10 +235,7 @@ $(document).ready(function() {
}
$('#streamURL').val(url);
var hlsLink = document.URL.split('?')[0] + '?src=' + encodeURIComponent(url);
var description = 'permalink: ' + "<a href=\"" + hlsLink + "\">" + hlsLink + "</a>";
$("#StreamPermalink").html(description);
updatePermalink();
if(!enableStreaming) {
$("#HlsStatus").text("Streaming disabled");
return;
@ -242,7 +244,7 @@ $(document).ready(function() {
$("#HlsStatus").text('loading ' + url);
events = { url : url, t0 : performance.now(), load : [], buffer : [], video : [], level : [], bitrate : []};
recoverDecodingErrorDate = recoverSwapAudioCodecDate = null;
hls = new Hls({debug:true});
hls = new Hls({debug:true, enableWorker : enableWorker});
$("#HlsStatus").text('loading manifest and attaching video element...');
hls.loadSource(url);
hls.attachMedia(video);
@ -470,6 +472,7 @@ $(document).ready(function() {
hls.destroy();
break;
}
console.log($("#HlsStatus").text());
}
if(!stats) stats = {};
// track all errors independently
@ -908,6 +911,25 @@ function timeRangesToString(r) {
}
}
function getURLParam(sParam, defaultValue) {
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++) {
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam) {
return sParameterName[1];
}
}
return defaultValue;
}
function updatePermalink() {
var url = $('#streamURL').val();
var hlsLink = document.URL.split('?')[0] + '?src=' + encodeURIComponent(url) + '&enableStreaming=' + enableStreaming + '&autoRecoverError=' + autoRecoverError + '&enableWorker=' + enableWorker;
var description = 'permalink: ' + "<a href=\"" + hlsLink + "\">" + hlsLink + "</a>";
$("#StreamPermalink").html(description);
}
</script>
</body>

View file

@ -532,7 +532,8 @@ var LevelController = (function () {
i,
bitrateSet = {},
videoCodecFound = false,
audioCodecFound = false;
audioCodecFound = false,
hls = this.hls;
// regroup redundant level together
data.levels.forEach(function (level) {
@ -565,32 +566,36 @@ var LevelController = (function () {
}
// only keep level with supported audio/video codecs
levels0 = levels0.filter(function (level) {
levels = levels.filter(function (level) {
var checkSupported = function checkSupported(codec) {
return MediaSource.isTypeSupported('video/mp4;codecs=' + codec);
};
var audioCodec = level.audioCodec,
videoCodec = level.videoCodec;
return (audioCodec && checkSupported(audioCodec) || !audioCodec) && (videoCodec && checkSupported(videoCodec) || !videoCodec);
return (!audioCodec || checkSupported(audioCodec)) && (!videoCodec || checkSupported(videoCodec));
});
// start bitrate is the first bitrate of the manifest
bitrateStart = levels[0].bitrate;
// sort level on bitrate
levels.sort(function (a, b) {
return a.bitrate - b.bitrate;
});
this._levels = levels;
// find index of first level in sorted levels
for (i = 0; i < levels.length; i++) {
if (levels[i].bitrate === bitrateStart) {
this._firstLevel = i;
_utilsLogger.logger.log('manifest loaded,' + levels.length + ' level(s) found, first bitrate:' + bitrateStart);
break;
if (levels.length) {
// start bitrate is the first bitrate of the manifest
bitrateStart = levels[0].bitrate;
// sort level on bitrate
levels.sort(function (a, b) {
return a.bitrate - b.bitrate;
});
this._levels = levels;
// find index of first level in sorted levels
for (i = 0; i < levels.length; i++) {
if (levels[i].bitrate === bitrateStart) {
this._firstLevel = i;
_utilsLogger.logger.log('manifest loaded,' + levels.length + ' level(s) found, first bitrate:' + bitrateStart);
break;
}
}
hls.trigger(_events2['default'].MANIFEST_PARSED, { levels: this._levels, firstLevel: this._firstLevel, stats: data.stats });
} else {
hls.trigger(_events2['default'].ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: hls.url, reason: 'no compatible level found in manifest' });
}
this.hls.trigger(_events2['default'].MANIFEST_PARSED, { levels: this._levels, firstLevel: this._firstLevel, stats: data.stats });
return;
}
}, {
@ -648,7 +653,8 @@ var LevelController = (function () {
}
/* try to switch to a redundant stream if any available.
* if no redundant stream available, emergency switch down (if in auto mode and current level not 0)
* otherwise, we cannot recover this network error ....
* otherwise, we cannot recover this network error ...
* don't raise FRAG_LOAD_ERROR and FRAG_LOAD_TIMEOUT as fatal, as it is handled by mediaController
*/
if (levelId !== undefined) {
level = this._levels[levelId];
@ -664,18 +670,19 @@ var LevelController = (function () {
hls.abrController.nextAutoLevel = 0;
} else if (level && level.details && level.details.live) {
_utilsLogger.logger.warn('level controller,' + details + ' on live stream, discard');
} else {
_utilsLogger.logger.error('cannot recover ' + details + ' error');
this._level = undefined;
// stopping live reloading timer if any
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
// FRAG_LOAD_ERROR and FRAG_LOAD_TIMEOUT are handled by mediaController
} else if (details !== _errors.ErrorDetails.FRAG_LOAD_ERROR && details !== _errors.ErrorDetails.FRAG_LOAD_TIMEOUT) {
_utilsLogger.logger.error('cannot recover ' + details + ' error');
this._level = undefined;
// stopping live reloading timer if any
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
// redispatch same error but with fatal set to true
data.fatal = true;
hls.trigger(event, data);
}
// redispatch same error but with fatal set to true
data.fatal = true;
hls.trigger(event, data);
}
}
}
}
@ -1194,26 +1201,30 @@ var MSEMediaController = (function () {
this.appendError = 0;
} catch (err) {
// in case any error occured while appending, put back segment in mp4segments table
//logger.error(`error while trying to append buffer:${err.message},try appending later`);
_utilsLogger.logger.error('error while trying to append buffer:' + err.message + ',try appending later');
this.mp4segments.unshift(segment);
if (this.appendError) {
this.appendError++;
} else {
this.appendError = 1;
}
var event = { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_APPEND_ERROR, frag: this.fragCurrent };
/* with UHD content, we could get loop of quota exceeded error until
browser is able to evict some data from sourcebuffer. retrying help recovering this
*/
if (this.appendError > this.config.appendErrorMaxRetry) {
_utilsLogger.logger.log('fail ' + this.config.appendErrorMaxRetry + ' times to append segment in sourceBuffer');
event.fatal = true;
hls.trigger(_events2['default'].ERROR, event);
this.state = State.ERROR;
return;
} else {
event.fatal = false;
hls.trigger(_events2['default'].ERROR, event);
// just discard QuotaExceededError for now, and wait for the natural browser buffer eviction
//http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror
if (err.code !== 22) {
if (this.appendError) {
this.appendError++;
} else {
this.appendError = 1;
}
var event = { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_APPEND_ERROR, frag: this.fragCurrent };
/* with UHD content, we could get loop of quota exceeded error until
browser is able to evict some data from sourcebuffer. retrying help recovering this
*/
if (this.appendError > this.config.appendErrorMaxRetry) {
_utilsLogger.logger.log('fail ' + this.config.appendErrorMaxRetry + ' times to append segment in sourceBuffer');
event.fatal = true;
hls.trigger(_events2['default'].ERROR, event);
this.state = State.ERROR;
return;
} else {
event.fatal = false;
hls.trigger(_events2['default'].ERROR, event);
}
}
}
this.state = State.APPENDING;
@ -1807,6 +1818,7 @@ var MSEMediaController = (function () {
this.demuxer.push(data.payload, audioCodec, currentLevel.videoCodec, start, fragCurrent.cc, level, sn, duration, fragCurrent.decryptdata);
}
}
this.fragLoadError = 0;
}
}, {
key: 'onInitSegment',
@ -1905,6 +1917,24 @@ var MSEMediaController = (function () {
// abort fragment loading on errors
case _errors.ErrorDetails.FRAG_LOAD_ERROR:
case _errors.ErrorDetails.FRAG_LOAD_TIMEOUT:
var loadError = this.fragLoadError;
if (loadError) {
loadError++;
} else {
loadError = 1;
}
if (loadError <= this.config.fragLoadingMaxRetry) {
this.fragLoadError = loadError;
// retry loading
this.state = State.IDLE;
} else {
_utilsLogger.logger.error('mediaController: ' + data.details + ' reaches max retry, redispatch as fatal ...');
// redispatch same error but with fatal set to true
data.fatal = true;
this.hls.trigger(event, data);
this.state = State.ERROR;
}
break;
case _errors.ErrorDetails.FRAG_LOOP_LOADING_ERROR:
case _errors.ErrorDetails.LEVEL_LOAD_ERROR:
case _errors.ErrorDetails.LEVEL_LOAD_TIMEOUT:
@ -2691,7 +2721,7 @@ var AACDemuxer = (function () {
break;
}
}
this.remuxer.remux(this._aacTrack, { samples: [] }, { samples: [] }, timeOffset);
this.remuxer.remux(this._aacTrack, { samples: [] }, { samples: [{ pts: pts, dts: pts, unit: id3.payload }] }, timeOffset);
}
}, {
key: '_ADTStoAudioConfig',
@ -3513,7 +3543,7 @@ module.exports = exports['default'];
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
value: true
});
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@ -3525,130 +3555,136 @@ var _utilsLogger = require('../utils/logger');
//import Hex from '../utils/hex';
var ID3 = (function () {
function ID3(data) {
_classCallCheck(this, ID3);
function ID3(data) {
_classCallCheck(this, ID3);
this._hasTimeStamp = false;
var offset = 0,
byte1,
byte2,
byte3,
byte4,
tagSize,
endPos,
header,
len;
do {
header = this.readUTF(data, offset, 3);
offset += 3;
// first check for ID3 header
if (header === 'ID3') {
// skip 24 bits
offset += 3;
// retrieve tag(s) length
byte1 = data[offset++] & 0x7f;
byte2 = data[offset++] & 0x7f;
byte3 = data[offset++] & 0x7f;
byte4 = data[offset++] & 0x7f;
tagSize = (byte1 << 21) + (byte2 << 14) + (byte3 << 7) + byte4;
endPos = offset + tagSize;
//logger.log(`ID3 tag found, size/end: ${tagSize}/${endPos}`);
this._hasTimeStamp = false;
var offset = 0,
byte1,
byte2,
byte3,
byte4,
tagSize,
endPos,
header,
len;
do {
header = this.readUTF(data, offset, 3);
offset += 3;
// first check for ID3 header
if (header === 'ID3') {
// skip 24 bits
offset += 3;
// retrieve tag(s) length
byte1 = data[offset++] & 0x7f;
byte2 = data[offset++] & 0x7f;
byte3 = data[offset++] & 0x7f;
byte4 = data[offset++] & 0x7f;
tagSize = (byte1 << 21) + (byte2 << 14) + (byte3 << 7) + byte4;
endPos = offset + tagSize;
//logger.log(`ID3 tag found, size/end: ${tagSize}/${endPos}`);
// read ID3 tags
this._parseID3Frames(data, offset, endPos);
offset = endPos;
} else if (header === '3DI') {
// http://id3.org/id3v2.4.0-structure chapter 3.4. ID3v2 footer
offset += 7;
_utilsLogger.logger.log('3DI footer found, end: ' + offset);
} else {
offset -= 3;
len = offset;
if (len) {
//logger.log(`ID3 len: ${len}`);
if (!this.hasTimeStamp) {
_utilsLogger.logger.warn('ID3 tag found, but no timestamp');
}
this._length = len;
}
return;
}
} while (true);
// read ID3 tags
this._parseID3Frames(data, offset, endPos);
offset = endPos;
} else if (header === '3DI') {
// http://id3.org/id3v2.4.0-structure chapter 3.4. ID3v2 footer
offset += 7;
_utilsLogger.logger.log('3DI footer found, end: ' + offset);
} else {
offset -= 3;
len = offset;
if (len) {
//logger.log(`ID3 len: ${len}`);
if (!this.hasTimeStamp) {
_utilsLogger.logger.warn('ID3 tag found, but no timestamp');
}
this._length = len;
this._payload = data.subarray(0, len);
}
return;
}
} while (true);
}
_createClass(ID3, [{
key: 'readUTF',
value: function readUTF(data, start, len) {
var result = '',
offset = start,
end = start + len;
do {
result += String.fromCharCode(data[offset++]);
} while (offset < end);
return result;
}
}, {
key: '_parseID3Frames',
value: function _parseID3Frames(data, offset, endPos) {
var tagId, tagLen, tagStart, tagFlags, timestamp;
while (offset + 8 <= endPos) {
tagId = this.readUTF(data, offset, 4);
offset += 4;
_createClass(ID3, [{
key: 'readUTF',
value: function readUTF(data, start, len) {
tagLen = data[offset++] << 24 + data[offset++] << 16 + data[offset++] << 8 + data[offset++];
var result = '',
offset = start,
end = start + len;
do {
result += String.fromCharCode(data[offset++]);
} while (offset < end);
return result;
}
}, {
key: '_parseID3Frames',
value: function _parseID3Frames(data, offset, endPos) {
var tagId, tagLen, tagStart, tagFlags, timestamp;
while (offset + 8 <= endPos) {
tagId = this.readUTF(data, offset, 4);
offset += 4;
tagFlags = data[offset++] << 8 + data[offset++];
tagLen = data[offset++] << 24 + data[offset++] << 16 + data[offset++] << 8 + data[offset++];
tagStart = offset;
//logger.log("ID3 tag id:" + tagId);
switch (tagId) {
case 'PRIV':
//logger.log('parse frame:' + Hex.hexDump(data.subarray(offset,endPos)));
// owner should be "com.apple.streaming.transportStreamTimestamp"
if (this.readUTF(data, offset, 44) === 'com.apple.streaming.transportStreamTimestamp') {
offset += 44;
// smelling even better ! we found the right descriptor
// skip null character (string end) + 3 first bytes
offset += 4;
tagFlags = data[offset++] << 8 + data[offset++];
// timestamp is 33 bit expressed as a big-endian eight-octet number, with the upper 31 bits set to zero.
var pts33Bit = data[offset++] & 0x1;
this._hasTimeStamp = true;
tagStart = offset;
//logger.log("ID3 tag id:" + tagId);
switch (tagId) {
case 'PRIV':
//logger.log('parse frame:' + Hex.hexDump(data.subarray(offset,endPos)));
// owner should be "com.apple.streaming.transportStreamTimestamp"
if (this.readUTF(data, offset, 44) === 'com.apple.streaming.transportStreamTimestamp') {
offset += 44;
// smelling even better ! we found the right descriptor
// skip null character (string end) + 3 first bytes
offset += 4;
timestamp = ((data[offset++] << 23) + (data[offset++] << 15) + (data[offset++] << 7) + data[offset++]) / 45;
// timestamp is 33 bit expressed as a big-endian eight-octet number, with the upper 31 bits set to zero.
var pts33Bit = data[offset++] & 0x1;
this._hasTimeStamp = true;
timestamp = ((data[offset++] << 23) + (data[offset++] << 15) + (data[offset++] << 7) + data[offset++]) / 45;
if (pts33Bit) {
timestamp += 47721858.84; // 2^32 / 90
}
timestamp = Math.round(timestamp);
_utilsLogger.logger.trace('ID3 timestamp found: ' + timestamp);
this._timeStamp = timestamp;
}
break;
default:
break;
}
if (pts33Bit) {
timestamp += 47721858.84; // 2^32 / 90
}
timestamp = Math.round(timestamp);
_utilsLogger.logger.trace('ID3 timestamp found: ' + timestamp);
this._timeStamp = timestamp;
}
break;
default:
break;
}
}, {
key: 'hasTimeStamp',
get: function get() {
return this._hasTimeStamp;
}
}, {
key: 'timeStamp',
get: function get() {
return this._timeStamp;
}
}, {
key: 'length',
get: function get() {
return this._length;
}
}]);
}
}
}, {
key: 'hasTimeStamp',
get: function get() {
return this._hasTimeStamp;
}
}, {
key: 'timeStamp',
get: function get() {
return this._timeStamp;
}
}, {
key: 'length',
get: function get() {
return this._length;
}
}, {
key: 'payload',
get: function get() {
return this._payload;
}
}]);
return ID3;
return ID3;
})();
exports['default'] = ID3;
@ -4746,7 +4782,7 @@ var Hls = (function () {
enableWorker: true,
enableSoftwareAES: true,
fragLoadingTimeOut: 20000,
fragLoadingMaxRetry: 1,
fragLoadingMaxRetry: 6,
fragLoadingRetryDelay: 1000,
fragLoadingLoopThreshold: 3,
manifestLoadingTimeOut: 10000,
@ -4754,7 +4790,7 @@ var Hls = (function () {
manifestLoadingRetryDelay: 1000,
// fpsDroppedMonitoringPeriod: 5000,
// fpsDroppedMonitoringThreshold: 0.2,
appendErrorMaxRetry: 200,
appendErrorMaxRetry: 3,
loader: _utilsXhrLoader2['default'],
fLoader: undefined,
pLoader: undefined,
@ -5038,7 +5074,7 @@ var FragmentLoader = (function () {
this.frag.loaded = 0;
var config = this.hls.config;
frag.loader = this.loader = typeof config.fLoader !== 'undefined' ? new config.fLoader(config) : new config.loader(config);
this.loader.load(frag.url, 'arraybuffer', this.loadsuccess.bind(this), this.loaderror.bind(this), this.loadtimeout.bind(this), config.fragLoadingTimeOut, config.fragLoadingMaxRetry, config.fragLoadingRetryDelay, this.loadprogress.bind(this), frag);
this.loader.load(frag.url, 'arraybuffer', this.loadsuccess.bind(this), this.loaderror.bind(this), this.loadtimeout.bind(this), config.fragLoadingTimeOut, 1, config.fragLoadingRetryDelay, this.loadprogress.bind(this), frag);
}
}, {
key: 'loadsuccess',
@ -5301,7 +5337,7 @@ var PlaylistLoader = (function () {
if (avcdata.length > 2) {
result = avcdata.shift() + '.';
result += parseInt(avcdata.shift()).toString(16);
result += ('00' + parseInt(avcdata.shift()).toString(16)).substr(-4);
result += ('000' + parseInt(avcdata.shift()).toString(16)).substr(-4);
} else {
result = codec;
}
@ -5651,6 +5687,7 @@ var MP4 = (function () {
var payload = Array.prototype.slice.call(arguments, 1),
size = 0,
i = payload.length,
len = i,
result,
view;
// calculate the total size we need to allocate
@ -5662,7 +5699,7 @@ var MP4 = (function () {
view.setUint32(0, result.byteLength);
result.set(type, 4);
// copy the payload into the result
for (i = 0, size = 8; i < payload.length; i++) {
for (i = 0, size = 8; i < len; i++) {
result.set(payload[i], size);
size += payload[i].byteLength;
}
@ -5818,7 +5855,10 @@ var MP4 = (function () {
0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes
0xE0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets
].concat(sps).concat([track.pps.length // numOfPictureParameterSets
]).concat(pps))); // "PPS"
]).concat(pps))),
// "PPS"
width = track.width,
height = track.height;
//console.log('avcc:' + Hex.hexDump(avcc));
return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00, // reserved
0x00, 0x00, 0x00, // reserved
@ -5826,8 +5866,8 @@ var MP4 = (function () {
0x00, 0x00, // pre_defined
0x00, 0x00, // reserved
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
track.width >> 8 & 0xFF, track.width & 0xff, // width
track.height >> 8 & 0xFF, track.height & 0xff, // height
width >> 8 & 0xFF, width & 0xff, // width
height >> 8 & 0xFF, height & 0xff, // height
0x00, 0x48, 0x00, 0x00, // horizresolution
0x00, 0x48, 0x00, 0x00, // vertresolution
0x00, 0x00, 0x00, 0x00, // reserved
@ -5843,16 +5883,17 @@ var MP4 = (function () {
}, {
key: 'esds',
value: function esds(track) {
var configlen = track.config.length;
return new Uint8Array([0x00, // version 0
0x00, 0x00, 0x00, // flags
0x03, // descriptor_type
0x17 + track.config.length, // length
0x17 + configlen, // length
0x00, 0x01, //es_id
0x00, // stream_priority
0x04, // descriptor_type
0x0f + track.config.length, // length
0x0f + configlen, // length
0x40, //codec : mpeg4_audio
0x15, // stream_type
0x00, 0x00, 0x00, // buffer_size
@ -5860,11 +5901,12 @@ var MP4 = (function () {
0x00, 0x00, 0x00, 0x00, // avgBitrate
0x05 // descriptor_type
].concat([track.config.length]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
}
}, {
key: 'mp4a',
value: function mp4a(track) {
var audiosamplerate = track.audiosamplerate;
return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00, // reserved
0x00, 0x00, 0x00, // reserved
0x00, 0x01, // data_reference_index
@ -5872,7 +5914,7 @@ var MP4 = (function () {
0x00, track.channelCount, // channelcount
0x00, 0x10, // sampleSize:16bits
0x00, 0x00, 0x00, 0x00, // reserved2
track.audiosamplerate >> 8 & 0xFF, track.audiosamplerate & 0xff, //
audiosamplerate >> 8 & 0xFF, audiosamplerate & 0xff, //
0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track)));
}
}, {
@ -5887,30 +5929,35 @@ var MP4 = (function () {
}, {
key: 'tkhd',
value: function tkhd(track) {
var id = track.id,
duration = track.duration,
width = track.width,
height = track.height;
return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, // version 0
0x00, 0x00, 0x07, // flags
0x00, 0x00, 0x00, 0x00, // creation_time
0x00, 0x00, 0x00, 0x00, // modification_time
track.id >> 24 & 0xFF, track.id >> 16 & 0xFF, track.id >> 8 & 0xFF, track.id & 0xFF, // track_ID
id >> 24 & 0xFF, id >> 16 & 0xFF, id >> 8 & 0xFF, id & 0xFF, // track_ID
0x00, 0x00, 0x00, 0x00, // reserved
track.duration >> 24, track.duration >> 16 & 0xFF, track.duration >> 8 & 0xFF, track.duration & 0xFF, // duration
duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
0x00, 0x00, // layer
0x00, 0x00, // alternate_group
0x00, 0x00, // non-audio track volume
0x00, 0x00, // reserved
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
track.width >> 8 & 0xFF, track.width & 0xFF, 0x00, 0x00, // width
track.height >> 8 & 0xFF, track.height & 0xFF, 0x00, 0x00 // height
width >> 8 & 0xFF, width & 0xFF, 0x00, 0x00, // width
height >> 8 & 0xFF, height & 0xFF, 0x00, 0x00 // height
]));
}
}, {
key: 'traf',
value: function traf(track, baseMediaDecodeTime) {
var sampleDependencyTable = MP4.sdtp(track);
var sampleDependencyTable = MP4.sdtp(track),
id = track.id;
return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00, // version 0
0x00, 0x00, 0x00, // flags
track.id >> 24, track.id >> 16 & 0XFF, track.id >> 8 & 0XFF, track.id & 0xFF])), // track_ID
id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF])), // track_ID
MP4.box(MP4.types.tfdt, new Uint8Array([0x00, // version 0
0x00, 0x00, 0x00, // flags
baseMediaDecodeTime >> 24, baseMediaDecodeTime >> 16 & 0XFF, baseMediaDecodeTime >> 8 & 0XFF, baseMediaDecodeTime & 0xFF])), // baseMediaDecodeTime
@ -5937,9 +5984,10 @@ var MP4 = (function () {
}, {
key: 'trex',
value: function trex(track) {
var id = track.id;
return MP4.box(MP4.types.trex, new Uint8Array([0x00, // version 0
0x00, 0x00, 0x00, // flags
track.id >> 24, track.id >> 16 & 0XFF, track.id >> 8 & 0XFF, track.id & 0xFF, // track_ID
id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF, // track_ID
0x00, 0x00, 0x00, 0x01, // default_sample_description_index
0x00, 0x00, 0x00, 0x00, // default_sample_duration
0x00, 0x00, 0x00, 0x00, // default_sample_size
@ -5949,21 +5997,32 @@ var MP4 = (function () {
}, {
key: 'trun',
value: function trun(track, offset) {
var samples, sample, i, array;
samples = track.samples || [];
array = new Uint8Array(12 + 16 * samples.length);
offset += 8 + array.byteLength;
var samples = track.samples || [],
len = samples.length,
arraylen = 12 + 16 * len,
array = new Uint8Array(arraylen),
i,
sample,
duration,
size,
flags,
cts;
offset += 8 + arraylen;
array.set([0x00, // version 0
0x00, 0x0f, 0x01, // flags
samples.length >>> 24 & 0xFF, samples.length >>> 16 & 0xFF, samples.length >>> 8 & 0xFF, samples.length & 0xFF, // sample_count
len >>> 24 & 0xFF, len >>> 16 & 0xFF, len >>> 8 & 0xFF, len & 0xFF, // sample_count
offset >>> 24 & 0xFF, offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF // data_offset
], 0);
for (i = 0; i < samples.length; i++) {
for (i = 0; i < len; i++) {
sample = samples[i];
array.set([sample.duration >>> 24 & 0xFF, sample.duration >>> 16 & 0xFF, sample.duration >>> 8 & 0xFF, sample.duration & 0xFF, // sample_duration
sample.size >>> 24 & 0xFF, sample.size >>> 16 & 0xFF, sample.size >>> 8 & 0xFF, sample.size & 0xFF, // sample_size
sample.flags.isLeading << 2 | sample.flags.dependsOn, sample.flags.isDependedOn << 6 | sample.flags.hasRedundancy << 4 | sample.flags.paddingValue << 1 | sample.flags.isNonSync, sample.flags.degradPrio & 0xF0 << 8, sample.flags.degradPrio & 0x0F, // sample_flags
sample.cts >>> 24 & 0xFF, sample.cts >>> 16 & 0xFF, sample.cts >>> 8 & 0xFF, sample.cts & 0xFF // sample_composition_time_offset
duration = sample.duration;
size = sample.size;
flags = sample.flags;
cts = sample.cts;
array.set([duration >>> 24 & 0xFF, duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, // sample_duration
size >>> 24 & 0xFF, size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, // sample_size
flags.isLeading << 2 | sample.flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xF0 << 8, flags.degradPrio & 0x0F, // sample_flags
cts >>> 24 & 0xFF, cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF // sample_composition_time_offset
], 12 + 16 * i);
}
return MP4.box(MP4.types.trun, array);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"name": "hls.js",
"version": "0.3.11",
"version": "0.3.15",
"description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js",
"authors": "Guillaume du Pontavice <guillaume.dupontavice@dailymotion.com>",

View file

@ -32,7 +32,7 @@ class LevelController {
}
onManifestLoaded(event, data) {
var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false;
var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false, hls = this.hls;
// regroup redundant level together
data.levels.forEach(level => {
@ -65,31 +65,34 @@ class LevelController {
}
// only keep level with supported audio/video codecs
levels0 = levels0.filter(function(level) {
levels = levels.filter(function(level) {
var checkSupported = function(codec) { return MediaSource.isTypeSupported(`video/mp4;codecs=${codec}`);};
var audioCodec = level.audioCodec, videoCodec = level.videoCodec;
return ((audioCodec && checkSupported(audioCodec)) || !audioCodec) &&
((videoCodec && checkSupported(videoCodec)) || !videoCodec);
return (!audioCodec || checkSupported(audioCodec)) &&
(!videoCodec || checkSupported(videoCodec));
});
// start bitrate is the first bitrate of the manifest
bitrateStart = levels[0].bitrate;
// sort level on bitrate
levels.sort(function (a, b) {
return a.bitrate - b.bitrate;
});
this._levels = levels;
// find index of first level in sorted levels
for (i = 0; i < levels.length; i++) {
if (levels[i].bitrate === bitrateStart) {
this._firstLevel = i;
logger.log(`manifest loaded,${levels.length} level(s) found, first bitrate:${bitrateStart}`);
break;
if(levels.length) {
// start bitrate is the first bitrate of the manifest
bitrateStart = levels[0].bitrate;
// sort level on bitrate
levels.sort(function (a, b) {
return a.bitrate - b.bitrate;
});
this._levels = levels;
// find index of first level in sorted levels
for (i = 0; i < levels.length; i++) {
if (levels[i].bitrate === bitrateStart) {
this._firstLevel = i;
logger.log(`manifest loaded,${levels.length} level(s) found, first bitrate:${bitrateStart}`);
break;
}
}
hls.trigger(Event.MANIFEST_PARSED, {levels: this._levels, firstLevel: this._firstLevel, stats: data.stats});
} else {
hls.trigger(Event.ERROR, {type: ErrorTypes.NETWORK_ERROR, details: ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: hls.url, reason: 'no compatible level found in manifest'});
}
this.hls.trigger(Event.MANIFEST_PARSED, {levels: this._levels, firstLevel: this._firstLevel, stats: data.stats});
return;
}
@ -187,7 +190,8 @@ class LevelController {
}
/* try to switch to a redundant stream if any available.
* if no redundant stream available, emergency switch down (if in auto mode and current level not 0)
* otherwise, we cannot recover this network error ....
* otherwise, we cannot recover this network error ...
* don't raise FRAG_LOAD_ERROR and FRAG_LOAD_TIMEOUT as fatal, as it is handled by mediaController
*/
if (levelId !== undefined) {
level = this._levels[levelId];
@ -203,7 +207,8 @@ class LevelController {
hls.abrController.nextAutoLevel = 0;
} else if(level && level.details && level.details.live) {
logger.warn(`level controller,${details} on live stream, discard`);
} else {
// FRAG_LOAD_ERROR and FRAG_LOAD_TIMEOUT are handled by mediaController
} else if (details !== ErrorDetails.FRAG_LOAD_ERROR && details !== ErrorDetails.FRAG_LOAD_TIMEOUT) {
logger.error(`cannot recover ${details} error`);
this._level = undefined;
// stopping live reloading timer if any

View file

@ -391,26 +391,30 @@ class MSEMediaController {
this.appendError = 0;
} catch(err) {
// in case any error occured while appending, put back segment in mp4segments table
//logger.error(`error while trying to append buffer:${err.message},try appending later`);
logger.error(`error while trying to append buffer:${err.message},try appending later`);
this.mp4segments.unshift(segment);
if (this.appendError) {
this.appendError++;
} else {
this.appendError = 1;
}
var event = {type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_APPEND_ERROR, frag: this.fragCurrent};
/* with UHD content, we could get loop of quota exceeded error until
browser is able to evict some data from sourcebuffer. retrying help recovering this
*/
if (this.appendError > this.config.appendErrorMaxRetry) {
logger.log(`fail ${this.config.appendErrorMaxRetry} times to append segment in sourceBuffer`);
event.fatal = true;
hls.trigger(Event.ERROR, event);
this.state = State.ERROR;
return;
} else {
event.fatal = false;
hls.trigger(Event.ERROR, event);
// just discard QuotaExceededError for now, and wait for the natural browser buffer eviction
//http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror
if(err.code !== 22) {
if (this.appendError) {
this.appendError++;
} else {
this.appendError = 1;
}
var event = {type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_APPEND_ERROR, frag: this.fragCurrent};
/* with UHD content, we could get loop of quota exceeded error until
browser is able to evict some data from sourcebuffer. retrying help recovering this
*/
if (this.appendError > this.config.appendErrorMaxRetry) {
logger.log(`fail ${this.config.appendErrorMaxRetry} times to append segment in sourceBuffer`);
event.fatal = true;
hls.trigger(Event.ERROR, event);
this.state = State.ERROR;
return;
} else {
event.fatal = false;
hls.trigger(Event.ERROR, event);
}
}
}
this.state = State.APPENDING;
@ -1000,6 +1004,7 @@ class MSEMediaController {
this.demuxer.push(data.payload, audioCodec, currentLevel.videoCodec, start, fragCurrent.cc, level, sn, duration, fragCurrent.decryptdata);
}
}
this.fragLoadError = 0;
}
onInitSegment(event, data) {
@ -1095,6 +1100,24 @@ class MSEMediaController {
// abort fragment loading on errors
case ErrorDetails.FRAG_LOAD_ERROR:
case ErrorDetails.FRAG_LOAD_TIMEOUT:
var loadError = this.fragLoadError;
if(loadError) {
loadError++;
} else {
loadError=1;
}
if (loadError <= this.config.fragLoadingMaxRetry) {
this.fragLoadError = loadError;
// retry loading
this.state = State.IDLE;
} else {
logger.error(`mediaController: ${data.details} reaches max retry, redispatch as fatal ...`);
// redispatch same error but with fatal set to true
data.fatal = true;
this.hls.trigger(event, data);
this.state = State.ERROR;
}
break;
case ErrorDetails.FRAG_LOOP_LOADING_ERROR:
case ErrorDetails.LEVEL_LOAD_ERROR:
case ErrorDetails.LEVEL_LOAD_TIMEOUT:

View file

@ -79,7 +79,7 @@ import {ErrorTypes, ErrorDetails} from '../errors';
break;
}
}
this.remuxer.remux(this._aacTrack,{samples : []}, {samples : []}, timeOffset);
this.remuxer.remux(this._aacTrack,{samples : []}, {samples : [ { pts: pts, dts : pts, unit : id3.payload} ]}, timeOffset);
}
_ADTStoAudioConfig(data, offset, audioCodec) {

View file

@ -41,6 +41,7 @@ import {logger} from '../utils/logger';
logger.warn('ID3 tag found, but no timestamp');
}
this._length = len;
this._payload = data.subarray(0,len);
}
return;
}
@ -117,6 +118,10 @@ import {logger} from '../utils/logger';
return this._length;
}
get payload() {
return this._payload;
}
}
export default ID3;

View file

@ -46,7 +46,7 @@ class Hls {
enableWorker: true,
enableSoftwareAES: true,
fragLoadingTimeOut: 20000,
fragLoadingMaxRetry: 1,
fragLoadingMaxRetry: 6,
fragLoadingRetryDelay: 1000,
fragLoadingLoopThreshold: 3,
manifestLoadingTimeOut: 10000,
@ -54,7 +54,7 @@ class Hls {
manifestLoadingRetryDelay: 1000,
// fpsDroppedMonitoringPeriod: 5000,
// fpsDroppedMonitoringThreshold: 0.2,
appendErrorMaxRetry: 200,
appendErrorMaxRetry: 3,
loader: XhrLoader,
fLoader: undefined,
pLoader: undefined,

View file

@ -27,9 +27,9 @@ class FragmentLoader {
this.frag.loaded = 0;
var config = this.hls.config;
frag.loader = this.loader = typeof(config.fLoader) !== 'undefined' ? new config.fLoader(config) : new config.loader(config);
this.loader.load(frag.url, 'arraybuffer', this.loadsuccess.bind(this), this.loaderror.bind(this), this.loadtimeout.bind(this), config.fragLoadingTimeOut, config.fragLoadingMaxRetry, config.fragLoadingRetryDelay, this.loadprogress.bind(this), frag);
this.loader.load(frag.url, 'arraybuffer', this.loadsuccess.bind(this), this.loaderror.bind(this), this.loadtimeout.bind(this), config.fragLoadingTimeOut, 1, config.fragLoadingRetryDelay, this.loadprogress.bind(this), frag);
}
loadsuccess(event, stats) {
var payload = event.currentTarget.response;
stats.length = payload.byteLength;
@ -41,7 +41,7 @@ class FragmentLoader {
loaderror(event) {
this.loader.abort();
this.hls.trigger(Event.ERROR, {type: ErrorTypes.NETWORK_ERROR, details: ErrorDetails.FRAG_LOAD_ERROR, fatal: false, frag: this.frag, response: event});
}
}
loadtimeout() {
this.loader.abort();

View file

@ -94,7 +94,7 @@ class PlaylistLoader {
if (avcdata.length > 2) {
result = avcdata.shift() + '.';
result += parseInt(avcdata.shift()).toString(16);
result += ('00' + parseInt(avcdata.shift()).toString(16)).substr(-4);
result += ('000' + parseInt(avcdata.shift()).toString(16)).substr(-4);
} else {
result = codec;
}

View file

@ -152,6 +152,7 @@ class MP4 {
payload = Array.prototype.slice.call(arguments, 1),
size = 0,
i = payload.length,
len = i,
result,
view;
// calculate the total size we need to allocate
@ -163,7 +164,7 @@ class MP4 {
view.setUint32(0, result.byteLength);
result.set(type, 4);
// copy the payload into the result
for (i = 0, size = 8; i < payload.length; i++) {
for (i = 0, size = 8; i < len; i++) {
result.set(payload[i], size);
size += payload[i].byteLength;
}
@ -341,7 +342,9 @@ class MP4 {
0xE0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets
].concat(sps).concat([
track.pps.length // numOfPictureParameterSets
]).concat(pps))); // "PPS"
]).concat(pps))), // "PPS"
width = track.width,
height = track.height;
//console.log('avcc:' + Hex.hexDump(avcc));
return MP4.box(MP4.types.avc1, new Uint8Array([
0x00, 0x00, 0x00, // reserved
@ -352,10 +355,10 @@ class MP4 {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // pre_defined
(track.width >> 8) & 0xFF,
track.width & 0xff, // width
(track.height >> 8) & 0xFF,
track.height & 0xff, // height
(width >> 8) & 0xFF,
width & 0xff, // width
(height >> 8) & 0xFF,
height & 0xff, // height
0x00, 0x48, 0x00, 0x00, // horizresolution
0x00, 0x48, 0x00, 0x00, // vertresolution
0x00, 0x00, 0x00, 0x00, // reserved
@ -380,17 +383,18 @@ class MP4 {
}
static esds(track) {
var configlen = track.config.length;
return new Uint8Array([
0x00, // version 0
0x00, 0x00, 0x00, // flags
0x03, // descriptor_type
0x17+track.config.length, // length
0x17+configlen, // length
0x00, 0x01, //es_id
0x00, // stream_priority
0x04, // descriptor_type
0x0f+track.config.length, // length
0x0f+configlen, // length
0x40, //codec : mpeg4_audio
0x15, // stream_type
0x00, 0x00, 0x00, // buffer_size
@ -398,23 +402,24 @@ class MP4 {
0x00, 0x00, 0x00, 0x00, // avgBitrate
0x05 // descriptor_type
].concat([track.config.length]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
}
static mp4a(track) {
return MP4.box(MP4.types.mp4a, new Uint8Array([
0x00, 0x00, 0x00, // reserved
0x00, 0x00, 0x00, // reserved
0x00, 0x01, // data_reference_index
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // reserved
0x00, track.channelCount, // channelcount
0x00, 0x10, // sampleSize:16bits
0x00, 0x00, 0x00, 0x00, // reserved2
(track.audiosamplerate >> 8) & 0xFF,
track.audiosamplerate & 0xff, //
0x00, 0x00]),
MP4.box(MP4.types.esds, MP4.esds(track)));
var audiosamplerate = track.audiosamplerate;
return MP4.box(MP4.types.mp4a, new Uint8Array([
0x00, 0x00, 0x00, // reserved
0x00, 0x00, 0x00, // reserved
0x00, 0x01, // data_reference_index
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // reserved
0x00, track.channelCount, // channelcount
0x00, 0x10, // sampleSize:16bits
0x00, 0x00, 0x00, 0x00, // reserved2
(audiosamplerate >> 8) & 0xFF,
audiosamplerate & 0xff, //
0x00, 0x00]),
MP4.box(MP4.types.esds, MP4.esds(track)));
}
static stsd(track) {
@ -426,20 +431,24 @@ class MP4 {
}
static tkhd(track) {
var id = track.id,
duration = track.duration,
width = track.width,
height = track.height;
return MP4.box(MP4.types.tkhd, new Uint8Array([
0x00, // version 0
0x00, 0x00, 0x07, // flags
0x00, 0x00, 0x00, 0x00, // creation_time
0x00, 0x00, 0x00, 0x00, // modification_time
(track.id >> 24) & 0xFF,
(track.id >> 16) & 0xFF,
(track.id >> 8) & 0xFF,
track.id & 0xFF, // track_ID
(id >> 24) & 0xFF,
(id >> 16) & 0xFF,
(id >> 8) & 0xFF,
id & 0xFF, // track_ID
0x00, 0x00, 0x00, 0x00, // reserved
(track.duration >> 24),
(track.duration >> 16) & 0xFF,
(track.duration >> 8) & 0xFF,
track.duration & 0xFF, // duration
(duration >> 24),
(duration >> 16) & 0xFF,
(duration >> 8) & 0xFF,
duration & 0xFF, // duration
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // reserved
0x00, 0x00, // layer
@ -455,25 +464,26 @@ class MP4 {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
(track.width >> 8) & 0xFF,
track.width & 0xFF,
(width >> 8) & 0xFF,
width & 0xFF,
0x00, 0x00, // width
(track.height >> 8) & 0xFF,
track.height & 0xFF,
(height >> 8) & 0xFF,
height & 0xFF,
0x00, 0x00 // height
]));
}
static traf(track,baseMediaDecodeTime) {
var sampleDependencyTable = MP4.sdtp(track);
var sampleDependencyTable = MP4.sdtp(track),
id = track.id;
return MP4.box(MP4.types.traf,
MP4.box(MP4.types.tfhd, new Uint8Array([
0x00, // version 0
0x00, 0x00, 0x00, // flags
(track.id >> 24),
(track.id >> 16) & 0XFF,
(track.id >> 8) & 0XFF,
(track.id & 0xFF) // track_ID
(id >> 24),
(id >> 16) & 0XFF,
(id >> 8) & 0XFF,
(id & 0xFF) // track_ID
])),
MP4.box(MP4.types.tfdt, new Uint8Array([
0x00, // version 0
@ -505,13 +515,14 @@ class MP4 {
}
static trex(track) {
var id = track.id;
return MP4.box(MP4.types.trex, new Uint8Array([
0x00, // version 0
0x00, 0x00, 0x00, // flags
(track.id >> 24),
(track.id >> 16) & 0XFF,
(track.id >> 8) & 0XFF,
(track.id & 0xFF), // track_ID
(id >> 24),
(id >> 16) & 0XFF,
(id >> 8) & 0XFF,
(id & 0xFF), // track_ID
0x00, 0x00, 0x00, 0x01, // default_sample_description_index
0x00, 0x00, 0x00, 0x00, // default_sample_duration
0x00, 0x00, 0x00, 0x00, // default_sample_size
@ -520,44 +531,50 @@ class MP4 {
}
static trun(track, offset) {
var samples, sample, i, array;
samples = track.samples || [];
array = new Uint8Array(12 + (16 * samples.length));
offset += 8 + array.byteLength;
var samples= track.samples || [],
len = samples.length,
arraylen = 12 + (16 * len),
array = new Uint8Array(arraylen),
i,sample,duration,size,flags,cts;
offset += 8 + arraylen;
array.set([
0x00, // version 0
0x00, 0x0f, 0x01, // flags
(samples.length >>> 24) & 0xFF,
(samples.length >>> 16) & 0xFF,
(samples.length >>> 8) & 0xFF,
samples.length & 0xFF, // sample_count
(len >>> 24) & 0xFF,
(len >>> 16) & 0xFF,
(len >>> 8) & 0xFF,
len & 0xFF, // sample_count
(offset >>> 24) & 0xFF,
(offset >>> 16) & 0xFF,
(offset >>> 8) & 0xFF,
offset & 0xFF // data_offset
],0);
for (i = 0; i < samples.length; i++) {
for (i = 0; i < len; i++) {
sample = samples[i];
duration = sample.duration;
size = sample.size;
flags = sample.flags;
cts = sample.cts;
array.set([
(sample.duration >>> 24) & 0xFF,
(sample.duration >>> 16) & 0xFF,
(sample.duration >>> 8) & 0xFF,
sample.duration & 0xFF, // sample_duration
(sample.size >>> 24) & 0xFF,
(sample.size >>> 16) & 0xFF,
(sample.size >>> 8) & 0xFF,
sample.size & 0xFF, // sample_size
(sample.flags.isLeading << 2) | sample.flags.dependsOn,
(sample.flags.isDependedOn << 6) |
(sample.flags.hasRedundancy << 4) |
(sample.flags.paddingValue << 1) |
sample.flags.isNonSync,
sample.flags.degradPrio & 0xF0 << 8,
sample.flags.degradPrio & 0x0F, // sample_flags
(sample.cts >>> 24) & 0xFF,
(sample.cts >>> 16) & 0xFF,
(sample.cts >>> 8) & 0xFF,
sample.cts & 0xFF // sample_composition_time_offset
(duration >>> 24) & 0xFF,
(duration >>> 16) & 0xFF,
(duration >>> 8) & 0xFF,
duration & 0xFF, // sample_duration
(size >>> 24) & 0xFF,
(size >>> 16) & 0xFF,
(size >>> 8) & 0xFF,
size & 0xFF, // sample_size
(flags.isLeading << 2) | sample.flags.dependsOn,
(flags.isDependedOn << 6) |
(flags.hasRedundancy << 4) |
(flags.paddingValue << 1) |
flags.isNonSync,
flags.degradPrio & 0xF0 << 8,
flags.degradPrio & 0x0F, // sample_flags
(cts >>> 24) & 0xFF,
(cts >>> 16) & 0xFF,
(cts >>> 8) & 0xFF,
cts & 0xFF // sample_composition_time_offset
],12+16*i);
}
return MP4.box(MP4.types.trun, array);

View file

@ -1,6 +1,6 @@
{
"name": "iron-checked-element-behavior",
"version": "1.0.3",
"version": "1.0.4",
"description": "Implements an element that has a checked attribute and can be added to a form",
"authors": "The Polymer Authors",
"keywords": [
@ -31,11 +31,11 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.3",
"_release": "1.0.4",
"_resolution": {
"type": "version",
"tag": "v1.0.3",
"commit": "5a0520d20eb8883076ce64117f2726ba209ebc97"
"tag": "v1.0.4",
"commit": "cc30263ec2871ae8f8f944948f44299d3f3cdf0d"
},
"_source": "git://github.com/PolymerElements/iron-checked-element-behavior.git",
"_target": "^1.0.0",

View file

@ -1,28 +1,22 @@
language: node_js
sudo: false
matrix:
include:
- node_js: stable
script: xvfb-run wct
addons:
firefox: latest
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
- node_js: node
script:
- |
if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
wct -s 'default'
fi
before_script:
- npm install web-component-tester
- npm install bower
- export PATH=$PWD/node_modules/.bin:$PATH
- bower install
- npm install web-component-tester
- npm install bower
- 'export PATH=$PWD/node_modules/.bin:$PATH'
- bower install
env:
global:
- secure: EJSBYkW/C3ppDTbxHYRzyFPAko5R1ET1LSbdM484/j0OHGLkSIwtKrrZLNz5+QEmKSw79MpLpBoD+SfXuSCn0yKkf6tvK4mt+kRs32vKVfoWrYReVcfth+EWV7QDpTDJw1QEijT1bKUxULhP0OrT2/5vVpKpXX2zczg+VFL7IZuY3y1dsA4qWmWTfMiAk3762dZx47D5qzJ4POHlpG0i/cHH2EgqV8sFXFBctf6EY68GqzStPUuMuea6xX2wMrebg6vqQDfDb1gs8N34gxGE+u8QaqOSniW1Vzdoe1vwOUo4dbJYw3JMYK5Qn2pj3p2E4m9J609JNnBfqjS7mB5KVC7Hf5r9ul3UMsAIlOnlmSqOq1oO22/3regjWHGjlrzCNHzma2SgDhTxGaLDJl1LnsUevbVb6TGloiQPXwum8oa7dvZ1PqspqyqZEb31t/FyUnG+VXnC0YYpdRj3eRGqeoqqaNtad97DrPHP7er9LdvJIKjsXux7gUW4hKWsr+jsU/krdHpTUC8GYWdTF54EcLhxfzNYKL7voTq+xoQ2yxCOSiBmcQCviuQyVvNQyhde/+edAmOt24CLiuSQjHCbEWzBQs9QinUPRekg6+LJ1WaifTIKkhsm04AdaZrs7LR34hF+Mpqp4HHl/AfcbtVeB/W7jUnhJyMFaQDfGkpzSZs=
- secure: izhN5Z3WdajR3ois2T55qepsvLwVg/wv8u4kVQ4TqWhUL08tka83m/W+EMzS/tcvfz7J3VkuTFrJ5scYD9kaTVhRo4dv2u+DdbPmTNcf/hmADXLVLxddyueK3bWEcBurg8+rSdqq/RdI+5CPwWeGtQl+lmjRCyBzodIpQ90zJQF4Al7nmmLuEUhiNVjuqQ3VB1pFLYgky4SVM0bfJnoKSDsZ2z9DOOJE34ZUUmcNqVcQoZ5/oM+PWdVDkUqW3vMK1lTMtE/dk6WcSztQwFyoMrW+uzEstPwUsJCyuBEx4KdioXZH3vrlxRApySfHmEf5eVWwE6jyPSHuWj/2D5O4R9LY1dq1Wcoiu3BJj19B4V3s4L2uJF+xL077d4Mna6z9dE4RSRzs8Z8MvSMTgzDkga/A25JI3XxJMJ78WTbkNQ4hVFN2xwcU5cm+fbs3Sr1ZEdFW/MWAPtUQOzscqS5Op7sSLLaiqO+R0zj56H2NA2bl/zCmbZhyLcOPl0oAfJ85bqNxyF8CoO+GZ98UG15ROigC90/HCP7TUHZnQSrGtiFGTiPTBm+VCITYmC5IEyJBTwgqh/ljbDzz4UuSZ3KsldL3MwWnqO3tGr6VvPfqKF6xq0vuyn9P7f9WNAYwZGcRi3AtxtY+znO+IGv2sGmrfo7ZY+U4nceXTEDrG8OY0Jo=
- secure: EJSBYkW/C3ppDTbxHYRzyFPAko5R1ET1LSbdM484/j0OHGLkSIwtKrrZLNz5+QEmKSw79MpLpBoD+SfXuSCn0yKkf6tvK4mt+kRs32vKVfoWrYReVcfth+EWV7QDpTDJw1QEijT1bKUxULhP0OrT2/5vVpKpXX2zczg+VFL7IZuY3y1dsA4qWmWTfMiAk3762dZx47D5qzJ4POHlpG0i/cHH2EgqV8sFXFBctf6EY68GqzStPUuMuea6xX2wMrebg6vqQDfDb1gs8N34gxGE+u8QaqOSniW1Vzdoe1vwOUo4dbJYw3JMYK5Qn2pj3p2E4m9J609JNnBfqjS7mB5KVC7Hf5r9ul3UMsAIlOnlmSqOq1oO22/3regjWHGjlrzCNHzma2SgDhTxGaLDJl1LnsUevbVb6TGloiQPXwum8oa7dvZ1PqspqyqZEb31t/FyUnG+VXnC0YYpdRj3eRGqeoqqaNtad97DrPHP7er9LdvJIKjsXux7gUW4hKWsr+jsU/krdHpTUC8GYWdTF54EcLhxfzNYKL7voTq+xoQ2yxCOSiBmcQCviuQyVvNQyhde/+edAmOt24CLiuSQjHCbEWzBQs9QinUPRekg6+LJ1WaifTIKkhsm04AdaZrs7LR34hF+Mpqp4HHl/AfcbtVeB/W7jUnhJyMFaQDfGkpzSZs=
- secure: izhN5Z3WdajR3ois2T55qepsvLwVg/wv8u4kVQ4TqWhUL08tka83m/W+EMzS/tcvfz7J3VkuTFrJ5scYD9kaTVhRo4dv2u+DdbPmTNcf/hmADXLVLxddyueK3bWEcBurg8+rSdqq/RdI+5CPwWeGtQl+lmjRCyBzodIpQ90zJQF4Al7nmmLuEUhiNVjuqQ3VB1pFLYgky4SVM0bfJnoKSDsZ2z9DOOJE34ZUUmcNqVcQoZ5/oM+PWdVDkUqW3vMK1lTMtE/dk6WcSztQwFyoMrW+uzEstPwUsJCyuBEx4KdioXZH3vrlxRApySfHmEf5eVWwE6jyPSHuWj/2D5O4R9LY1dq1Wcoiu3BJj19B4V3s4L2uJF+xL077d4Mna6z9dE4RSRzs8Z8MvSMTgzDkga/A25JI3XxJMJ78WTbkNQ4hVFN2xwcU5cm+fbs3Sr1ZEdFW/MWAPtUQOzscqS5Op7sSLLaiqO+R0zj56H2NA2bl/zCmbZhyLcOPl0oAfJ85bqNxyF8CoO+GZ98UG15ROigC90/HCP7TUHZnQSrGtiFGTiPTBm+VCITYmC5IEyJBTwgqh/ljbDzz4UuSZ3KsldL3MwWnqO3tGr6VvPfqKF6xq0vuyn9P7f9WNAYwZGcRi3AtxtY+znO+IGv2sGmrfo7ZY+U4nceXTEDrG8OY0Jo=
node_js: 4
addons:
firefox: latest
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
script:
- xvfb-run wct
- "if [ \"${TRAVIS_PULL_REQUEST}\" = \"false\" ]; then wct -s 'default'; fi"

View file

@ -1,6 +1,6 @@
{
"name": "iron-checked-element-behavior",
"version": "1.0.3",
"version": "1.0.4",
"description": "Implements an element that has a checked attribute and can be added to a form",
"authors": "The Polymer Authors",
"keywords": [

View file

@ -74,6 +74,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/**
* Returns false if the element is required and not checked, and true otherwise.
* @param {*=} _value Ignored.
* @return {boolean} true if `required` is false, or if `required` and `checked` are both true.
*/
_getValidity: function(_value) {

View file

@ -1,5 +1,4 @@
<!doctype html>
<!--
<!DOCTYPE html><!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
@ -7,9 +6,7 @@ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
--><html><head>
<title>iron-checked-element-behavior tests</title>
@ -23,12 +20,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<body>
<script>
WCT.loadSuites([
'basic.html'
'basic.html',
'basic.html?dom=shadow'
]);
</script>
</body>
</html>
</body></html>

View file

@ -1,6 +1,6 @@
{
"name": "iron-icons",
"version": "1.0.5",
"version": "1.0.6",
"description": "A set of icons for use with iron-icon",
"authors": [
"The Polymer Authors"
@ -34,11 +34,11 @@
"util",
"update-icons.sh"
],
"_release": "1.0.5",
"_release": "1.0.6",
"_resolution": {
"type": "version",
"tag": "v1.0.5",
"commit": "39da54afbc17af343d1f95e62c5c0c477492677a"
"tag": "v1.0.6",
"commit": "bea6cd482cb127b08f9fbcb2b74aa7bbc8604076"
},
"_source": "git://github.com/PolymerElements/iron-icons.git",
"_target": "^1.0.0",

View file

@ -11,7 +11,7 @@ env:
- secure: LBT0VumsEPWUYm0OLhqHU1XWmVY18QP64cMeqZAwASnYYyH/R5OGYAcI7aH8To29FWpkZSL85NPto37bN+f8DWRSULq4p+1wl2HviYHsam8x1NzN7hKq6nv+203qaT9SflheaNy6sSDfZJQ+36bRcGQ5khKkVeDpw7h8D/osSQ4=
node_js: 4
addons:
firefox: '42.0'
firefox: latest
apt:
sources:
- google-chrome

View file

@ -1,6 +1,6 @@
{
"name": "iron-icons",
"version": "1.0.5",
"version": "1.0.6",
"description": "A set of icons for use with iron-icon",
"authors": [
"The Polymer Authors"

View file

@ -63,7 +63,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}
.set:nth-of-type(4n-2) {
color: var(--google-yellow-300);
color: var(--paper-pink-500);
}
.set:nth-of-type(4n-1) {

View file

@ -1,11 +1,11 @@
<!doctype html>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>

View file

@ -1,6 +1,6 @@
{
"name": "paper-item",
"version": "1.1.2",
"version": "1.1.3",
"description": "A material-design styled list item",
"authors": [
"The Polymer Authors"
@ -20,7 +20,7 @@
"type": "git",
"url": "git://github.com/PolymerElements/paper-item"
},
"license": "MIT",
"license": "http://polymer.github.io/LICENSE.txt",
"homepage": "https://github.com/PolymerElements/paper-item",
"ignore": [],
"dependencies": {
@ -42,11 +42,11 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
},
"_release": "1.1.2",
"_release": "1.1.3",
"_resolution": {
"type": "version",
"tag": "v1.1.2",
"commit": "e6d048b25af0a84e1ff9f48450f07972326d476b"
"tag": "v1.1.3",
"commit": "280c2e703315a6f1f707bec6fd0b1e0b80fee8f4"
},
"_source": "git://github.com/PolymerElements/paper-item.git",
"_target": "^1.0.0",

View file

@ -1,6 +1,6 @@
{
"name": "paper-item",
"version": "1.1.2",
"version": "1.1.3",
"description": "A material-design styled list item",
"authors": [
"The Polymer Authors"
@ -20,7 +20,7 @@
"type": "git",
"url": "git://github.com/PolymerElements/paper-item"
},
"license": "MIT",
"license": "http://polymer.github.io/LICENSE.txt",
"homepage": "https://github.com/PolymerElements/paper-item",
"ignore": [],
"dependencies": {

View file

@ -30,12 +30,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<link rel="import" href="../paper-item-body.html">
<link rel="import" href="../../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../../paper-styles/demo-pages.html">
<style is="custom-style">
.list {
@apply(--layout-vertical);
padding-top: 12px;
background-color: white;
display: inline-block;
width: 240px;
height: 228px;
margin: 12px;
@ -257,7 +257,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<div secondary>Personal</div>
</paper-item-body>
</paper-icon-item>
<paper-icon-item>
</div>
</div>

View file

@ -9,12 +9,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-behaviors/iron-control-state.html">
<link rel="import" href="../iron-behaviors/iron-button-state.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../paper-styles/typography.html">
<link rel="import" href="../paper-styles/color.html">
<link rel="import" href="../paper-styles/default-theme.html">
<link rel="import" href="paper-item-behavior.html">
<link rel="import" href="paper-item-shared-styles.html">
@ -63,9 +59,10 @@ Custom property | Description |
}
.content-icon {
width: var(--paper-item-icon-width, 56px);
@apply(--layout-horizontal);
@apply(--layout-center);
width: var(--paper-item-icon-width, 56px);
}
</style>

View file

@ -9,8 +9,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-behaviors/iron-control-state.html">
<link rel="import" href="../iron-behaviors/iron-button-state.html">
<link rel="import" href="../iron-behaviors/iron-control-state.html">
<!--
`PaperItemBehavior` is a convenience behavior shared by <paper-item> and
@ -29,9 +29,8 @@ the items.
/** @polymerBehavior */
Polymer.PaperItemBehavior = [
Polymer.IronControlState,
Polymer.IronButtonState,
Polymer.IronControlState,
Polymer.PaperItemBehaviorImpl
];
</script>

View file

@ -11,8 +11,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../paper-styles/default-theme.html">
<link rel="import" href="../paper-styles/color.html">
<link rel="import" href="../paper-styles/typography.html">
<!--
Use `<paper-item-body>` in a `<paper-item>` or `<paper-icon-item>` to make two- or
three- line items. It is a flex item that is a vertical flexbox.
@ -58,15 +58,16 @@ Custom property | Description | Default
}
:host > ::content > * {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
:host > ::content [secondary] {
color: var(--paper-item-body-secondary-color, --secondary-text-color);
@apply(--paper-font-body1);
color: var(--paper-item-body-secondary-color, --secondary-text-color);
@apply(--paper-item-body-secondary);
}
</style>

View file

@ -8,35 +8,48 @@ Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../paper-styles/default-theme.html">
<link rel="import" href="../paper-styles/color.html">
<dom-module id="paper-item-shared-styles">
<template>
<style>
:host {
display: block;
position: relative;
min-height: var(--paper-item-min-height, 48px);
padding: 0px 16px;
}
:host([hidden]) {
display: none !important;
}
:host(.iron-selected) {
font-weight: var(--paper-item-selected-weight, bold);
@apply(--paper-item-selected);
}
:host([disabled]) {
color: var(--paper-item-disabled-color, --disabled-text-color);
@apply(--paper-item-disabled);
}
:host(:focus) {
position: relative;
outline: 0;
@apply(--paper-item-focused);
}
:host(:focus):before {
@apply(--layout-fit);
content: '';
background: currentColor;
content: '';
opacity: var(--dark-divider-opacity);
pointer-events: none;

View file

@ -9,11 +9,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-behaviors/iron-control-state.html">
<link rel="import" href="../iron-behaviors/iron-button-state.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../paper-styles/default-theme.html">
<link rel="import" href="../paper-styles/color.html">
<link rel="import" href="paper-item-behavior.html">
<link rel="import" href="paper-item-shared-styles.html">
@ -39,13 +35,13 @@ items.
The following custom properties and mixins are available for styling:
Custom property | Description | Default
------------------------------|------------------------------------------------|----------
`--paper-item-min-height` | Minimum height of the item | `48px`
`--paper-item` | Mixin applied to the item | `{}`
`--paper-item-selected-weight`| The font weight of a selected item | `bold`
`--paper-item-selected` | Mixin applied to selected paper-items | `{}`
`--paper-item-disabled-color` | The color for disabled paper-items | `--disabled-text-color`
Custom property | Description | Default
------------------------------|----------------------------------------------|----------
`--paper-item-min-height` | Minimum height of the item | `48px`
`--paper-item` | Mixin applied to the item | `{}`
`--paper-item-selected-weight`| The font weight of a selected item | `bold`
`--paper-item-selected` | Mixin applied to selected paper-items | `{}`
`--paper-item-disabled-color` | The color for disabled paper-items | `--disabled-text-color`
`--paper-item-disabled` | Mixin applied to disabled paper-items | `{}`
`--paper-item-focused` | Mixin applied to focused paper-items | `{}`
`--paper-item-focused-before` | Mixin applied to :before focused paper-items | `{}`

View file

@ -1,6 +1,6 @@
{
"name": "paper-styles",
"version": "1.1.0",
"version": "1.1.1",
"description": "Common (global) styles for Material Design elements.",
"authors": [
"The Polymer Authors"
@ -29,11 +29,11 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"iron-component-page": "polymerelements/iron-component-page#^1.0.0"
},
"_release": "1.1.0",
"_release": "1.1.1",
"_resolution": {
"type": "version",
"tag": "1.1.0",
"commit": "4104485003ccbcf2c3c9eb542156930974294525"
"tag": "v1.1.1",
"commit": "fc3ca8dcfc69b9c7a7261e51eefc9741d0f113f8"
},
"_source": "git://github.com/PolymerElements/paper-styles.git",
"_target": "^1.0.0",

View file

@ -1,6 +1,6 @@
{
"name": "paper-styles",
"version": "1.1.0",
"version": "1.1.1",
"description": "Common (global) styles for Material Design elements.",
"authors": [
"The Polymer Authors"

View file

@ -38,8 +38,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/*
* Primary and accent colors. Also see color.html for more colors.
*/
--primary-color: #3f51b5; /* --paper-indigo-500 */
--light-primary-color: #c5cae9; /* --paper-indigo-100 */
--default-primary-color: #3f51b5; /* --paper-indigo-500 */
--dark-primary-color: #303f9f; /* --paper-indigo-700 */
--accent-color: #ff4081; /* --paper-pink-a200 */
@ -55,6 +55,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
--secondary-text-color: var(--light-theme-secondary-color);
--disabled-text-color:var(--light-theme-disabled-color);
--divider-color: var(--light-theme-divider-color);
--default-primary-color: var(--primary-color);
}
</style>

View file

@ -1,6 +1,6 @@
{
"name": "paper-toggle-button",
"version": "1.0.12",
"version": "1.0.13",
"description": "A material design toggle button control",
"authors": [
"The Polymer Authors"
@ -36,11 +36,11 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"main": "paper-toggle-button.html",
"_release": "1.0.12",
"_release": "1.0.13",
"_resolution": {
"type": "version",
"tag": "v1.0.12",
"commit": "363fb16086662fea165668ffe10be233e02e0aa9"
"tag": "1.0.13",
"commit": "dbc3924b8d9c16ee6376704dd80c39d12aee72c8"
},
"_source": "git://github.com/PolymerElements/paper-toggle-button.git",
"_target": "~1.0.5",

View file

@ -1,6 +1,6 @@
{
"name": "paper-toggle-button",
"version": "1.0.12",
"version": "1.0.13",
"description": "A material design toggle button control",
"authors": [
"The Polymer Authors"

View file

@ -25,7 +25,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<style is="custom-style" include="demo-pages-shared-styles">
.vertical-section-container {
max-width: 600px;
max-width: 500px;
}
paper-toggle-button {
@ -44,19 +44,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<paper-toggle-button disabled>Disabled</paper-toggle-button>
</template>
</demo-snippet>
</div>
<div class="vertical-section-container centered">
<h3>Toggle buttons can hide the ripple effect using the <i>noink</i> attribute</h3>
<demo-snippet class="centered-demo">
<template>
<paper-toggle-button noink>Toggle</paper-toggle-button>
</template>
</demo-snippet>
</div>
<div class="vertical-section-container centered">
<h3>Toggle buttons can be styled using custom properties</h3>
<h3>Toggle buttons can be styled using custom properties</h3>
<demo-snippet class="centered-demo">
<template>
<style is="custom-style">

View file

@ -41,6 +41,7 @@ Custom property | Description | Default
`--paper-toggle-button-checked-bar` | Mixin applied to the slider when the input is checked | `{}`
`--paper-toggle-button-checked-button` | Mixin applied to the slider button when the input is checked | `{}`
`--paper-toggle-button-label-color` | Label color | `--primary-text-color`
`--paper-toggle-button-label-spacing` | Spacing between the label and the button | `8px`
@group Paper Elements
@element paper-toggle-button
@ -148,7 +149,7 @@ Custom property | Description | Default
top: -2px;
display: inline-block;
vertical-align: middle;
margin-left: 10px;
padding-left: var(--paper-toggle-button-label-spacing, 8px);
white-space: normal;
pointer-events: none;
color: var(--paper-toggle-button-label-color, --primary-text-color);

View file

@ -22,6 +22,6 @@
"commit": "9cd0b99417eac61e890d11c5119f2e45e752c999"
},
"_source": "git://github.com/jrburke/requirejs-bower.git",
"_target": "~2.1.19",
"_target": "^2.1.22",
"_originalSource": "requirejs"
}

View file

@ -91,7 +91,7 @@
function downloadToFile(url, dir, filename, callback, errorCallback) {
Logger.log('Downloading ' + url);
console.log('Downloading ' + url);
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
@ -146,7 +146,7 @@
};
var errorCallback = function (e) {
Logger.log('Imagestore error: ' + e.name);
console.log('Imagestore error: ' + e.name);
reject();
};

View file

@ -42,7 +42,7 @@
};
reader.onabort = function () {
Dashboard.hideLoadingMsg();
Logger.log('File read cancelled');
console.log('File read cancelled');
};
// Closure to capture the file information.

View file

@ -69,7 +69,7 @@ define(function () {
var stylesheet = stylesheets[i];
Logger.log('Unloading stylesheet: ' + stylesheet.href);
console.log('Unloading stylesheet: ' + stylesheet.href);
stylesheet.parentNode.removeChild(stylesheet);
removeFromLoadHistory(stylesheet.href);
}

View file

@ -66,7 +66,7 @@
// Subtract to avoid getting programs that are starting when the grid ends
var nextDay = new Date(date.getTime() + msPerDay - 2000);
Logger.log(nextDay);
console.log(nextDay);
channelsPromise.then(function (channelsResult) {
ApiClient.getLiveTvPrograms({

View file

@ -162,7 +162,7 @@
if (options.showConfirmation !== false) {
Dashboard.processServerConfigurationUpdateResult();
}
$(self).trigger('submitted');
Events.trigger(self, 'submitted');
}, function () {
Dashboard.hideLoadingMsg();

View file

@ -44,7 +44,7 @@
}
.cardBox {
margin: 2px;
margin: 1px;
}
@media all and (max-width: 800px) {

View file

@ -140,7 +140,7 @@
@media all and (min-width: 1200px) {
.ehsContent:not(.fullWidth), .ehsContent .pageTabContent {
width: 95%;
width: 96%;
}
}

View file

@ -189,7 +189,8 @@ paper-tab {
padding: 0;
}
.cardBox {
/* Need the div specifier to gain preference over the value in card.css */
div.cardBox {
margin: 5px;
}

View file

@ -91,7 +91,7 @@
html += "</div>";
}
Events.trigger($('#latestReviews', page).html(html)[0], 'create');
$('#latestReviews', page).html(html).trigger('create');
});
}

View file

@ -41,7 +41,7 @@
picker.innerHTML = getPickerHtml();
Events.on(picker, 'click', 'a', function () {
$(picker).on('click', 'a', function () {
var elem = this;
@ -52,9 +52,9 @@
if (!isSelected) {
elem.classList.add('selectedCharacter');
Events.trigger(picker, 'alphaselect', [this.innerHTML]);
$(picker).trigger('alphaselect', [this.innerHTML]);
} else {
Events.trigger(picker, 'alphaclear');
$(picker).trigger('alphaclear');
}
});
}

View file

@ -48,7 +48,7 @@
if (data) {
Logger.log('Found backdrop id list in cache. Key: ' + key)
console.log('Found backdrop id list in cache. Key: ' + key)
data = JSON.parse(data);
deferred.resolveWith(null, [data]);
} else {

View file

@ -82,7 +82,7 @@
this.sessionListener.bind(this),
this.receiverListener.bind(this));
Logger.log('chromecast.initialize');
console.log('chromecast.initialize');
chrome.cast.initialize(apiConfig, this.onInitSuccess.bind(this), this.errorHandler);
@ -93,14 +93,14 @@
*/
CastPlayer.prototype.onInitSuccess = function () {
this.isInitialized = true;
Logger.log("chromecast init success");
console.log("chromecast init success");
};
/**
* Generic error callback function
*/
CastPlayer.prototype.onError = function () {
Logger.log("chromecast error");
console.log("chromecast error");
};
/**
@ -115,7 +115,7 @@
this.session = e;
if (this.session) {
Logger.log('sessionListener ' + JSON.stringify(e));
console.log('sessionListener ' + JSON.stringify(e));
if (this.session.media[0]) {
this.onMediaDiscovered('activeSession', this.session.media[0]);
@ -165,11 +165,11 @@
CastPlayer.prototype.receiverListener = function (e) {
if (e === 'available') {
Logger.log("chromecast receiver found");
console.log("chromecast receiver found");
this.hasReceivers = true;
}
else {
Logger.log("chromecast receiver list empty");
console.log("chromecast receiver list empty");
this.hasReceivers = false;
}
};
@ -179,7 +179,7 @@
*/
CastPlayer.prototype.sessionUpdateListener = function (isAlive) {
Logger.log('sessionUpdateListener alive: ' + isAlive);
console.log('sessionUpdateListener alive: ' + isAlive);
if (isAlive) {
}
@ -188,7 +188,7 @@
this.deviceState = DEVICE_STATE.IDLE;
this.castPlayerState = PLAYER_STATE.IDLE;
Logger.log('sessionUpdateListener: setting currentMediaSession to null');
console.log('sessionUpdateListener: setting currentMediaSession to null');
this.currentMediaSession = null;
MediaController.removeActivePlayer(PlayerName);
@ -201,7 +201,7 @@
* session request in opt_sessionRequest.
*/
CastPlayer.prototype.launchApp = function () {
Logger.log("chromecast launching app...");
console.log("chromecast launching app...");
chrome.cast.requestSession(this.onRequestSessionSuccess.bind(this), this.onLaunchError.bind(this));
};
@ -211,7 +211,7 @@
*/
CastPlayer.prototype.onRequestSessionSuccess = function (e) {
Logger.log("chromecast session success: " + e.sessionId);
console.log("chromecast session success: " + e.sessionId);
this.onSessionConnected(e);
};
@ -238,7 +238,7 @@
*/
CastPlayer.prototype.sessionMediaListener = function (e) {
Logger.log('sessionMediaListener');
console.log('sessionMediaListener');
this.currentMediaSession = e;
this.currentMediaSession.addUpdateListener(this.mediaStatusUpdateHandler);
};
@ -247,7 +247,7 @@
* Callback function for launch error
*/
CastPlayer.prototype.onLaunchError = function () {
Logger.log("chromecast launch error");
console.log("chromecast launch error");
this.deviceState = DEVICE_STATE.ERROR;
//Dashboard.alert({
@ -276,11 +276,11 @@
* Callback function for stop app success
*/
CastPlayer.prototype.onStopAppSuccess = function (message) {
Logger.log(message);
console.log(message);
this.deviceState = DEVICE_STATE.IDLE;
this.castPlayerState = PLAYER_STATE.IDLE;
Logger.log('onStopAppSuccess: setting currentMediaSession to null');
console.log('onStopAppSuccess: setting currentMediaSession to null');
this.currentMediaSession = null;
};
@ -291,7 +291,7 @@
CastPlayer.prototype.loadMedia = function (options, command) {
if (!this.session) {
Logger.log("no session");
console.log("no session");
return;
}
@ -370,13 +370,13 @@
CastPlayer.prototype.sendMessageInternal = function (message) {
message = JSON.stringify(message);
//Logger.log(message);
//console.log(message);
this.session.sendMessage(messageNamespace, message, this.onPlayCommandSuccess.bind(this), this.errorHandler);
};
CastPlayer.prototype.onPlayCommandSuccess = function () {
Logger.log('Message was sent to receiver ok.');
console.log('Message was sent to receiver ok.');
};
/**
@ -385,7 +385,7 @@
*/
CastPlayer.prototype.onMediaDiscovered = function (how, mediaSession) {
Logger.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
this.currentMediaSession = mediaSession;
if (how == 'loadMedia') {
@ -408,7 +408,7 @@
if (e == false) {
this.castPlayerState = PLAYER_STATE.IDLE;
}
Logger.log("chromecast updating media: " + e);
console.log("chromecast updating media: " + e);
};
/**
@ -418,7 +418,7 @@
CastPlayer.prototype.setReceiverVolume = function (mute, vol) {
if (!this.currentMediaSession) {
Logger.log('this.currentMediaSession is null');
console.log('this.currentMediaSession is null');
return;
}
@ -446,7 +446,7 @@
* Callback function for media command success
*/
CastPlayer.prototype.mediaCommandSuccessCallback = function (info, e) {
Logger.log(info);
console.log(info);
};
// Create Cast Player
@ -483,18 +483,18 @@
}
};
$(castPlayer).on("connect", function (e) {
Events.on(castPlayer, "connect", function (e) {
MediaController.setActivePlayer(PlayerName, self.getCurrentTargetInfo());
Logger.log('cc: connect');
console.log('cc: connect');
// Reset this so the next query doesn't make it appear like content is playing.
self.lastPlayerData = {};
});
$(castPlayer).on("playbackstart", function (e, data) {
Events.on(castPlayer, "playbackstart", function (e, data) {
Logger.log('cc: playbackstart');
console.log('cc: playbackstart');
castPlayer.initializeCastPlayer();
@ -502,9 +502,9 @@
Events.trigger(self, "playbackstart", [state]);
});
$(castPlayer).on("playbackstop", function (e, data) {
Events.on(castPlayer, "playbackstop", function (e, data) {
Logger.log('cc: playbackstop');
console.log('cc: playbackstop');
var state = self.getPlayerStateInternal(data);
Events.trigger(self, "playbackstop", [state]);
@ -513,9 +513,9 @@
self.lastPlayerData = {};
});
$(castPlayer).on("playbackprogress", function (e, data) {
Events.on(castPlayer, "playbackprogress", function (e, data) {
Logger.log('cc: positionchange');
console.log('cc: positionchange');
var state = self.getPlayerStateInternal(data);
Events.trigger(self, "positionchange", [state]);
@ -825,7 +825,7 @@
data = data || self.lastPlayerData;
self.lastPlayerData = data;
Logger.log(JSON.stringify(data));
console.log(JSON.stringify(data));
return data;
};
@ -843,7 +843,7 @@
MediaController.registerPlayer(new chromecastPlayer());
$(MediaController).on('playerchange', function (e, newPlayer, newTarget) {
Events.on(MediaController, 'playerchange', function (e, newPlayer, newTarget) {
if (newPlayer.name == PlayerName) {
if (castPlayer.deviceState != DEVICE_STATE.ACTIVE && castPlayer.isInitialized) {
castPlayer.launchApp();

View file

@ -22,8 +22,8 @@
DashboardPage.pollForInfo(page);
DashboardPage.startInterval(apiClient);
$(apiClient).on("websocketmessage", DashboardPage.onWebSocketMessage)
.on("websocketopen", DashboardPage.onWebSocketOpen);
Events.on(apiClient, 'websocketmessage', DashboardPage.onWebSocketMessage);
Events.on(apiClient, 'websocketopen', DashboardPage.onWebSocketOpen);
DashboardPage.lastAppUpdateCheck = null;
DashboardPage.lastPluginUpdateCheck = null;
@ -53,7 +53,8 @@
var apiClient = ApiClient;
if (apiClient) {
$(apiClient).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange);
Events.off(apiClient, 'websocketmessage', DashboardPage.onWebSocketMessage);
Events.off(apiClient, 'websocketopen', DashboardPage.onWebSocketOpen);
DashboardPage.stopInterval(apiClient);
}
@ -1195,7 +1196,8 @@ $(document).on('pageshow', "#dashboardPage", DashboardPage.onPageShow).on('pageb
return;
}
$(apiClient).on('websocketmessage', onSocketMessage).on('websocketopen', onSocketOpen);
Events.on(apiClient, 'websocketopen', onSocketOpen);
Events.on(apiClient, 'websocketmessage', onSocketMessage);
}
function startListening(apiClient) {
@ -1239,7 +1241,8 @@ $(document).on('pageshow', "#dashboardPage", DashboardPage.onPageShow).on('pageb
var apiClient = ApiClient;
if (apiClient) {
$(apiClient).off('websocketopen', onSocketOpen).off('websocketmessage', onSocketOpen);
Events.off(apiClient, 'websocketopen', onSocketOpen);
Events.off(apiClient, 'websocketmessage', onSocketMessage);
stopListening(apiClient);
}

View file

@ -1090,7 +1090,7 @@
var page = $.mobile.activePage;
Logger.log('Item updated - reloading metadata');
console.log('Item updated - reloading metadata');
reload(page);
}
}
@ -1098,12 +1098,12 @@
function bindItemChanged(page) {
$(ApiClient).on("websocketmessage", onWebSocketMessageReceived);
Events.on(ApiClient, "websocketmessage", onWebSocketMessageReceived);
}
function unbindItemChanged(page) {
$(ApiClient).off("websocketmessage", onWebSocketMessageReceived);
Events.off(ApiClient, "websocketmessage", onWebSocketMessageReceived);
}
function onItemDeleted(e, itemId) {
@ -1221,13 +1221,13 @@
var page = this;
$(LibraryBrowser).on('itemdeleting', onItemDeleted);
Events.on(LibraryBrowser, 'itemdeleting', onItemDeleted);
reload(page);
}).on('pagebeforehide', "#editItemMetadataPage", function () {
var page = this;
$(LibraryBrowser).off('itemdeleting', onItemDeleted);
Events.off(LibraryBrowser, 'itemdeleting', onItemDeleted);
unbindItemChanged(page);
});

View file

@ -71,7 +71,6 @@
page.querySelector('.listTopPaging').innerHTML = pagingHtml;
updateFilterControls(page, viewPanel);
var trigger = false;
if (view == "List") {
@ -79,7 +78,6 @@
items: result.Items,
sortBy: query.SortBy
});
trigger = true;
}
else if (view == "Poster") {
html += LibraryBrowser.getPosterViewHtml({
@ -108,10 +106,6 @@
elem.innerHTML = html + pagingHtml;
ImageLoader.lazyChildren(elem);
if (trigger) {
Events.trigger(elem, 'create');
}
$('.btnNextPage', page).on('click', function () {
query.StartIndex += query.Limit;
reloadItems(page, viewPanel);

View file

@ -383,7 +383,7 @@
$('.sliderValue', elem).html(tooltext);
Logger.log("slidin", pct, self.currentDurationTicks, time);
console.log("slidin", pct, self.currentDurationTicks, time);
});
});

View file

@ -30,14 +30,14 @@
var requestUrl = url + "?v=" + AppInfo.appVersion;
Logger.log('Requesting ' + requestUrl);
console.log('Requesting ' + requestUrl);
var xhr = new XMLHttpRequest();
xhr.open('GET', requestUrl, true);
var onError = function () {
Logger.log('Dictionary not found. Reverting to english');
console.log('Dictionary not found. Reverting to english');
// Grab the english version
var xhr2 = new XMLHttpRequest();
@ -53,7 +53,7 @@
xhr.onload = function (e) {
Logger.log('Globalize response status: ' + this.status);
console.log('Globalize response status: ' + this.status);
if (this.status < 400) {
@ -74,7 +74,7 @@
var currentCulture = 'en-US';
function setCulture(value) {
Logger.log('Setting culture to ' + value);
console.log('Setting culture to ' + value);
currentCulture = value;
return Promise.all([loadDictionary('html', value), loadDictionary('javascript', value)]);
@ -105,13 +105,13 @@
} else if (AppInfo.supportsUserDisplayLanguageSetting) {
Logger.log('AppInfo.supportsUserDisplayLanguageSetting is true');
console.log('AppInfo.supportsUserDisplayLanguageSetting is true');
resolve(AppSettings.displayLanguage());
} else {
Logger.log('Getting culture from document');
console.log('Getting culture from document');
resolve(document.documentElement.getAttribute('data-culture'));
}
});
@ -120,7 +120,7 @@
function ensure() {
Logger.log('Entering Globalize.ensure');
console.log('Entering Globalize.ensure');
return getDeviceCulture().then(function (culture) {

View file

@ -3,6 +3,7 @@
var supportsTextTracks;
var hlsPlayer;
var requiresSettingStartTimeOnStart;
var subtitleTrackIndexToSetOnPlaying;
function htmlMediaRenderer(options) {
@ -26,7 +27,7 @@
function onEnded() {
showStatusBar();
$(self).trigger('ended');
Events.trigger(self, 'ended');
}
function onTimeUpdate() {
@ -46,50 +47,58 @@
// }
//}
$(self).trigger('timeupdate');
Events.trigger(self, 'timeupdate');
}
function onVolumeChange() {
$(self).trigger('volumechange');
Events.trigger(self, 'volumechange');
}
function onOneAudioPlaying() {
function onOneAudioPlaying(e) {
var elem = e.target;
elem.removeEventListener('playing', onOneAudioPlaying);
$('.mediaPlayerAudioContainer').hide();
}
function onPlaying() {
$(self).trigger('playing');
Events.trigger(self, 'playing');
}
function onPlay() {
$(self).trigger('play');
Events.trigger(self, 'play');
}
function onPause() {
$(self).trigger('pause');
Events.trigger(self, 'pause');
}
function onClick() {
$(self).trigger('click');
Events.trigger(self, 'click');
}
function onDblClick() {
$(self).trigger('dblclick');
Events.trigger(self, 'dblclick');
}
function onError() {
function onError(e) {
var errorCode = this.error ? this.error.code : '';
Logger.log('Media element error code: ' + errorCode);
var elem = e.target;
var errorCode = elem.error ? elem.error.code : '';
console.log('Media element error code: ' + errorCode);
showStatusBar();
$(self).trigger('error');
Events.trigger(self, 'error');
}
function onLoadedMetadata() {
function onLoadedMetadata(e) {
var elem = e.target;
elem.removeEventListener('loadedmetadata', onLoadedMetadata);
if (!hlsPlayer) {
this.play();
elem.play();
}
}
@ -119,14 +128,19 @@
return 0;
}
function onOneVideoPlaying() {
function onOneVideoPlaying(e) {
hideStatusBar();
var element = e.target;
element.removeEventListener('playing', onOneVideoPlaying);
self.setCurrentTrackElement(subtitleTrackIndexToSetOnPlaying);
var requiresNativeControls = !self.enableCustomVideoControls();
if (requiresNativeControls) {
$(this).attr('controls', 'controls');
$(element).attr('controls', 'controls');
}
if (requiresSettingStartTimeOnStart) {
@ -138,7 +152,6 @@
if (startPositionInSeekParam && src.indexOf('.m3u8') != -1) {
var delay = browserInfo.safari ? 2500 : 0;
var element = this;
if (delay) {
setTimeout(function () {
element.currentTime = startPositionInSeekParam;
@ -173,15 +186,18 @@
elem = $('.mediaPlayerAudio');
}
return $(elem)
.on('timeupdate', onTimeUpdate)
.on('ended', onEnded)
.on('volumechange', onVolumeChange)
.one('playing', onOneAudioPlaying)
.on('play', onPlay)
.on('pause', onPause)
.on('playing', onPlaying)
.on('error', onError)[0];
elem = elem[0];
elem.addEventListener('playing', onOneAudioPlaying);
elem.addEventListener('timeupdate', onTimeUpdate);
elem.addEventListener('ended', onEnded);
elem.addEventListener('volumechange', onVolumeChange);
elem.addEventListener('error', onError);
elem.addEventListener('pause', onPause);
elem.addEventListener('play', onPlay);
elem.addEventListener('playing', onPlaying);
return elem;
}
function enableHlsPlayer(src) {
@ -221,18 +237,24 @@
var elem = $('#videoElement', '#videoPlayer').prepend(html);
return $('.itemVideo', elem)
.one('.loadedmetadata', onLoadedMetadata)
.one('playing', onOneVideoPlaying)
.on('timeupdate', onTimeUpdate)
.on('ended', onEnded)
.on('volumechange', onVolumeChange)
.on('play', onPlay)
.on('pause', onPause)
.on('playing', onPlaying)
.on('click', onClick)
.on('dblclick', onDblClick)
.on('error', onError)[0];
var itemVideo = $('.itemVideo', elem)[0];
itemVideo.addEventListener('loadedmetadata', onLoadedMetadata);
itemVideo.addEventListener('playing', onOneVideoPlaying);
itemVideo.addEventListener('timeupdate', onTimeUpdate);
itemVideo.addEventListener('ended', onEnded);
itemVideo.addEventListener('volumechange', onVolumeChange);
itemVideo.addEventListener('voluplaymechange', onPlay);
itemVideo.addEventListener('pause', onPause);
itemVideo.addEventListener('playing', onPlaying);
itemVideo.addEventListener('click', onClick);
itemVideo.addEventListener('dblclick', onDblClick);
itemVideo.addEventListener('error', onError);
return itemVideo;
}
// Save this for when playback stops, because querying the time at that point might return 0
@ -274,7 +296,7 @@
hlsPlayer.destroy();
}
catch (err) {
Logger.log(err);
console.log(err);
}
hlsPlayer = null;
@ -365,6 +387,15 @@
tracks = tracks || [];
var currentTrackIndex = -1;
for (var i = 0, length = tracks.length; i < length; i++) {
if (tracks[i].isDefault) {
currentTrackIndex = i;
break;
}
}
subtitleTrackIndexToSetOnPlaying = currentTrackIndex;
if (enableHlsPlayer(val)) {
setTracks(elem, tracks);
@ -384,18 +415,10 @@
setTracks(elem, tracks);
$(elem).one("loadedmetadata", onLoadedMetadata);
elem.addEventListener("loadedmetadata", onLoadedMetadata);
playNow = true;
}
var currentTrackIndex = -1;
for (var i = 0, length = tracks.length; i < length; i++) {
if (tracks[i].isDefault) {
currentTrackIndex = i;
break;
}
}
self.setCurrentTrackElement(currentTrackIndex);
}
@ -448,28 +471,28 @@
if (elem.tagName == 'AUDIO') {
Events.off(elem, 'timeupdate', onTimeUpdate);
Events.off(elem, 'ended', onEnded);
Events.off(elem, 'volumechange', onVolumeChange);
Events.off(elem, 'playing', onOneAudioPlaying);
Events.off(elem, 'play', onPlay);
Events.off(elem, 'pause', onPause);
Events.off(elem, 'playing', onPlaying);
Events.off(elem, 'error', onError);
elem.removeEventListener('timeupdate', onTimeUpdate);
elem.removeEventListener('ended', onEnded);
elem.removeEventListener('volumechange', onVolumeChange);
elem.removeEventListener('playing', onOneAudioPlaying);
elem.removeEventListener('play', onPlay);
elem.removeEventListener('pause', onPause);
elem.removeEventListener('playing', onPlaying);
elem.removeEventListener('error', onError);
} else {
Events.off(elem, 'loadedmetadata', onLoadedMetadata);
Events.off(elem, 'playing', onOneVideoPlaying);
Events.off(elem, 'timeupdate', onTimeUpdate);
Events.off(elem, 'ended', onEnded);
Events.off(elem, 'volumechange', onVolumeChange);
Events.off(elem, 'play', onPlay);
Events.off(elem, 'pause', onPause);
Events.off(elem, 'playing', onPlaying);
Events.off(elem, 'click', onClick);
Events.off(elem, 'dblclick', onDblClick);
Events.off(elem, 'error', onError);
elem.removeEventListener('loadedmetadata', onLoadedMetadata);
elem.removeEventListener('playing', onOneVideoPlaying);
elem.removeEventListener('timeupdate', onTimeUpdate);
elem.removeEventListener('ended', onEnded);
elem.removeEventListener('volumechange', onVolumeChange);
elem.removeEventListener('play', onPlay);
elem.removeEventListener('pause', onPause);
elem.removeEventListener('playing', onPlaying);
elem.removeEventListener('click', onClick);
elem.removeEventListener('dblclick', onDblClick);
elem.removeEventListener('error', onError);
}
if (elem.tagName.toLowerCase() != 'audio') {
@ -492,7 +515,7 @@
self.setCurrentTrackElement = function (trackIndex) {
Logger.log('Setting new text track index to: ' + trackIndex);
console.log('Setting new text track index to: ' + trackIndex);
var allTracks = mediaElement.textTracks; // get list of tracks
@ -508,7 +531,7 @@
mode = 0; // hide all other tracks
}
Logger.log('Setting track ' + i + ' mode to: ' + mode);
console.log('Setting track ' + i + ' mode to: ' + mode);
// Safari uses integers for the mode property
// http://www.jwplayer.com/html5/scripting/
@ -545,7 +568,7 @@
track.removeCue(track.cues[0]);
}
} catch (e) {
Logger.log('Error removing cue from textTrack');
console.log('Error removing cue from textTrack');
}
}

View file

@ -286,13 +286,13 @@
pageIdOn('pageshow', "indexPage", function () {
var page = this;
$(MediaController).on('playbackstop', onPlaybackStop);
Events.on(MediaController, 'playbackstop', onPlaybackStop);
});
pageIdOn('pagebeforehide', "indexPage", function () {
var page = this;
$(MediaController).off('playbackstop', onPlaybackStop);
Events.off(MediaController, 'playbackstop', onPlaybackStop);
});
function onPlaybackStop(e, state) {

View file

@ -123,7 +123,7 @@
}
if (NavHelper.isBack()) {
Logger.log('Not refreshing data because IsBack=true');
console.log('Not refreshing data because IsBack=true');
return false;
}
@ -139,7 +139,7 @@
}
if ((now - last) < cacheDuration) {
Logger.log('Not refreshing data due to age');
console.log('Not refreshing data due to age');
return false;
}
@ -155,7 +155,7 @@
enableFullPaperTabs: function () {
if (browserInfo.animate && !browserInfo.mobile) {
//return true;
return true;
}
return AppInfo.isNativeApp;
@ -385,11 +385,11 @@
if (isFirstLoad) {
Logger.log('selected tab is null, checking query string');
console.log('selected tab is null, checking query string');
var selected = parseInt(getParameterByName('tab') || '0');
Logger.log('selected tab will be ' + selected);
console.log('selected tab will be ' + selected);
if (LibraryBrowser.enableFullPaperTabs()) {
@ -3364,7 +3364,7 @@
miscInfo.push(text);
}
catch (e) {
Logger.log("Error parsing date: " + item.PremiereDate);
console.log("Error parsing date: " + item.PremiereDate);
}
}
}
@ -3383,7 +3383,7 @@
}
}
catch (e) {
Logger.log("Error parsing date: " + item.PremiereDate);
console.log("Error parsing date: " + item.PremiereDate);
}
}
@ -3409,7 +3409,7 @@
}
catch (e) {
Logger.log("Error parsing date: " + item.EndDate);
console.log("Error parsing date: " + item.EndDate);
}
}
@ -3430,7 +3430,7 @@
miscInfo.push(text);
}
catch (e) {
Logger.log("Error parsing date: " + item.PremiereDate);
console.log("Error parsing date: " + item.PremiereDate);
}
}
}

View file

@ -1377,7 +1377,8 @@
}
function initializeApiClient(apiClient) {
$(apiClient).off('websocketmessage', onWebSocketMessage).on('websocketmessage', onWebSocketMessage);
Events.off(apiClient, "websocketmessage", onWebSocketMessage);
Events.on(apiClient, "websocketmessage", onWebSocketMessage);
}
function clearRefreshTimes() {
@ -1388,7 +1389,7 @@
initializeApiClient(window.ApiClient);
}
$(ConnectionManager).on('apiclientcreated', function (e, apiClient) {
Events.on(ConnectionManager, 'apiclientcreated', function (e, apiClient) {
initializeApiClient(apiClient);
});

View file

@ -204,7 +204,7 @@
refreshLibraryInfoInDrawer(user, drawer);
refreshBottomUserInfoInDrawer(user, drawer);
Events.trigger(document, 'libraryMenuCreated');
document.dispatchEvent(new CustomEvent("libraryMenuCreated", {}));
updateLibraryMenu(user.localUser);
}

View file

@ -133,7 +133,7 @@
airDate = parseISO8601Date(airDate, { toLocal: true }).toLocaleDateString();
}
catch (e) {
Logger.log("Error parsing date: " + airDate);
console.log("Error parsing date: " + airDate);
}

View file

@ -43,7 +43,7 @@
html += '</ul>';
Events.trigger($('.serverLogs', page).html(html)[0], 'create');
$('.serverLogs', page).html(html).trigger('create');
});
});

View file

@ -192,7 +192,7 @@
if (bypass()) return;
Logger.log("keyCode", e.keyCode);
console.log("keyCode", e.keyCode);
if (keyResult[e.keyCode]) {
e.preventDefault();
@ -307,7 +307,7 @@
currentPlayer = player;
currentTargetInfo = targetInfo;
Logger.log('Active player: ' + JSON.stringify(currentTargetInfo));
console.log('Active player: ' + JSON.stringify(currentTargetInfo));
triggerPlayerChange(player, targetInfo);
};
@ -336,7 +336,7 @@
currentPlayer = player;
currentTargetInfo = targetInfo;
Logger.log('Active player: ' + JSON.stringify(currentTargetInfo));
console.log('Active player: ' + JSON.stringify(currentTargetInfo));
triggerPlayerChange(player, targetInfo);
});
@ -720,7 +720,7 @@
// Full list
// https://github.com/MediaBrowser/MediaBrowser/blob/master/MediaBrowser.Model/Session/GeneralCommand.cs#L23
Logger.log('MediaController received command: ' + cmd.Name);
console.log('MediaController received command: ' + cmd.Name);
switch (cmd.Name) {
case 'SetRepeatMode':
@ -950,7 +950,7 @@
require(['localassetmanager'], function () {
LocalAssetManager.fileExists(mediaSource.Path).then(function (exists) {
Logger.log('LocalAssetManager.fileExists: path: ' + mediaSource.Path + ' result: ' + exists);
console.log('LocalAssetManager.fileExists: path: ' + mediaSource.Path + ' result: ' + exists);
deferred.resolveWith(null, [exists]);
});
});
@ -1026,7 +1026,8 @@
}
function initializeApiClient(apiClient) {
$(apiClient).off("websocketmessage", onWebSocketMessageReceived).on("websocketmessage", onWebSocketMessageReceived);
Events.off(apiClient, "websocketmessage", onWebSocketMessageReceived);
Events.on(apiClient, "websocketmessage", onWebSocketMessageReceived);
}
MediaController.init = function () {
@ -1034,7 +1035,7 @@
initializeApiClient(window.ApiClient);
}
$(ConnectionManager).on('apiclientcreated', function (e, apiClient) {
Events.on(ConnectionManager, 'apiclientcreated', function (e, apiClient) {
initializeApiClient(apiClient);
});
};

View file

@ -77,11 +77,14 @@
return currentStream.Type == "Subtitle";
});
var currentIndex = self.currentSubtitleStreamIndex || -1;
var currentIndex = self.currentSubtitleStreamIndex;
if (currentIndex == null) {
currentIndex = -1;
}
streams.unshift({
Index: -1,
Language: "Off"
Language: Globalize.translate('ButtonOff')
});
var menuItems = streams.map(function (stream) {
@ -880,6 +883,15 @@
function bindEventsForPlayback(mediaRenderer) {
Events.on(mediaRenderer, 'playing', onOnePlaying);
Events.on(mediaRenderer, 'playing', onPlaying);
Events.on(mediaRenderer, 'volumechange', onVolumeChange);
Events.on(mediaRenderer, 'pause', onPause);
Events.on(mediaRenderer, 'timeupdate', onTimeUpdate);
Events.on(mediaRenderer, 'error', onError);
Events.on(mediaRenderer, 'click', onClick);
Events.on(mediaRenderer, 'dblclick', onDoubleClick);
var hideElementsOnIdle = true;
if (hideElementsOnIdle) {
@ -908,6 +920,16 @@
function unbindEventsForPlayback(mediaRenderer) {
Events.off(mediaRenderer, 'playing', onOnePlaying);
Events.off(mediaRenderer, 'playing', onPlaying);
Events.off(mediaRenderer, 'volumechange', onVolumeChange);
Events.off(mediaRenderer, 'pause', onPause);
Events.off(mediaRenderer, 'timeupdate', onTimeUpdate);
Events.off(mediaRenderer, 'error', onError);
Events.off(mediaRenderer, 'click', onClick);
Events.off(mediaRenderer, 'dblclick', onDoubleClick);
$(document).off('webkitfullscreenchange', onFullScreenChange);
$(document).off('mozfullscreenchange', onFullScreenChange);
$(document).off('msfullscreenchange', onFullScreenChange);
@ -1091,77 +1113,6 @@
volumeSlider.value = initialVolume * 100;
updateVolumeButtons(initialVolume);
$(mediaRenderer).on("volumechange.mediaplayerevent", function (e) {
updateVolumeButtons(this.volume());
}).one("playing.mediaplayerevent", function () {
// For some reason this is firing at the start, so don't bind until playback has begun
$(this).on("ended", self.onPlaybackStopped).one('ended', self.playNextAfterEnded);
self.onPlaybackStart(this, item, mediaSource);
}).on("pause.mediaplayerevent", function (e) {
$('#video-playButton', videoControls).show();
$('#video-pauseButton', videoControls).hide();
$("#pause", videoElement).show().addClass("fadeOut");
setTimeout(function () {
$("#pause", videoElement).hide().removeClass("fadeOut");
}, 300);
}).on("playing.mediaplayerevent", function (e) {
$('#video-playButton', videoControls).hide();
$('#video-pauseButton', videoControls).show();
$("#play", videoElement).show().addClass("fadeOut");
setTimeout(function () {
$("#play", videoElement).hide().removeClass("fadeOut");
}, 300);
}).on("timeupdate.mediaplayerevent", function () {
if (!positionSlider.dragging) {
self.setCurrentTime(self.getCurrentTicks(this), positionSlider, currentTimeElement);
}
}).on("error.mediaplayerevent", function () {
var errorMsg = Globalize.translate('MessageErrorPlayingVideo');
if (item.Type == "TvChannel") {
errorMsg += '<p>';
errorMsg += Globalize.translate('MessageEnsureOpenTuner');
errorMsg += '</p>';
}
Dashboard.alert({
title: Globalize.translate('HeaderVideoError'),
message: errorMsg
});
self.onPlaybackStopped.call(mediaRenderer);
self.nextTrack();
}).on("click.mediaplayerevent", function (e) {
if (!browserInfo.mobile) {
if (this.paused()) {
self.unpause();
} else {
self.pause();
}
}
}).on("dblclick.mediaplayerevent", function () {
if (!browserInfo.mobile) {
self.toggleFullscreen();
}
});
bindEventsForPlayback(mediaRenderer);
self.currentSubtitleStreamIndex = mediaSource.DefaultSubtitleStreamIndex;
@ -1186,6 +1137,90 @@
});
};
function onOnePlaying() {
Events.off(this, 'playing', onOnePlaying);
// For some reason this is firing at the start, so don't bind until playback has begun
Events.on(this, 'ended', self.onPlaybackStopped);
Events.on(this, 'ended', self.playNextAfterEnded);
self.onPlaybackStart(this, self.currentItem, self.currentMediaSource);
}
function onPlaying() {
var videoControls = document.querySelector('#videoPlayer .videoControls');
var videoElement = document.querySelector('#videoPlayer #videoElement');
$('#video-playButton', videoControls).hide();
$('#video-pauseButton', videoControls).show();
$("#play", videoElement).show().addClass("fadeOut");
setTimeout(function () {
$("#play", videoElement).hide().removeClass("fadeOut");
}, 300);
}
function onVolumeChange() {
updateVolumeButtons(this.volume());
}
function onPause() {
var videoControls = document.querySelector('#videoPlayer .videoControls');
var videoElement = document.querySelector('#videoPlayer #videoElement');
$('#video-playButton', videoControls).show();
$('#video-pauseButton', videoControls).hide();
$("#pause", videoElement).show().addClass("fadeOut");
setTimeout(function () {
$("#pause", videoElement).hide().removeClass("fadeOut");
}, 300);
}
function onTimeUpdate() {
if (!positionSlider.dragging) {
self.setCurrentTime(self.getCurrentTicks(this), positionSlider, currentTimeElement);
}
}
function onError() {
var errorMsg = Globalize.translate('MessageErrorPlayingVideo');
if (item.Type == "TvChannel") {
errorMsg += '<p>';
errorMsg += Globalize.translate('MessageEnsureOpenTuner');
errorMsg += '</p>';
}
Dashboard.alert({
title: Globalize.translate('HeaderVideoError'),
message: errorMsg
});
self.onPlaybackStopped.call(mediaRenderer);
self.nextTrack();
}
function onClick() {
if (!browserInfo.mobile) {
if (this.paused()) {
self.unpause();
} else {
self.pause();
}
}
}
function onDoubleClick() {
if (!browserInfo.mobile) {
self.toggleFullscreen();
}
}
self.updatePlaylistUi = function () {
if (!initComplete) {

View file

@ -207,7 +207,7 @@
profile.TranscodingProfiles.push({
Container: 'mkv',
Type: 'Video',
AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : ''),
AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : '') + (canPlayMp3 ? ',mp3' : ''),
VideoCodec: 'h264',
Context: 'Streaming'
});
@ -311,40 +311,6 @@
}]
});
if (!isVlc) {
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'aac',
Container: 'mkv,mov',
Conditions: [
{
Condition: 'NotEquals',
Property: 'AudioProfile',
Value: 'HE-AAC'
}
// Disabling this is going to require us to learn why it was disabled in the first place
//,
//{
// Condition: 'NotEquals',
// Property: 'AudioProfile',
// Value: 'LC'
//}
]
});
}
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'aac',
Conditions: [
{
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: '6'
}
]
});
// These don't play very well
if (isVlc) {
profile.CodecProfiles.push({
@ -358,6 +324,69 @@
}
]
});
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'aac,mp3',
Conditions: [
{
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: '6'
}
]
});
} else {
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'aac',
Container: 'mkv,mov',
Conditions: [
{
Condition: 'NotEquals',
Property: 'AudioProfile',
Value: 'HE-AAC'
},
{
Condition: 'Equals',
Property: 'IsSecondaryAudio',
Value: 'false',
IsRequired: 'false'
},
{
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: '6'
}
// Disabling this is going to require us to learn why it was disabled in the first place
//,
//{
// Condition: 'NotEquals',
// Property: 'AudioProfile',
// Value: 'LC'
//}
]
});
profile.CodecProfiles.push({
Type: 'VideoAudio',
Conditions: [
{
Condition: 'Equals',
Property: 'IsSecondaryAudio',
Value: 'false',
IsRequired: 'false'
},
{
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: '6'
}
]
});
}
if (isVlc) {
@ -543,6 +572,10 @@
self.playNextAfterEnded = function () {
console.log('playNextAfterEnded');
Events.off(this, 'ended', self.playNextAfterEnded);
self.nextTrack();
};
@ -661,16 +694,18 @@
Events.off(mediaRenderer, 'ended', self.onPlaybackStopped);
Events.off(mediaRenderer, 'ended', self.playNextAfterEnded);
$(mediaRenderer).one("play", function () {
function onPlayingOnce() {
Events.off(this, "play", onPlayingOnce);
Events.on(this, 'ended', self.onPlaybackStopped);
$(this).one('ended', self.playNextAfterEnded);
Events.on(this, 'ended', self.playNextAfterEnded);
self.startProgressInterval();
sendProgressUpdate();
}
});
Events.on(mediaRenderer, "play", onPlayingOnce);
if (self.currentItem.MediaType == "Video") {
ApiClient.stopActiveEncodings(playSessionId).then(function () {
@ -958,13 +993,9 @@
if (mediaSource.TranscodingSubProtocol == 'hls') {
if (mediaSource.RunTimeTicks) {
// Reports of stuttering with h264 stream copy in IE
mediaUrl += '&EnableAutoStreamCopy=false';
}
mediaUrl += seekParam;
contentType = 'application/x-mpegURL';
} else {
// Reports of stuttering with h264 stream copy in IE
@ -1044,7 +1075,7 @@
LocalAssetManager.translateFilePath(resultInfo.url).then(function (path) {
resultInfo.url = path;
Logger.log('LocalAssetManager.translateFilePath: path: ' + resultInfo.url + ' result: ' + path);
console.log('LocalAssetManager.translateFilePath: path: ' + resultInfo.url + ' result: ' + path);
deferred.resolveWith(null, [resultInfo]);
});
});
@ -1086,7 +1117,7 @@
Dashboard.showLoadingMsg();
ApiClient.detectBitrate().then(function (bitrate) {
Logger.log('Max bitrate auto detected to ' + bitrate);
console.log('Max bitrate auto detected to ' + bitrate);
self.lastBitrateDetections[bitrateDetectionKey] = new Date().getTime();
AppSettings.maxStreamingBitrate(bitrate);
@ -1295,7 +1326,7 @@
if (newItem) {
Logger.log('playing next track');
console.log('playing next track');
self.playInternal(newItem, 0, function () {
self.setPlaylistState(newIndex);
@ -1433,7 +1464,7 @@
if (self.currentMediaRenderer) {
Logger.log('MediaPlayer toggling mute');
console.log('MediaPlayer toggling mute');
if (self.volume()) {
self.mute();
@ -1462,7 +1493,7 @@
if (self.currentMediaRenderer) {
Logger.log('MediaPlayer setting volume to ' + val);
console.log('MediaPlayer setting volume to ' + val);
self.currentMediaRenderer.volume(val / 100);
self.onVolumeChanged(self.currentMediaRenderer);
@ -1550,25 +1581,23 @@
if (mediaRenderer) {
mediaRenderer.stop();
Events.off(mediaRenderer, 'ended', self.playNextAfterEnded);
$(mediaRenderer).one("ended", function () {
$(this).off('.mediaplayerevent');
this.cleanup(destroyRenderer);
self.currentMediaRenderer = null;
self.currentItem = null;
self.currentMediaSource = null;
self.currentSubtitleStreamIndex = null;
self.streamInfo = {};
});
mediaRenderer.stop();
Events.trigger(mediaRenderer, "ended");
//self.onPlaybackStopped.call(mediaRenderer);
// TODO: Unbind video events
unBindAudioEvents(mediaRenderer);
mediaRenderer.cleanup(destroyRenderer);
self.currentMediaRenderer = null;
self.currentItem = null;
self.currentMediaSource = null;
self.currentSubtitleStreamIndex = null;
self.streamInfo = {};
} else {
self.currentMediaRenderer = null;
@ -1583,6 +1612,14 @@
}
};
function unBindAudioEvents(mediaRenderer) {
Events.off(mediaRenderer, "volumechange", onVolumeChange);
Events.off(mediaRenderer, "pause", onPause);
Events.off(mediaRenderer, "playing", onPlaying);
Events.off(mediaRenderer, "timeupdate", onTimeUpdate);
}
self.isPlaying = function () {
return self.playlist.length > 0;
};
@ -1761,14 +1798,14 @@
self.onPlaybackStopped = function () {
Logger.log('playback stopped');
console.log('playback stopped');
document.body.classList.remove('bodyWithPopupOpen');
var mediaRenderer = this;
Events.off(mediaRenderer, '.mediaplayerevent');
// TODO: Unbind other events
unBindAudioEvents(mediaRenderer);
Events.off(mediaRenderer, 'ended', self.onPlaybackStopped);
var item = self.currentItem;
@ -1790,6 +1827,8 @@
self.onPlaystateChange = function (mediaRenderer) {
console.log('mediaplayer onPlaystateChange');
var state = self.getPlayerStateInternal(mediaRenderer, self.currentItem, self.currentMediaSource);
Events.trigger(self, 'playstatechange', [state]);
@ -1939,44 +1978,24 @@
poster: self.getPosterUrl(item)
});
Events.on(mediaRenderer, "volumechange.mediaplayerevent", function () {
function onPlayingOnce() {
Logger.log('audio element event: volumechange');
Events.off(mediaRenderer, "playing", onPlayingOnce);
self.onVolumeChanged(this);
});
$(mediaRenderer).one("playing.mediaplayerevent", function () {
Logger.log('audio element event: playing');
console.log('audio element event: playing');
// For some reason this is firing at the start, so don't bind until playback has begun
Events.on(this, 'ended', self.onPlaybackStopped);
Events.on(mediaRenderer, 'ended', self.onPlaybackStopped);
Events.on(mediaRenderer, 'ended', self.playNextAfterEnded);
$(this).one('ended', self.playNextAfterEnded);
self.onPlaybackStart(mediaRenderer, item, mediaSource);
}
self.onPlaybackStart(this, item, mediaSource);
}).on("pause.mediaplayerevent", function () {
Logger.log('audio element event: pause');
self.onPlaystateChange(this);
// In the event timeupdate isn't firing, at least we can update when this happens
self.setCurrentTime(self.getCurrentTicks());
}).on("playing.mediaplayerevent", function () {
Logger.log('audio element event: playing');
self.onPlaystateChange(this);
// In the event timeupdate isn't firing, at least we can update when this happens
self.setCurrentTime(self.getCurrentTicks());
}).on("timeupdate.mediaplayerevent", onTimeUpdate);
Events.on(mediaRenderer, "volumechange", onVolumeChange);
Events.on(mediaRenderer, "playing", onPlayingOnce);
Events.on(mediaRenderer, "pause", onPause);
Events.on(mediaRenderer, "playing", onPlaying);
Events.on(mediaRenderer, "timeupdate", onTimeUpdate);
self.currentMediaRenderer = mediaRenderer;
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
@ -1994,6 +2013,34 @@
});
}
function onVolumeChange() {
console.log('audio element event: pause');
self.onPlaystateChange(this);
// In the event timeupdate isn't firing, at least we can update when this happens
self.setCurrentTime(self.getCurrentTicks());
}
function onPause() {
console.log('audio element event: pause');
self.onPlaystateChange(this);
// In the event timeupdate isn't firing, at least we can update when this happens
self.setCurrentTime(self.getCurrentTicks());
}
function onPlaying() {
console.log('audio element event: playing');
self.onPlaystateChange(this);
// In the event timeupdate isn't firing, at least we can update when this happens
self.setCurrentTime(self.getCurrentTicks());
}
var getItemFields = "MediaSources,Chapters";
self.tryPair = function (target) {

View file

@ -72,7 +72,6 @@
page.querySelector('.listTopPaging').innerHTML = pagingHtml;
updateFilterControls(page);
var trigger = false;
if (view == "Thumb") {
html = LibraryBrowser.getPosterViewHtml({
@ -112,7 +111,6 @@
items: result.Items,
sortBy: query.SortBy
});
trigger = true;
}
else if (view == "Poster") {
html = LibraryBrowser.getPosterViewHtml({
@ -150,10 +148,6 @@
elem.innerHTML = html + pagingHtml;
ImageLoader.lazyChildren(elem);
if (trigger) {
Events.trigger(elem, 'create');
}
$('.btnNextPage', page).on('click', function () {
query.StartIndex += query.Limit;
reloadItems(page, viewPanel);

View file

@ -370,13 +370,13 @@
}
}
$(MediaController).on('playbackstop', onPlaybackStop);
Events.on(MediaController, 'playbackstop', onPlaybackStop);
});
pageIdOn('pagebeforehide', "moviesPage", function () {
var page = this;
$(MediaController).off('playbackstop', onPlaybackStop);
Events.off(MediaController, 'playbackstop', onPlaybackStop);
});
function onPlaybackStop(e, state) {

View file

@ -66,7 +66,6 @@
items: result.Items,
shape: "backdrop",
preferThumb: true,
context: 'music',
showItemCounts: true,
lazy: true,
centerText: true,
@ -79,13 +78,21 @@
items: result.Items,
shape: "backdrop",
preferThumb: true,
context: 'music',
showItemCounts: true,
cardLayout: true,
lazy: true,
showTitle: true
});
}
else if (view == "Poster") {
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "portrait",
centerText: true,
showItemCounts: true,
lazy: true
});
}
var elem = page.querySelector('#items');
elem.innerHTML = html;

View file

@ -11,7 +11,7 @@
ApiClient.getUser(userId).then(function (user) {
$('.username', page).html(user.Name);
Events.trigger($('#uploadUserImage', page).val('')[0], 'change');
$('#uploadUserImage', page).val('').trigger('change');
Dashboard.setPageTitle(user.Name);

View file

@ -177,14 +177,15 @@
}
function initializeApiClient(apiClient) {
$(apiClient).off("websocketmessage", onWebSocketMessage).on("websocketmessage", onWebSocketMessage);
Events.off(apiClient, "websocketmessage", onWebSocketMessage);
Events.on(apiClient, "websocketmessage", onWebSocketMessage);
}
if (window.ApiClient) {
initializeApiClient(window.ApiClient);
}
$(ConnectionManager).on('apiclientcreated', function (e, apiClient) {
Events.on(ConnectionManager, 'apiclientcreated', function (e, apiClient) {
initializeApiClient(apiClient);
});

View file

@ -79,7 +79,6 @@
}
return height + 'px';
return '80px';
}
function slideDown(elem) {
@ -97,8 +96,6 @@
return;
}
onfinish();
return;
requestAnimationFrame(function () {
var keyframes = [
{ height: getHeight(elem), offset: 0 },
@ -119,7 +116,6 @@
if (!browserInfo.animate || browserInfo.mobile) {
return;
}
return;
requestAnimationFrame(function () {
@ -541,7 +537,7 @@
function onPlaybackStart(e, state) {
Logger.log('nowplaying event: ' + e.type);
console.log('nowplaying event: ' + e.type);
var player = this;
@ -569,7 +565,7 @@
function onPlaybackStopped(e, state) {
Logger.log('nowplaying event: ' + e.type);
console.log('nowplaying event: ' + e.type);
var player = this;
player.endPlayerUpdates();
@ -579,7 +575,7 @@
function onStateChanged(e, state) {
//Logger.log('nowplaying event: ' + e.type);
//console.log('nowplaying event: ' + e.type);
var player = this;
if (player.isDefaultPlayer && state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') {
@ -593,11 +589,11 @@
if (currentPlayer) {
$(currentPlayer).off('playbackstart', onPlaybackStart)
.off('playbackstop', onPlaybackStopped)
.off('volumechange', onVolumeChanged)
.off('playstatechange', onStateChanged)
.off('positionchange', onStateChanged);
Events.off(currentPlayer, 'playbackstart', onPlaybackStart);
Events.off(currentPlayer, 'playbackstop', onPlaybackStopped);
Events.off(currentPlayer, 'volumechange', onVolumeChanged);
Events.off(currentPlayer, 'playstatechange', onStateChanged);
Events.off(currentPlayer, 'positionchange', onStateChanged);
currentPlayer.endPlayerUpdates();
currentPlayer = null;
@ -637,11 +633,11 @@
onStateChanged.call(player, { type: 'init' }, state);
});
$(player).on('playbackstart', onPlaybackStart)
.on('playbackstop', onPlaybackStopped)
.on('volumechange', onVolumeChanged)
.on('playstatechange', onStateChanged)
.on('positionchange', onStateChanged);
Events.on(player, 'playbackstart', onPlaybackStart);
Events.on(player, 'playbackstop', onPlaybackStopped);
Events.on(player, 'volumechange', onVolumeChanged);
Events.on(player, 'playstatechange', onStateChanged);
Events.on(player, 'positionchange', onStateChanged);
}
Events.on(MediaController, 'playerchange', function () {

View file

@ -605,8 +605,8 @@
// This should be outside of the IF
// But for now, if you change songs but keep the same artist, the backdrop will flicker because in-between songs it clears out the image
if (!browserInfo.safari) {
// Exclude from safari because it just doesn't perform well
if (!browserInfo.mobile) {
// Exclude from mobile because it just doesn't perform well
Backdrops.setBackdropUrl(page, backdropUrl);
}
@ -637,11 +637,11 @@
if (currentPlayer) {
$(currentPlayer).off('playbackstart', onPlaybackStart)
.off('playbackstop', onPlaybackStopped)
.off('volumechange', onStateChanged)
.off('playstatechange', onStateChanged)
.off('positionchange', onStateChanged);
Events.off(currentPlayer, 'playbackstart', onPlaybackStart);
Events.off(currentPlayer, 'playbackstop', onPlaybackStopped);
Events.off(currentPlayer, 'volumechange', onStateChanged);
Events.off(currentPlayer, 'playstatechange', onStateChanged);
Events.off(currentPlayer, 'positionchange', onStateChanged);
currentPlayer.endPlayerUpdates();
currentPlayer = null;
@ -663,11 +663,11 @@
onStateChanged.call(player, { type: 'init' }, state);
});
$(player).on('playbackstart', onPlaybackStart)
.on('playbackstop', onPlaybackStopped)
.on('volumechange', onStateChanged)
.on('playstatechange', onStateChanged)
.on('positionchange', onStateChanged);
Events.on(player, 'playbackstart', onPlaybackStart);
Events.on(player, 'playbackstop', onPlaybackStopped);
Events.on(player, 'volumechange', onStateChanged);
Events.on(player, 'playstatechange', onStateChanged);
Events.on(player, 'positionchange', onStateChanged);
var playerInfo = MediaController.getPlayerInfo();
@ -820,7 +820,7 @@
}
});
$(MediaController).on('playerchange', function () {
Events.on(MediaController, 'playerchange', function () {
updateCastIcon(page);
});
@ -832,7 +832,7 @@
currentImgUrl = null;
$(MediaController).on('playerchange', onPlayerChange);
Events.on(MediaController, 'playerchange', onPlayerChange);
bindToPlayer(page, MediaController.getCurrentPlayer());
@ -861,7 +861,7 @@
releaseCurrentPlayer();
$(MediaController).off('playerchange', onPlayerChange);
Events.off(MediaController, 'playerchange', onPlayerChange);
lastPlayerState = null;
$(document.body).removeClass('hiddenViewMenuBar').removeClass('hiddenNowPlayingBar');

View file

@ -74,7 +74,7 @@
};
options.callback(review);
} else Logger.log("No callback function provided");
} else console.log("No callback function provided");
return false;
});
@ -98,7 +98,7 @@
id: id,
rating: rating,
callback: function (review) {
Logger.log(review);
console.log(review);
dialog.close();
ApiClient.createPackageReview(review).then(function () {

Some files were not shown because too many files have changed in this diff Show more