diff --git a/dashboard-ui/apiclient/localassetmanager.js b/dashboard-ui/apiclient/localassetmanager.js index de0641c045..e4ce74d2a2 100644 --- a/dashboard-ui/apiclient/localassetmanager.js +++ b/dashboard-ui/apiclient/localassetmanager.js @@ -95,6 +95,13 @@ return deferred.promise(); } + function fileExists(path) { + + var deferred = DeferredBuilder.Deferred(); + deferred.resolveWith(null, [false]); + return deferred.promise(); + } + window.LocalAssetManager = { getLocalMediaSource: getLocalMediaSource, saveOfflineUser: saveOfflineUser, @@ -110,7 +117,8 @@ downloadFile: downloadFile, downloadSubtitles: downloadSubtitles, hasImage: hasImage, - downloadImage: downloadImage + downloadImage: downloadImage, + fileExists: fileExists }; })(); \ No newline at end of file diff --git a/dashboard-ui/cordova/android/filesystem.js b/dashboard-ui/cordova/android/filesystem.js deleted file mode 100644 index d054e2335c..0000000000 --- a/dashboard-ui/cordova/android/filesystem.js +++ /dev/null @@ -1,14 +0,0 @@ -(function () { - - window.FileSystemBridge = { - - fileExists: function (path) { - return NativeFileSystem.fileExists(path); - }, - - translateFilePath: function (path) { - return 'file://' + NativeFileSystem.translateFilePath(path); - } - }; - -})(); \ No newline at end of file diff --git a/dashboard-ui/cordova/filesystem.js b/dashboard-ui/cordova/filesystem.js deleted file mode 100644 index 24a54e2bc3..0000000000 --- a/dashboard-ui/cordova/filesystem.js +++ /dev/null @@ -1,14 +0,0 @@ -(function () { - - window.FileSystemBridge = { - - fileExists: function (path) { - return false; - }, - - translateFilePath: function (path) { - return 'file://' + path; - } - }; - -})(); \ No newline at end of file diff --git a/dashboard-ui/cordova/localassetmanager.js b/dashboard-ui/cordova/localassetmanager.js index 635d0d2aa8..1a78ed49e9 100644 --- a/dashboard-ui/cordova/localassetmanager.js +++ b/dashboard-ui/cordova/localassetmanager.js @@ -19,9 +19,9 @@ getLocalItem(itemId, serverId).done(function (localItem) { - if (localItem && localItem.MediaSources.length) { + if (localItem && localItem.Item.MediaSources.length) { - var mediaSource = localItem.MediaSources[0]; + var mediaSource = localItem.Item.MediaSources[0]; fileExists(mediaSource.Path).done(function (exists) { @@ -156,11 +156,11 @@ db.transaction(function (tx) { - tx.executeSql("SELECT json from offlineactions where ServerId=?", [serverId], function (tx, res) { + tx.executeSql("SELECT Json from offlineactions where ServerId=?", [serverId], function (tx, res) { var actions = []; for (var i = 0, length = res.rows.length; i < length; i++) { - actions.push(JSON.parse(res.rows.item(i).json)); + actions.push(JSON.parse(res.rows.item(i).Json)); } deferred.resolveWith(null, [actions]); @@ -260,7 +260,7 @@ var localItem = JSON.parse(res.rows.item(0).Json); - deferred.resolveWith(null, [item]); + deferred.resolveWith(null, [localItem]); } else { deferred.resolveWith(null, [null]); @@ -350,7 +350,7 @@ var deferred = DeferredBuilder.Deferred(); Logger.log('Deleting ' + path); - resolveLocalFileSystemURL(path, function (fileEntry) { + resolveFile(path, function (fileEntry) { fileEntry.remove(function () { Logger.log('Deleted ' + path); @@ -370,6 +370,14 @@ return deferred.promise(); } + function resolveFile(path, success, fail) { + + getFileSystem().done(function (fileSystem) { + + fileSystem.root.getFile(path, { create: false }, success, fail); + }); + } + function createLocalItem(libraryItem, serverInfo, originalFileName) { var path = getDirectoryPath(libraryItem, serverInfo); @@ -379,25 +387,22 @@ var deferred = DeferredBuilder.Deferred(); - getFileSystem().done(function (fileSystem) { + var localPath = path.join('/'); - var localPath = fileSystem.root.toURL() + "/" + path.join('/'); + item.LocalPath = localPath; - item.LocalPath = localPath; + for (var i = 0, length = libraryItem.MediaSources.length; i < length; i++) { - for (var i = 0, length = libraryItem.MediaSources.length; i < length; i++) { + var mediaSource = libraryItem.MediaSources[i]; + mediaSource.Path = localPath; + mediaSource.Protocol = 'File'; + } - var mediaSource = libraryItem.MediaSources[i]; - mediaSource.Path = localPath; - mediaSource.Protocol = 'File'; - } - - item.ServerId = serverInfo.Id; - item.Item = libraryItem; - item.ItemId = libraryItem.Id; - item.Id = getLocalId(item.ServerId, item.ItemId); - deferred.resolveWith(null, [item]); - }); + item.ServerId = serverInfo.Id; + item.Item = libraryItem; + item.ItemId = libraryItem.Id; + item.Id = getLocalId(item.ServerId, item.ItemId); + deferred.resolveWith(null, [item]); return deferred.promise(); } @@ -405,7 +410,6 @@ function getDirectoryPath(item, server) { var parts = []; - parts.push("emby"); parts.push("sync"); parts.push(server.Name); @@ -463,33 +467,33 @@ getFileSystem().done(function (fileSystem) { - var targetFile = localPath; + fileSystem.root.getFile(fileName, { create: true }, function (targetFile) { - var downloader = new BackgroundTransfer.BackgroundDownloader(); - // Create a new download operation. - var download = downloader.createDownload(url, targetFile); - // Start the download and persist the promise to be able to cancel the download. - var downloadPromise = download.startAsync().then(function () { + var downloader = new BackgroundTransfer.BackgroundDownloader(); + // Create a new download operation. + var download = downloader.createDownload(url, targetFile.toURL()); + // Start the download and persist the promise to be able to cancel the download. + var downloadPromise = download.startAsync().then(function () { - // on success - var localUrl = localPath; + // on success + var localUrl = localPath; - Logger.log('Downloaded local url: ' + localUrl); - deferred.resolveWith(null, [localUrl]); + Logger.log('Downloaded local url: ' + localUrl); + deferred.resolveWith(null, [localUrl]); - }, function () { + }, function () { - // on error - Logger.log('download failed: ' + url + ' to ' + localPath); - deferred.reject(); + // on error + Logger.log('download failed: ' + url + ' to ' + localPath); + deferred.reject(); - }, function (value) { + }, function (value) { - // on progress - Logger.log('download progress: ' + value); + // on progress + Logger.log('download progress: ' + value); + }); }); - }); return deferred.promise(); @@ -589,11 +593,9 @@ function getImageLocalPath(serverId, itemId, imageTag) { var deferred = DeferredBuilder.Deferred(); - getFileSystem().done(function (fileSystem) { - var path = fileSystem.root.toURL() + "/emby/images/" + serverId + "/" + itemId + "/" + imageTag; + var path = "images/" + serverId + "-" + itemId + "/" + imageTag; - deferred.resolveWith(null, [path]); - }); + deferred.resolveWith(null, [path]); return deferred.promise(); } @@ -602,12 +604,12 @@ var deferred = DeferredBuilder.Deferred(); - resolveLocalFileSystemURL(path, function (fileEntry) { - + resolveFile(path, function (fileEntry) { + Logger.log('fileExists: true - path: ' + path); deferred.resolveWith(null, [true]); }, function () { - + Logger.log('fileExists: false - path: ' + path); deferred.resolveWith(null, [false]); }); @@ -653,7 +655,8 @@ downloadFile: downloadFile, downloadSubtitles: downloadSubtitles, hasImage: hasImage, - downloadImage: downloadImage + downloadImage: downloadImage, + fileExists: fileExists }; })(); \ No newline at end of file diff --git a/dashboard-ui/css/librarymenu.css b/dashboard-ui/css/librarymenu.css index a166c0d177..fd7047d0a6 100644 --- a/dashboard-ui/css/librarymenu.css +++ b/dashboard-ui/css/librarymenu.css @@ -207,7 +207,7 @@ } .viewMenuBar.semiTransparent { - background-color: rgba(18, 18, 18, .70); + background-color: rgba(18, 18, 18, .65); } .paperLibraryViewNav { diff --git a/dashboard-ui/scripts/externalplayer.js b/dashboard-ui/scripts/externalplayer.js index 98e6ade85e..67a30152e2 100644 --- a/dashboard-ui/scripts/externalplayer.js +++ b/dashboard-ui/scripts/externalplayer.js @@ -104,40 +104,6 @@ return profile; } - function validatePlaybackInfoResult(result) { - - if (result.ErrorCode) { - - MediaController.showPlaybackInfoErrorMessage(result.ErrorCode); - return false; - } - - return true; - } - - function getOptimalMediaSource(mediaType, versions) { - - var optimalVersion = versions.filter(function (v) { - - v.enableDirectPlay = MediaController.supportsDirectPlay(v); - - return v.enableDirectPlay; - - })[0]; - - if (!optimalVersion) { - optimalVersion = versions.filter(function (v) { - - return v.SupportsDirectStream; - - })[0]; - } - - return optimalVersion || versions.filter(function (s) { - return s.SupportsTranscoding; - })[0]; - } - var currentMediaSource; var currentItem; var basePlayerState; @@ -146,37 +112,13 @@ function getVideoStreamInfo(item) { var deferred = $.Deferred(); - Dashboard.showModalLoadingMsg(); var deviceProfile = getDeviceProfile(); var startPosition = 0; - MediaController.getPlaybackInfo(item.Id, deviceProfile, startPosition).done(function (playbackInfoResult) { - - if (validatePlaybackInfoResult(playbackInfoResult)) { - - var mediaSource = getOptimalMediaSource(item.MediaType, playbackInfoResult.MediaSources); - - if (mediaSource) { - - if (mediaSource.RequiresOpening) { - - MediaController.getLiveStream(item.Id, playbackInfoResult.PlaySessionId, deviceProfile, startPosition, mediaSource, null, null).done(function (openLiveStreamResult) { - - openLiveStreamResult.MediaSource.enableDirectPlay = MediaController.supportsDirectPlay(openLiveStreamResult.MediaSource); - - playInternalPostMediaSourceSelection(item, openLiveStreamResult.MediaSource, startPosition, deferred); - }); - - } else { - playInternalPostMediaSourceSelection(item, mediaSource, startPosition, deferred); - } - } else { - Dashboard.hideModalLoadingMsg(); - MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream'); - } - } + MediaPlayer.tryStartPlayback(deviceProfile, item, startPosition, function (mediaSource) { + playInternalPostMediaSourceSelection(item, mediaSource, startPosition, deferred); }); return deferred.promise(); diff --git a/dashboard-ui/scripts/mediacontroller.js b/dashboard-ui/scripts/mediacontroller.js index 8f5574fab4..a1501fb7cf 100644 --- a/dashboard-ui/scripts/mediacontroller.js +++ b/dashboard-ui/scripts/mediacontroller.js @@ -852,27 +852,36 @@ self.supportsDirectPlay = function (mediaSource) { + var deferred = $.Deferred(); if (mediaSource.SupportsDirectPlay) { if (mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) { // If this is the only way it can be played, then allow it if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) { - return true; + deferred.resolveWith(null, [true]); + } + else { + var val = mediaSource.Path.toLowerCase().replace('https:', 'http').indexOf(ApiClient.serverAddress().toLowerCase().replace('https:', 'http').substring(0, 14)) == 0; + deferred.resolveWith(null, [val]); } - - return mediaSource.Path.toLowerCase().replace('https:', 'http').indexOf(ApiClient.serverAddress().toLowerCase().replace('https:', 'http').substring(0, 14)) == 0; } if (mediaSource.Protocol == 'File') { - var exists = FileSystemBridge.fileExists(mediaSource.Path); - Logger.log('FileSystemBridge.fileExists: path: ' + mediaSource.Path + ' result: ' + exists); - return exists; + require(['localassetmanager'], function () { + + LocalAssetManager.fileExists(mediaSource.Path).done(function (exists) { + Logger.log('LocalAssetManager.fileExists: path: ' + mediaSource.Path + ' result: ' + exists); + deferred.resolveWith(null, [exists]); + }); + }); } } - - return false; + else { + deferred.resolveWith(null, [false]); + } + return deferred.promise(); }; self.showPlayerSelection = showPlayerSelection; diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js index 48d24d70fe..90530b01f2 100644 --- a/dashboard-ui/scripts/mediaplayer.js +++ b/dashboard-ui/scripts/mediaplayer.js @@ -878,25 +878,39 @@ function getOptimalMediaSource(mediaType, versions) { - var optimalVersion = versions.filter(function (v) { + var deferred = $.Deferred(); - v.enableDirectPlay = MediaController.supportsDirectPlay(v); + var promises = versions.map(function (v) { + return MediaController.supportsDirectPlay(v); + }); - return v.enableDirectPlay; + $.when.apply($, promises).done(function () { - })[0]; + for (var i = 0, length = versions.length; i < length; i++) { + versions[i].enableDirectPlay = arguments[i] || false; + } + var optimalVersion = versions.filter(function (v) { - if (!optimalVersion) { - optimalVersion = versions.filter(function (v) { - - return v.SupportsDirectStream; + return v.enableDirectPlay; })[0]; - } - return optimalVersion || versions.filter(function (s) { - return s.SupportsTranscoding; - })[0]; + if (!optimalVersion) { + optimalVersion = versions.filter(function (v) { + + return v.SupportsDirectStream; + + })[0]; + } + + optimalVersion = optimalVersion || versions.filter(function (s) { + return s.SupportsTranscoding; + })[0]; + + deferred.resolveWith(null, [optimalVersion]); + }); + + return deferred.promise(); } self.createStreamInfo = function (type, item, mediaSource, startPosition) { @@ -916,10 +930,6 @@ if (mediaSource.enableDirectPlay) { mediaUrl = mediaSource.Path; - if (mediaSource.Protocol == 'File') { - mediaUrl = FileSystemBridge.translateFilePath(mediaUrl); - } - playMethod = 'DirectPlay'; } else { @@ -965,9 +975,6 @@ mediaUrl = mediaSource.Path; - if (mediaSource.Protocol == 'File') { - mediaUrl = FileSystemBridge.translateFilePath(mediaUrl); - } playMethod = 'DirectPlay'; } else { @@ -1063,7 +1070,7 @@ } }; - function playOnDeviceProfileCreated(deviceProfile, item, startPosition, callback) { + self.tryStartPlayback = function (deviceProfile, item, startPosition, callback) { if (item.MediaType === "Video") { @@ -1074,28 +1081,39 @@ if (validatePlaybackInfoResult(playbackInfoResult)) { - var mediaSource = getOptimalMediaSource(item.MediaType, playbackInfoResult.MediaSources); + getOptimalMediaSource(item.MediaType, playbackInfoResult.MediaSources).done(function (mediaSource) { + if (mediaSource) { - if (mediaSource) { + if (mediaSource.RequiresOpening) { - if (mediaSource.RequiresOpening) { + MediaController.getLiveStream(item.Id, playbackInfoResult.PlaySessionId, deviceProfile, startPosition, mediaSource, null, null).done(function (openLiveStreamResult) { - MediaController.getLiveStream(item.Id, playbackInfoResult.PlaySessionId, deviceProfile, startPosition, mediaSource, null, null).done(function (openLiveStreamResult) { + MediaController.supportsDirectPlay(openLiveStreamResult.MediaSource).done(function (result) { - openLiveStreamResult.MediaSource.enableDirectPlay = MediaController.supportsDirectPlay(openLiveStreamResult.MediaSource); + openLiveStreamResult.MediaSource.enableDirectPlay = result; + callback(openLiveStreamResult.MediaSource); + }); - playInternalPostMediaSourceSelection(item, openLiveStreamResult.MediaSource, startPosition, callback); - }); + }); + } else { + callback(mediaSource); + } } else { - playInternalPostMediaSourceSelection(item, mediaSource, startPosition, callback); + Dashboard.hideModalLoadingMsg(); + MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream'); } - } else { - Dashboard.hideModalLoadingMsg(); - MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream'); - } + }); } }); + }; + + function playOnDeviceProfileCreated(deviceProfile, item, startPosition, callback) { + + self.tryStartPlayback(deviceProfile, item, startPosition, function (mediaSource) { + + playInternalPostMediaSourceSelection(item, mediaSource, startPosition, callback); + }); } function playInternalPostMediaSourceSelection(item, mediaSource, startPosition, callback) { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 62ff889fe9..24140827a9 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1027,7 +1027,7 @@ var Dashboard = { name: Globalize.translate('TabSync'), href: "syncactivity.html", selected: page.classList.contains('syncConfigurationPage') || (isServicesPage && context == 'sync'), - icon: 'refresh' + icon: 'sync' }, { divider: true, name: Globalize.translate('TabExtras') @@ -1965,8 +1965,6 @@ var AppInfo = {}; return false; }); - require(['filesystem']); - if (Dashboard.isRunningInCordova()) { require(['cordova/connectsdk', 'scripts/registrationservices', 'cordova/back']); @@ -2027,16 +2025,6 @@ var AppInfo = {}; define("localassetmanager", ["apiclient/localassetmanager"]); } - if (Dashboard.isRunningInCordova() && $.browser.android) { - define("filesystem", ["cordova/android/filesystem"]); - } - else if (Dashboard.isRunningInCordova()) { - define("filesystem", ["cordova/filesystem"]); - } - else { - define("filesystem", ["thirdparty/filesystem"]); - } - if (Dashboard.isRunningInCordova() && $.browser.android) { define("nativedirectorychooser", ["cordova/android/nativedirectorychooser"]); } diff --git a/dashboard-ui/scripts/syncactivity.js b/dashboard-ui/scripts/syncactivity.js index dce8492bc7..5e1505d2a7 100644 --- a/dashboard-ui/scripts/syncactivity.js +++ b/dashboard-ui/scripts/syncactivity.js @@ -282,7 +282,7 @@ if (hasLocalSync()) { var targetId = ApiClient.deviceId(); data = data.filter(function (j) { - return TargetId = targetId; + return j.TargetId == targetId; }); } loadData(page, data); diff --git a/dashboard-ui/themes/android.css b/dashboard-ui/themes/android.css index 4f3399aff2..dab59d7365 100644 --- a/dashboard-ui/themes/android.css +++ b/dashboard-ui/themes/android.css @@ -3,7 +3,7 @@ } .viewMenuBar.semiTransparent { - background-color: rgba(27, 27, 27, .70); + background-color: rgba(27, 27, 27, .65); } .background-theme-b { diff --git a/dashboard-ui/thirdparty/filesystem.js b/dashboard-ui/thirdparty/filesystem.js deleted file mode 100644 index 9f210106e9..0000000000 --- a/dashboard-ui/thirdparty/filesystem.js +++ /dev/null @@ -1,13 +0,0 @@ -(function () { - - window.FileSystemBridge = { - - fileExists: function (path) { - return false; - }, - - translateFilePath: function (path) { - return 'file://' + path; - } - }; -})(); \ No newline at end of file