From 3a6cc1b003d70699da8f5110aa45af26d5010288 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 29 Dec 2015 11:12:47 -0500 Subject: [PATCH 1/6] add download button to context menu --- dashboard-ui/scripts/librarylist.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 231db5dd16..4159bfa7ed 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -260,6 +260,16 @@ }); } + if (user.Policy.EnableContentDownloading) { + if (mediaType) { + items.push({ + name: Globalize.translate('ButtonDownload'), + id: 'download', + ironIcon: 'file-download' + }); + } + } + if (commands.indexOf('delete') != -1) { items.push({ name: Globalize.translate('ButtonDelete'), From 0c9e8c99e8ffbdc10d524f199791c8ff31791a5d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 29 Dec 2015 11:13:31 -0500 Subject: [PATCH 2/6] adjust video audio channels for safari --- dashboard-ui/scripts/mediaplayer.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js index a554a616c7..234073a530 100644 --- a/dashboard-ui/scripts/mediaplayer.js +++ b/dashboard-ui/scripts/mediaplayer.js @@ -316,6 +316,8 @@ } else { + var videoAudioChannels = browserInfo.safari ? '2' : '6'; + profile.CodecProfiles.push({ Type: 'VideoAudio', Codec: 'aac', @@ -335,7 +337,7 @@ { Condition: 'LessThanEqual', Property: 'AudioChannels', - Value: '6' + Value: videoAudioChannels } // Disabling this is going to require us to learn why it was disabled in the first place //, @@ -359,7 +361,7 @@ { Condition: 'LessThanEqual', Property: 'AudioChannels', - Value: '6' + Value: videoAudioChannels } ] }); From 78caa79e1eda6c879a7529647c6c38ded186da01 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 29 Dec 2015 11:22:30 -0500 Subject: [PATCH 3/6] update channels --- dashboard-ui/mypreferenceshome.html | 6 ------ dashboard-ui/scripts/mypreferenceshome.js | 3 --- 2 files changed, 9 deletions(-) diff --git a/dashboard-ui/mypreferenceshome.html b/dashboard-ui/mypreferenceshome.html index 4dd34ad13a..735a111c16 100644 --- a/dashboard-ui/mypreferenceshome.html +++ b/dashboard-ui/mypreferenceshome.html @@ -88,12 +88,6 @@
${LabelSelectFolderGroupsHelp}
- -
-
- ${OptionDisplayChannelsInline} -
${OptionDisplayChannelsInlineHelp}
-

diff --git a/dashboard-ui/scripts/mypreferenceshome.js b/dashboard-ui/scripts/mypreferenceshome.js index b2528efad2..e0e7eed34f 100644 --- a/dashboard-ui/scripts/mypreferenceshome.js +++ b/dashboard-ui/scripts/mypreferenceshome.js @@ -129,7 +129,6 @@ page.querySelector('.chkDisplayCollectionView').checked = user.Configuration.DisplayCollectionsView || false; page.querySelector('.chkHidePlayedFromLatest').checked = user.Configuration.HidePlayedInLatest || false; - page.querySelector('.chkDisplayChannelsInline').checked = user.Configuration.DisplayChannelsInline || false; $('#selectHomeSection1', page).val(displayPreferences.CustomPrefs.home0 || ''); $('#selectHomeSection2', page).val(displayPreferences.CustomPrefs.home1 || ''); @@ -159,8 +158,6 @@ user.Configuration.DisplayCollectionsView = page.querySelector('.chkDisplayCollectionView').checked; user.Configuration.HidePlayedInLatest = page.querySelector('.chkHidePlayedFromLatest').checked; - user.Configuration.DisplayChannelsInline = page.querySelector('.chkDisplayChannelsInline').checked; - user.Configuration.LatestItemsExcludes = $(".chkIncludeInLatest", page).get().filter(function (i) { return !i.checked; From 5ca18644c63461c0551b1b696959c3aba2734c98 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 29 Dec 2015 12:10:21 -0500 Subject: [PATCH 4/6] use shared components for quality options --- .../emby-webcomponents/.bower.json | 8 +- .../browserdeviceprofile.js | 26 +- .../emby-webcomponents/qualityoptions.js | 81 ++ .../iron-behaviors/.bower.json | 6 +- .../iron-selector/.bower.json | 4 +- dashboard-ui/scripts/mediaplayer-video.js | 53 +- dashboard-ui/scripts/mediaplayer.js | 881 ++++++++---------- .../scripts/mypreferenceslanguages.js | 27 +- dashboard-ui/scripts/site.js | 1 + 9 files changed, 565 insertions(+), 522 deletions(-) create mode 100644 dashboard-ui/bower_components/emby-webcomponents/qualityoptions.js diff --git a/dashboard-ui/bower_components/emby-webcomponents/.bower.json b/dashboard-ui/bower_components/emby-webcomponents/.bower.json index d62e0f8ed6..8200afb011 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/.bower.json +++ b/dashboard-ui/bower_components/emby-webcomponents/.bower.json @@ -15,12 +15,12 @@ }, "devDependencies": {}, "ignore": [], - "version": "1.0.2", - "_release": "1.0.2", + "version": "1.0.5", + "_release": "1.0.5", "_resolution": { "type": "version", - "tag": "1.0.2", - "commit": "a4909b1637879d7e52ce9eaba8247ad98b690de9" + "tag": "1.0.5", + "commit": "ff6d4ba01de70b907dfa51b36aee6c63f64685c9" }, "_source": "git://github.com/MediaBrowser/emby-webcomponents.git", "_target": "~1.0.0", diff --git a/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js b/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js index 17ab704e3d..92dcb9cda4 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js +++ b/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js @@ -225,6 +225,8 @@ }] }); + var videoAudioChannels = browser.safari ? '2' : '6'; + profile.CodecProfiles.push({ Type: 'VideoAudio', Codec: 'aac', @@ -234,6 +236,17 @@ Condition: 'NotEquals', Property: 'AudioProfile', Value: 'HE-AAC' + }, + { + Condition: 'LessThanEqual', + Property: 'AudioChannels', + Value: videoAudioChannels + }, + { + Condition: 'Equals', + Property: 'IsSecondaryAudio', + Value: 'false', + IsRequired: 'false' } // Disabling this is going to require us to learn why it was disabled in the first place //, @@ -252,7 +265,13 @@ { Condition: 'LessThanEqual', Property: 'AudioChannels', - Value: '6' + Value: videoAudioChannels + }, + { + Condition: 'Equals', + Property: 'IsSecondaryAudio', + Value: 'false', + IsRequired: 'false' } ] }); @@ -260,6 +279,11 @@ profile.CodecProfiles.push({ Type: 'VideoAudio', Conditions: [ + { + Condition: 'LessThanEqual', + Property: 'AudioChannels', + Value: videoAudioChannels + }, { Condition: 'Equals', Property: 'IsSecondaryAudio', diff --git a/dashboard-ui/bower_components/emby-webcomponents/qualityoptions.js b/dashboard-ui/bower_components/emby-webcomponents/qualityoptions.js new file mode 100644 index 0000000000..5b628053d7 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/qualityoptions.js @@ -0,0 +1,81 @@ +define([], function () { + + function getVideoQualityOptions(maxStreamingBitrate, videoWidth) { + + var maxAllowedWidth = videoWidth || 4096; + //var maxAllowedHeight = videoHeight || 2304; + + var options = []; + + // Some 1080- videos are reported as 1912? + if (maxAllowedWidth >= 1900) { + + options.push({ name: '1080p - 40Mbps', maxHeight: 1080, bitrate: 40000000 }); + options.push({ name: '1080p - 35Mbps', maxHeight: 1080, bitrate: 35000000 }); + options.push({ name: '1080p - 30Mbps', maxHeight: 1080, bitrate: 30000000 }); + options.push({ name: '1080p - 25Mbps', maxHeight: 1080, bitrate: 25000000 }); + options.push({ name: '1080p - 20Mbps', maxHeight: 1080, bitrate: 20000000 }); + options.push({ name: '1080p - 15Mbps', maxHeight: 1080, bitrate: 15000000 }); + options.push({ name: '1080p - 10Mbps', maxHeight: 1080, bitrate: 10000001 }); + options.push({ name: '1080p - 8Mbps', maxHeight: 1080, bitrate: 8000001 }); + options.push({ name: '1080p - 6Mbps', maxHeight: 1080, bitrate: 6000001 }); + options.push({ name: '1080p - 5Mbps', maxHeight: 1080, bitrate: 5000001 }); + options.push({ name: '1080p - 4Mbps', maxHeight: 1080, bitrate: 4000002 }); + + } else if (maxAllowedWidth >= 1260) { + options.push({ name: '720p - 10Mbps', maxHeight: 720, bitrate: 10000000 }); + options.push({ name: '720p - 8Mbps', maxHeight: 720, bitrate: 8000000 }); + options.push({ name: '720p - 6Mbps', maxHeight: 720, bitrate: 6000000 }); + options.push({ name: '720p - 5Mbps', maxHeight: 720, bitrate: 5000000 }); + + } else if (maxAllowedWidth >= 700) { + options.push({ name: '480p - 4Mbps', maxHeight: 480, bitrate: 4000001 }); + options.push({ name: '480p - 3Mbps', maxHeight: 480, bitrate: 3000001 }); + options.push({ name: '480p - 2.5Mbps', maxHeight: 480, bitrate: 2500000 }); + options.push({ name: '480p - 2Mbps', maxHeight: 480, bitrate: 2000001 }); + options.push({ name: '480p - 1.5Mbps', maxHeight: 480, bitrate: 1500001 }); + } + + if (maxAllowedWidth >= 1260) { + options.push({ name: '720p - 4Mbps', maxHeight: 720, bitrate: 4000000 }); + options.push({ name: '720p - 3Mbps', maxHeight: 720, bitrate: 3000000 }); + options.push({ name: '720p - 2Mbps', maxHeight: 720, bitrate: 2000000 }); + + // The extra 1 is because they're keyed off the bitrate value + options.push({ name: '720p - 1.5Mbps', maxHeight: 720, bitrate: 1500000 }); + options.push({ name: '720p - 1Mbps', maxHeight: 720, bitrate: 1000001 }); + } + + options.push({ name: '480p - 1.0Mbps', maxHeight: 480, bitrate: 1000000 }); + options.push({ name: '480p - 720kbps', maxHeight: 480, bitrate: 720000 }); + options.push({ name: '480p - 420kbps', maxHeight: 480, bitrate: 420000 }); + options.push({ name: '360p', maxHeight: 360, bitrate: 400000 }); + options.push({ name: '240p', maxHeight: 240, bitrate: 320000 }); + options.push({ name: '144p', maxHeight: 144, bitrate: 192000 }); + + if (maxStreamingBitrate) { + var selectedIndex = -1; + for (var i = 0, length = options.length; i < length; i++) { + + var option = options[i]; + + if (selectedIndex == -1 && option.bitrate <= maxStreamingBitrate) { + selectedIndex = i; + } + } + + if (selectedIndex == -1) { + + selectedIndex = options.length - 1; + } + + options[selectedIndex].selected = true; + } + + return options; + }; + + return { + getVideoQualityOptions: getVideoQualityOptions + }; +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/iron-behaviors/.bower.json b/dashboard-ui/bower_components/iron-behaviors/.bower.json index db08f2170c..17f68b3351 100644 --- a/dashboard-ui/bower_components/iron-behaviors/.bower.json +++ b/dashboard-ui/bower_components/iron-behaviors/.bower.json @@ -29,14 +29,14 @@ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" }, "ignore": [], - "homepage": "https://github.com/PolymerElements/iron-behaviors", + "homepage": "https://github.com/polymerelements/iron-behaviors", "_release": "1.0.12", "_resolution": { "type": "version", "tag": "v1.0.12", "commit": "657f526a2382a659cdf4e13be87ecc89261588a3" }, - "_source": "git://github.com/PolymerElements/iron-behaviors.git", + "_source": "git://github.com/polymerelements/iron-behaviors.git", "_target": "^1.0.0", - "_originalSource": "PolymerElements/iron-behaviors" + "_originalSource": "polymerelements/iron-behaviors" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/iron-selector/.bower.json b/dashboard-ui/bower_components/iron-selector/.bower.json index 52d44c1907..ebb18c5b7b 100644 --- a/dashboard-ui/bower_components/iron-selector/.bower.json +++ b/dashboard-ui/bower_components/iron-selector/.bower.json @@ -36,7 +36,7 @@ "tag": "v1.0.8", "commit": "e9a66727f3da0446f04956d4e4f1dcd51cdec2ff" }, - "_source": "git://github.com/PolymerElements/iron-selector.git", + "_source": "git://github.com/polymerelements/iron-selector.git", "_target": "^1.0.0", - "_originalSource": "PolymerElements/iron-selector" + "_originalSource": "polymerelements/iron-selector" } \ No newline at end of file diff --git a/dashboard-ui/scripts/mediaplayer-video.js b/dashboard-ui/scripts/mediaplayer-video.js index 435c64ae54..5077d4e93b 100644 --- a/dashboard-ui/scripts/mediaplayer-video.js +++ b/dashboard-ui/scripts/mediaplayer-video.js @@ -140,41 +140,40 @@ self.showQualityFlyout = function () { - var currentSrc = self.getCurrentSrc(self.currentMediaRenderer).toLowerCase(); - var isStatic = currentSrc.indexOf('static=true') != -1; + require(['qualityoptions', 'actionsheet'], function (qualityoptions) { - var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) { - return stream.Type == "Video"; - })[0]; - var videoWidth = videoStream ? videoStream.Width : null; - var videoHeight = videoStream ? videoStream.Height : null; + var currentSrc = self.getCurrentSrc(self.currentMediaRenderer).toLowerCase(); + var isStatic = currentSrc.indexOf('static=true') != -1; - var options = self.getVideoQualityOptions(videoWidth, videoHeight); + var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) { + return stream.Type == "Video"; + })[0]; + var videoWidth = videoStream ? videoStream.Width : null; - if (isStatic) { - options[0].name = "Direct"; - } + var options = qualityoptions.getVideoQualityOptions(AppSettings.maxStreamingBitrate(), videoWidth); - var menuItems = options.map(function (o) { - - var opt = { - name: o.name, - id: o.bitrate - }; - - if (o.selected) { - opt.ironIcon = "check"; + if (isStatic) { + options[0].name = "Direct"; } - return opt; - }); + var menuItems = options.map(function (o) { - var selectedId = options.filter(function (o) { - return o.selected; - }); - selectedId = selectedId.length ? selectedId[0].bitrate : null; - require(['actionsheet'], function () { + var opt = { + name: o.name, + id: o.bitrate + }; + if (o.selected) { + opt.ironIcon = "check"; + } + + return opt; + }); + + var selectedId = options.filter(function (o) { + return o.selected; + }); + selectedId = selectedId.length ? selectedId[0].bitrate : null; ActionSheetElement.show({ items: menuItems, positionTo: $('.videoQualityButton')[0], diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js index 234073a530..295ac35a1a 100644 --- a/dashboard-ui/scripts/mediaplayer.js +++ b/dashboard-ui/scripts/mediaplayer.js @@ -36,479 +36,410 @@ return targets; }; - self.getVideoQualityOptions = function (videoWidth, videoHeight) { - - var bitrateSetting = AppSettings.maxStreamingBitrate(); - - var maxAllowedWidth = videoWidth || 4096; - var maxAllowedHeight = videoHeight || 2304; - - var options = []; - - // Some 1080- videos are reported as 1912? - if (maxAllowedWidth >= 1900) { - - options.push({ name: '1080p - 40Mbps', maxHeight: 1080, bitrate: 40000000 }); - options.push({ name: '1080p - 35Mbps', maxHeight: 1080, bitrate: 35000000 }); - options.push({ name: '1080p - 30Mbps', maxHeight: 1080, bitrate: 30000000 }); - options.push({ name: '1080p - 25Mbps', maxHeight: 1080, bitrate: 25000000 }); - options.push({ name: '1080p - 20Mbps', maxHeight: 1080, bitrate: 20000000 }); - options.push({ name: '1080p - 15Mbps', maxHeight: 1080, bitrate: 15000000 }); - options.push({ name: '1080p - 10Mbps', maxHeight: 1080, bitrate: 10000001 }); - options.push({ name: '1080p - 8Mbps', maxHeight: 1080, bitrate: 8000001 }); - options.push({ name: '1080p - 6Mbps', maxHeight: 1080, bitrate: 6000001 }); - options.push({ name: '1080p - 5Mbps', maxHeight: 1080, bitrate: 5000001 }); - options.push({ name: '1080p - 4Mbps', maxHeight: 1080, bitrate: 4000002 }); - - } else if (maxAllowedWidth >= 1260) { - options.push({ name: '720p - 10Mbps', maxHeight: 720, bitrate: 10000000 }); - options.push({ name: '720p - 8Mbps', maxHeight: 720, bitrate: 8000000 }); - options.push({ name: '720p - 6Mbps', maxHeight: 720, bitrate: 6000000 }); - options.push({ name: '720p - 5Mbps', maxHeight: 720, bitrate: 5000000 }); - - } else if (maxAllowedWidth >= 700) { - options.push({ name: '480p - 4Mbps', maxHeight: 480, bitrate: 4000001 }); - options.push({ name: '480p - 3Mbps', maxHeight: 480, bitrate: 3000001 }); - options.push({ name: '480p - 2.5Mbps', maxHeight: 480, bitrate: 2500000 }); - options.push({ name: '480p - 2Mbps', maxHeight: 480, bitrate: 2000001 }); - options.push({ name: '480p - 1.5Mbps', maxHeight: 480, bitrate: 1500001 }); - } - - if (maxAllowedWidth >= 1260) { - options.push({ name: '720p - 4Mbps', maxHeight: 720, bitrate: 4000000 }); - options.push({ name: '720p - 3Mbps', maxHeight: 720, bitrate: 3000000 }); - options.push({ name: '720p - 2Mbps', maxHeight: 720, bitrate: 2000000 }); - - // The extra 1 is because they're keyed off the bitrate value - options.push({ name: '720p - 1.5Mbps', maxHeight: 720, bitrate: 1500000 }); - options.push({ name: '720p - 1Mbps', maxHeight: 720, bitrate: 1000001 }); - } - - options.push({ name: '480p - 1.0Mbps', maxHeight: 480, bitrate: 1000000 }); - options.push({ name: '480p - 720kbps', maxHeight: 480, bitrate: 720000 }); - options.push({ name: '480p - 420kbps', maxHeight: 480, bitrate: 420000 }); - options.push({ name: '360p', maxHeight: 360, bitrate: 400000 }); - options.push({ name: '240p', maxHeight: 240, bitrate: 320000 }); - options.push({ name: '144p', maxHeight: 144, bitrate: 192000 }); - - var i, length, option; - var selectedIndex = -1; - for (i = 0, length = options.length; i < length; i++) { - - option = options[i]; - - if (selectedIndex == -1 && option.bitrate <= bitrateSetting) { - selectedIndex = i; - } - } - - if (selectedIndex == -1) { - - selectedIndex = options.length - 1; - } - - options[selectedIndex].selected = true; - - return options; - }; - self.getDeviceProfile = function (maxHeight) { - if (!maxHeight) { - maxHeight = self.getVideoQualityOptions().filter(function (q) { - return q.selected; - })[0].maxHeight; - } + return new Promise(function (resolve, reject) { - var isVlc = AppInfo.isNativeApp && browserInfo.android; - var bitrateSetting = AppSettings.maxStreamingBitrate(); + require(['qualityoptions'], function (qualityoptions) { - var supportedFormats = getSupportedFormats(); + var bitrateSetting = AppSettings.maxStreamingBitrate(); - var canPlayWebm = supportedFormats.indexOf('webm') != -1; - var canPlayAc3 = supportedFormats.indexOf('ac3') != -1; - var canPlayAac = supportedFormats.indexOf('aac') != -1; - var canPlayMp3 = supportedFormats.indexOf('mp3') != -1; - var canPlayMkv = supportedFormats.indexOf('mkv') != -1; + if (!maxHeight) { + maxHeight = qualityoptions.getVideoQualityOptions(bitrateSetting).filter(function (q) { + return q.selected; + })[0].maxHeight; + } - var profile = {}; + var isVlc = AppInfo.isNativeApp && browserInfo.android; - profile.MaxStreamingBitrate = bitrateSetting; - profile.MaxStaticBitrate = 8000000; - profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000); + var supportedFormats = getSupportedFormats(); - profile.DirectPlayProfiles = []; + var canPlayWebm = supportedFormats.indexOf('webm') != -1; + var canPlayAc3 = supportedFormats.indexOf('ac3') != -1; + var canPlayAac = supportedFormats.indexOf('aac') != -1; + var canPlayMp3 = supportedFormats.indexOf('mp3') != -1; + var canPlayMkv = supportedFormats.indexOf('mkv') != -1; - if (supportedFormats.indexOf('h264') != -1) { - profile.DirectPlayProfiles.push({ - Container: 'mp4,m4v', - Type: 'Video', - VideoCodec: 'h264', - AudioCodec: 'aac' + (canPlayMp3 ? ',mp3' : '') + (canPlayAc3 ? ',ac3' : '') - }); - } + var profile = {}; - if (canPlayMkv) { - profile.DirectPlayProfiles.push({ - Container: 'mkv,mov', - Type: 'Video', - VideoCodec: 'h264', - AudioCodec: 'aac' + (canPlayMp3 ? ',mp3' : '') + (canPlayAc3 ? ',ac3' : '') - }); - } + profile.MaxStreamingBitrate = bitrateSetting; + profile.MaxStaticBitrate = 8000000; + profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000); - var directPlayVideoContainers = AppInfo.directPlayVideoContainers; + profile.DirectPlayProfiles = []; - if (directPlayVideoContainers && directPlayVideoContainers.length) { - profile.DirectPlayProfiles.push({ - Container: directPlayVideoContainers.join(','), - Type: 'Video' - }); - } + if (supportedFormats.indexOf('h264') != -1) { + profile.DirectPlayProfiles.push({ + Container: 'mp4,m4v', + Type: 'Video', + VideoCodec: 'h264', + AudioCodec: 'aac' + (canPlayMp3 ? ',mp3' : '') + (canPlayAc3 ? ',ac3' : '') + }); + } - ['opus', 'mp3', 'aac', 'webma'].forEach(function(audioFormat){ + if (canPlayMkv) { + profile.DirectPlayProfiles.push({ + Container: 'mkv,mov', + Type: 'Video', + VideoCodec: 'h264', + AudioCodec: 'aac' + (canPlayMp3 ? ',mp3' : '') + (canPlayAc3 ? ',ac3' : '') + }); + } - if (supportedFormats.indexOf(audioFormat) != -1) { - profile.DirectPlayProfiles.push({ - Container: audioFormat == 'webma' ? 'webma,webm' : audioFormat, - Type: 'Audio' - }); - } - }); + var directPlayVideoContainers = AppInfo.directPlayVideoContainers; - var directPlayAudioContainers = AppInfo.directPlayAudioContainers; + if (directPlayVideoContainers && directPlayVideoContainers.length) { + profile.DirectPlayProfiles.push({ + Container: directPlayVideoContainers.join(','), + Type: 'Video' + }); + } - if (directPlayAudioContainers && directPlayAudioContainers.length) { - profile.DirectPlayProfiles.push({ - Container: directPlayAudioContainers.join(','), - Type: 'Audio' - }); - } + ['opus', 'mp3', 'aac', 'webma'].forEach(function (audioFormat) { - if (canPlayWebm) { - profile.DirectPlayProfiles.push({ - Container: 'webm', - Type: 'Video' - }); - } + if (supportedFormats.indexOf(audioFormat) != -1) { + profile.DirectPlayProfiles.push({ + Container: audioFormat == 'webma' ? 'webma,webm' : audioFormat, + Type: 'Audio' + }); + } + }); - profile.TranscodingProfiles = []; + var directPlayAudioContainers = AppInfo.directPlayAudioContainers; - // Can't use mkv on mobile because we have to use the native player controls and they won't be able to seek it - if (canPlayMkv && !isVlc && !browserInfo.mobile) { - profile.TranscodingProfiles.push({ - Container: 'mkv', - Type: 'Video', - AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : '') + (canPlayMp3 ? ',mp3' : ''), - VideoCodec: 'h264', - Context: 'Streaming' - }); - } + if (directPlayAudioContainers && directPlayAudioContainers.length) { + profile.DirectPlayProfiles.push({ + Container: directPlayAudioContainers.join(','), + Type: 'Audio' + }); + } - if (self.canPlayHls()) { - profile.TranscodingProfiles.push({ - Container: 'ts', - Type: 'Video', - AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : ''), - VideoCodec: 'h264', - Context: 'Streaming', - Protocol: 'hls' - }); + if (canPlayWebm) { + profile.DirectPlayProfiles.push({ + Container: 'webm', + Type: 'Video' + }); + } + + profile.TranscodingProfiles = []; + + // Can't use mkv on mobile because we have to use the native player controls and they won't be able to seek it + if (canPlayMkv && !isVlc && !browserInfo.mobile) { + profile.TranscodingProfiles.push({ + Container: 'mkv', + Type: 'Video', + AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : '') + (canPlayMp3 ? ',mp3' : ''), + VideoCodec: 'h264', + Context: 'Streaming' + }); + } + + if (self.canPlayHls()) { + profile.TranscodingProfiles.push({ + Container: 'ts', + Type: 'Video', + AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : ''), + VideoCodec: 'h264', + Context: 'Streaming', + Protocol: 'hls' + }); + + if (canPlayAac && browserInfo.safari && !AppInfo.isNativeApp) { + profile.TranscodingProfiles.push({ + Container: 'ts', + Type: 'Audio', + AudioCodec: 'aac', + Context: 'Streaming', + Protocol: 'hls' + }); + } + } + + if (canPlayWebm) { + + profile.TranscodingProfiles.push({ + Container: 'webm', + Type: 'Video', + AudioCodec: 'vorbis', + VideoCodec: 'vpx', + Context: 'Streaming', + Protocol: 'http' + }); + } - if (canPlayAac && browserInfo.safari && !AppInfo.isNativeApp) { profile.TranscodingProfiles.push({ - Container: 'ts', - Type: 'Audio', + Container: 'mp4', + Type: 'Video', AudioCodec: 'aac', + VideoCodec: 'h264', Context: 'Streaming', - Protocol: 'hls' + Protocol: 'http' }); - } - } - if (canPlayWebm) { + profile.TranscodingProfiles.push({ + Container: 'mp4', + Type: 'Video', + AudioCodec: 'aac', + VideoCodec: 'h264', + Context: 'Static', + Protocol: 'http' + }); - profile.TranscodingProfiles.push({ - Container: 'webm', - Type: 'Video', - AudioCodec: 'vorbis', - VideoCodec: 'vpx', - Context: 'Streaming', - Protocol: 'http' - }); - } + ['opus', 'mp3', 'aac'].forEach(function (audioFormat) { - profile.TranscodingProfiles.push({ - Container: 'mp4', - Type: 'Video', - AudioCodec: 'aac', - VideoCodec: 'h264', - Context: 'Streaming', - Protocol: 'http' - }); + if (supportedFormats.indexOf(audioFormat) != -1) { + profile.TranscodingProfiles.push({ + Container: audioFormat, + Type: 'Audio', + AudioCodec: audioFormat, + Context: 'Streaming', + Protocol: 'http' + }); + profile.TranscodingProfiles.push({ + Container: audioFormat, + Type: 'Audio', + AudioCodec: audioFormat, + Context: 'Static', + Protocol: 'http' + }); + } + }); - profile.TranscodingProfiles.push({ - Container: 'mp4', - Type: 'Video', - AudioCodec: 'aac', - VideoCodec: 'h264', - Context: 'Static', - Protocol: 'http' - }); + profile.ContainerProfiles = []; - ['opus', 'mp3', 'aac'].forEach(function(audioFormat){ - - if (supportedFormats.indexOf(audioFormat) != -1) { - profile.TranscodingProfiles.push({ - Container: audioFormat, - Type: 'Audio', - AudioCodec: audioFormat, - Context: 'Streaming', - Protocol: 'http' - }); - profile.TranscodingProfiles.push({ - Container: audioFormat, - Type: 'Audio', - AudioCodec: audioFormat, - Context: 'Static', - Protocol: 'http' - }); - } - }); - - profile.ContainerProfiles = []; - - profile.CodecProfiles = []; - profile.CodecProfiles.push({ - Type: 'Audio', - Conditions: [{ - Condition: 'LessThanEqual', - Property: 'AudioChannels', - Value: '2' - }] - }); - - // These don't play very well - if (isVlc) { - profile.CodecProfiles.push({ - Type: 'VideoAudio', - Codec: 'dca', - Conditions: [ - { + profile.CodecProfiles = []; + profile.CodecProfiles.push({ + Type: 'Audio', + Conditions: [{ Condition: 'LessThanEqual', Property: 'AudioChannels', - Value: 6 + Value: '2' + }] + }); + + // These don't play very well + if (isVlc) { + profile.CodecProfiles.push({ + Type: 'VideoAudio', + Codec: 'dca', + Conditions: [ + { + Condition: 'LessThanEqual', + Property: 'AudioChannels', + Value: 6 + } + ] + }); + + profile.CodecProfiles.push({ + Type: 'VideoAudio', + Codec: 'aac,mp3', + Conditions: [ + { + Condition: 'LessThanEqual', + Property: 'AudioChannels', + Value: '6' + } + ] + }); + + } else { + + var videoAudioChannels = browserInfo.safari ? '2' : '6'; + + 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: videoAudioChannels + } + // 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: videoAudioChannels + } + ] + }); + + } + + if (isVlc) { + profile.CodecProfiles.push({ + Type: 'Video', + Codec: 'h264', + Conditions: [ + { + Condition: 'EqualsAny', + Property: 'VideoProfile', + Value: 'high|main|baseline|constrained baseline' + }, + { + Condition: 'LessThanEqual', + Property: 'VideoLevel', + Value: '41' + }] + }); + } else { + profile.CodecProfiles.push({ + Type: 'Video', + Codec: 'h264', + Conditions: [ + { + Condition: 'NotEquals', + Property: 'IsAnamorphic', + Value: 'true', + IsRequired: false + }, + { + Condition: 'EqualsAny', + Property: 'VideoProfile', + Value: 'high|main|baseline|constrained baseline' + }, + { + Condition: 'LessThanEqual', + Property: 'VideoLevel', + Value: '41' + }, + { + Condition: 'LessThanEqual', + Property: 'Height', + Value: maxHeight + }] + }); + } + + if (!isVlc) { + profile.CodecProfiles.push({ + Type: 'Video', + Codec: 'vpx', + Conditions: [ + { + Condition: 'NotEquals', + Property: 'IsAnamorphic', + Value: 'true', + IsRequired: false + }, + { + Condition: 'LessThanEqual', + Property: 'Height', + Value: maxHeight + }] + }); + } + + // Subtitle profiles + // External vtt or burn in + profile.SubtitleProfiles = []; + if (self.supportsTextTracks()) { + + if (isVlc) { + profile.SubtitleProfiles.push({ + Format: 'srt', + Method: 'External' + }); + profile.SubtitleProfiles.push({ + Format: 'srt', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'subrip', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'ass', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'ssa', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'pgs', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'pgssub', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'dvdsub', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'vtt', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'sub', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'idx', + Method: 'Embed' + }); + profile.SubtitleProfiles.push({ + Format: 'smi', + Method: 'Embed' + }); + } else { + profile.SubtitleProfiles.push({ + Format: 'vtt', + Method: 'External' + }); } - ] + } + + profile.ResponseProfiles = []; + + profile.ResponseProfiles.push({ + Type: 'Video', + Container: 'm4v', + MimeType: 'video/mp4' + }); + + profile.ResponseProfiles.push({ + Type: 'Video', + Container: 'mov', + MimeType: 'video/webm' + }); + + resolve(profile); }); - - profile.CodecProfiles.push({ - Type: 'VideoAudio', - Codec: 'aac,mp3', - Conditions: [ - { - Condition: 'LessThanEqual', - Property: 'AudioChannels', - Value: '6' - } - ] - }); - - } else { - - var videoAudioChannels = browserInfo.safari ? '2' : '6'; - - 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: videoAudioChannels - } - // 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: videoAudioChannels - } - ] - }); - - } - - if (isVlc) { - profile.CodecProfiles.push({ - Type: 'Video', - Codec: 'h264', - Conditions: [ - { - Condition: 'EqualsAny', - Property: 'VideoProfile', - Value: 'high|main|baseline|constrained baseline' - }, - { - Condition: 'LessThanEqual', - Property: 'VideoLevel', - Value: '41' - }] - }); - } else { - profile.CodecProfiles.push({ - Type: 'Video', - Codec: 'h264', - Conditions: [ - { - Condition: 'NotEquals', - Property: 'IsAnamorphic', - Value: 'true', - IsRequired: false - }, - { - Condition: 'EqualsAny', - Property: 'VideoProfile', - Value: 'high|main|baseline|constrained baseline' - }, - { - Condition: 'LessThanEqual', - Property: 'VideoLevel', - Value: '41' - }, - { - Condition: 'LessThanEqual', - Property: 'Height', - Value: maxHeight - }] - }); - } - - if (!isVlc) { - profile.CodecProfiles.push({ - Type: 'Video', - Codec: 'vpx', - Conditions: [ - { - Condition: 'NotEquals', - Property: 'IsAnamorphic', - Value: 'true', - IsRequired: false - }, - { - Condition: 'LessThanEqual', - Property: 'Height', - Value: maxHeight - }] - }); - } - - // Subtitle profiles - // External vtt or burn in - profile.SubtitleProfiles = []; - if (self.supportsTextTracks()) { - - if (isVlc) { - profile.SubtitleProfiles.push({ - Format: 'srt', - Method: 'External' - }); - profile.SubtitleProfiles.push({ - Format: 'srt', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'subrip', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'ass', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'ssa', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'pgs', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'pgssub', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'dvdsub', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'vtt', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'sub', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'idx', - Method: 'Embed' - }); - profile.SubtitleProfiles.push({ - Format: 'smi', - Method: 'Embed' - }); - } else { - profile.SubtitleProfiles.push({ - Format: 'vtt', - Method: 'External' - }); - } - } - - profile.ResponseProfiles = []; - - profile.ResponseProfiles.push({ - Type: 'Video', - Container: 'm4v', - MimeType: 'video/mp4' }); - - profile.ResponseProfiles.push({ - Type: 'Video', - Container: 'mov', - MimeType: 'video/webm' - }); - - return profile; }; var supportsTextTracks; @@ -633,36 +564,37 @@ var playSessionId = getParameterByName('PlaySessionId', currentSrc); var liveStreamId = getParameterByName('LiveStreamId', currentSrc); - var deviceProfile = self.getDeviceProfile(); - - var audioStreamIndex = params.AudioStreamIndex == null ? (getParameterByName('AudioStreamIndex', currentSrc) || null) : params.AudioStreamIndex; - if (typeof (audioStreamIndex) == 'string') { - audioStreamIndex = parseInt(audioStreamIndex); - } - - var subtitleStreamIndex = params.SubtitleStreamIndex == null ? (getParameterByName('SubtitleStreamIndex', currentSrc) || null) : params.SubtitleStreamIndex; - if (typeof (subtitleStreamIndex) == 'string') { - subtitleStreamIndex = parseInt(subtitleStreamIndex); - } - - MediaController.getPlaybackInfo(self.currentItem.Id, deviceProfile, ticks, self.currentMediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId).then(function (result) { - - if (validatePlaybackInfoResult(result)) { - - self.currentMediaSource = result.MediaSources[0]; - self.createStreamInfo(self.currentItem.MediaType, self.currentItem, self.currentMediaSource, ticks).then(function (streamInfo) { - - if (!streamInfo.url) { - MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream'); - self.stop(); - return; - } - - self.currentSubtitleStreamIndex = subtitleStreamIndex; - - changeStreamToUrl(mediaRenderer, playSessionId, streamInfo); - }); + self.getDeviceProfile().then(function (deviceProfile) { + + var audioStreamIndex = params.AudioStreamIndex == null ? (getParameterByName('AudioStreamIndex', currentSrc) || null) : params.AudioStreamIndex; + if (typeof (audioStreamIndex) == 'string') { + audioStreamIndex = parseInt(audioStreamIndex); } + + var subtitleStreamIndex = params.SubtitleStreamIndex == null ? (getParameterByName('SubtitleStreamIndex', currentSrc) || null) : params.SubtitleStreamIndex; + if (typeof (subtitleStreamIndex) == 'string') { + subtitleStreamIndex = parseInt(subtitleStreamIndex); + } + + MediaController.getPlaybackInfo(self.currentItem.Id, deviceProfile, ticks, self.currentMediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId).then(function (result) { + + if (validatePlaybackInfoResult(result)) { + + self.currentMediaSource = result.MediaSources[0]; + self.createStreamInfo(self.currentItem.MediaType, self.currentItem, self.currentMediaSource, ticks).then(function (streamInfo) { + + if (!streamInfo.url) { + MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream'); + self.stop(); + return; + } + + self.currentSubtitleStreamIndex = subtitleStreamIndex; + + changeStreamToUrl(mediaRenderer, playSessionId, streamInfo); + }); + } + }); }); }; @@ -1089,6 +1021,12 @@ return; } + var onBitrateDetected = function() { + self.getDeviceProfile().then(function(deviceProfile) { + playOnDeviceProfileCreated(deviceProfile, item, startPosition, callback); + }); + }; + var bitrateDetectionKey = ApiClient.serverAddress(); if (item.MediaType == 'Video' && AppSettings.enableAutomaticBitrateDetection() && (new Date().getTime() - (self.lastBitrateDetections[bitrateDetectionKey] || 0)) > 300000) { @@ -1100,15 +1038,12 @@ self.lastBitrateDetections[bitrateDetectionKey] = new Date().getTime(); AppSettings.maxStreamingBitrate(bitrate); - playOnDeviceProfileCreated(self.getDeviceProfile(), item, startPosition, callback); + onBitrateDetected(); - }, function () { - - playOnDeviceProfileCreated(self.getDeviceProfile(), item, startPosition, callback); - }); + }, onBitrateDetected); } else { - playOnDeviceProfileCreated(self.getDeviceProfile(), item, startPosition, callback); + onBitrateDetected(); } }; diff --git a/dashboard-ui/scripts/mypreferenceslanguages.js b/dashboard-ui/scripts/mypreferenceslanguages.js index a74c54f685..aad219ad4f 100644 --- a/dashboard-ui/scripts/mypreferenceslanguages.js +++ b/dashboard-ui/scripts/mypreferenceslanguages.js @@ -34,25 +34,28 @@ page.querySelector('.chkEnableChromecastAc3').checked = AppSettings.enableChromecastAc3(); page.querySelector('.chkExternalVideoPlayer').checked = AppSettings.enableExternalPlayers(); - var bitrateOptions = MediaPlayer.getVideoQualityOptions().map(function (i) { + require(['qualityoptions'], function (qualityoptions) { - return ''; + var bitrateOptions = qualityoptions.getVideoQualityOptions(AppSettings.maxStreamingBitrate()).map(function (i) { - }).join(''); + return ''; - bitrateOptions = '' + bitrateOptions; + }).join(''); - $('#selectMaxBitrate', page).html(bitrateOptions); + bitrateOptions = '' + bitrateOptions; - if (AppSettings.enableAutomaticBitrateDetection()) { - $('#selectMaxBitrate', page).val(''); - } else { - $('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate()); - } + $('#selectMaxBitrate', page).html(bitrateOptions); - $('#selectMaxChromecastBitrate', page).val(AppSettings.maxChromecastBitrate()); + if (AppSettings.enableAutomaticBitrateDetection()) { + $('#selectMaxBitrate', page).val(''); + } else { + $('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate()); + } - Dashboard.hideLoadingMsg(); + $('#selectMaxChromecastBitrate', page).val(AppSettings.maxChromecastBitrate()); + + Dashboard.hideLoadingMsg(); + }); } function loadPage(page) { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 2ce8557eb7..1243e5bcf4 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1804,6 +1804,7 @@ var AppInfo = {}; connectionmanagerfactory: apiClientBowerPath + '/connectionmanager', browserdeviceprofile: embyWebComponentsBowerPath + "/browserdeviceprofile", browser: embyWebComponentsBowerPath + "/browser", + qualityoptions: embyWebComponentsBowerPath + "/qualityoptions", connectservice: apiClientBowerPath + '/connectservice' }; From dc1dc6d111d0123be8409a70c6a53ac8cb378b85 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 29 Dec 2015 13:11:29 -0500 Subject: [PATCH 5/6] update downloading --- dashboard-ui/scripts/librarylist.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 4159bfa7ed..d55214233d 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -260,7 +260,7 @@ }); } - if (user.Policy.EnableContentDownloading) { + if (user.Policy.EnableContentDownloading && AppInfo.supportsDownloading) { if (mediaType) { items.push({ name: Globalize.translate('ButtonDownload'), @@ -1101,6 +1101,14 @@ ironIcon: 'playlist-add' }); + if (user.Policy.EnableContentDownloading && AppInfo.supportsDownloading) { + //items.push({ + // name: Globalize.translate('ButtonDownload'), + // id: 'download', + // ironIcon: 'file-download' + //}); + } + items.push({ name: Globalize.translate('HeaderGroupVersions'), id: 'groupvideos', From 982b1fe96572d689c6368aabcb12adc565f71efd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 29 Dec 2015 13:47:00 -0500 Subject: [PATCH 6/6] update startup resource loading Conflicts: MediaBrowser.WebDashboard/dashboard-ui/scripts/site.js --- dashboard-ui/scripts/site.js | 189 ++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 82 deletions(-) diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 1243e5bcf4..de51a00fa8 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -14,7 +14,7 @@ // Compatibility window.Logger = { - log: function(msg) { + log: function (msg) { console.log(msg); } }; @@ -310,6 +310,10 @@ var Dashboard = { showServerRestartWarning: function (systemInfo) { + if (AppInfo.isNativeApp) { + return; + } + var html = '' + Globalize.translate('MessagePleaseRestart') + ''; if (systemInfo.CanSelfRestart) { @@ -329,6 +333,10 @@ var Dashboard = { showDashboardRefreshNotification: function () { + if (AppInfo.isNativeApp) { + return; + } + var html = '' + Globalize.translate('MessagePleaseRefreshPage') + ''; html += '' + Globalize.translate('ButtonRefresh') + ''; @@ -364,10 +372,6 @@ var Dashboard = { showFooterNotification: function (options) { - if (!AppInfo.enableFooterNotifications) { - return; - } - var removeOnHide = !options.id; options.id = options.id || "notification" + new Date().getTime() + parseInt(Math.random()); @@ -1039,8 +1043,32 @@ var Dashboard = { { var args = cmd.Arguments; - if (args.TimeoutMs) { - Dashboard.showFooterNotification({ html: "
" + args.Header + "
" + args.Text, timeout: args.TimeoutMs }); + if (args.TimeoutMs && window.Notification && Notification.permission === "granted") { + + var notification = { + title: args.Header, + body: args.Text, + vibrate: true, + timeout: args.TimeoutMs + }; + + var notif = new Notification(notification.title, notification); + + if (notif.show) { + notif.show(); + } + + if (notification.timeout) { + setTimeout(function () { + + if (notif.close) { + notif.close(); + } + else if (notif.cancel) { + notif.cancel(); + } + }, notification.timeout); + } } else { Dashboard.alert({ title: args.Header, message: args.Text }); @@ -1168,6 +1196,10 @@ var Dashboard = { showPackageInstallNotification: function (installation, status) { + if (AppInfo.isNativeApp) { + return; + } + var html = ''; if (status == 'completed') { @@ -1229,7 +1261,7 @@ var Dashboard = { var newItems = data.ItemsAdded; - if (!newItems.length || AppInfo.isNativeApp || !window.Notification) { + if (!newItems.length || AppInfo.isNativeApp || !window.Notification || Notification.permission !== "granted") { return; } @@ -1254,8 +1286,14 @@ var Dashboard = { var notification = { title: "New " + item.Type, body: item.Name, - timeout: 5000, - vibrate: true + timeout: 15000, + vibrate: true, + + data: { + options: { + url: LibraryBrowser.getHref(item) + } + } }; var imageTags = item.ImageTags || {}; @@ -1269,25 +1307,22 @@ var Dashboard = { }); } - if (Notification.permission === "granted") { + var notif = new Notification(notification.title, notification); - var notif = new Notification(notification.title, notification); + if (notif.show) { + notif.show(); + } - if (notif.show) { - notif.show(); - } + if (notification.timeout) { + setTimeout(function () { - if (notification.timeout) { - setTimeout(function () { - - if (notif.close) { - notif.close(); - } - else if (notif.cancel) { - notif.cancel(); - } - }, notification.timeout); - } + if (notif.close) { + notif.close(); + } + else if (notif.cancel) { + notif.cancel(); + } + }, notification.timeout); } } }); @@ -1572,7 +1607,6 @@ var AppInfo = {}; } } else { - AppInfo.enableFooterNotifications = true; AppInfo.enableSupporterMembership = true; if (!isAndroid && !isIOS) { @@ -1618,24 +1652,34 @@ var AppInfo = {}; Events.on(apiClient, 'requestfail', Dashboard.onRequestFail); } + function getSyncProfile() { + + return getRequirePromise(['scripts/mediaplayer']).then(function () { + return MediaPlayer.getDeviceProfile(Math.max(screen.height, screen.width)); + }); + } + + function onApiClientCreated(e, newApiClient) { + initializeApiClient(newApiClient); + } + //localStorage.clear(); function createConnectionManager(credentialProviderFactory, capabilities) { var credentialKey = Dashboard.isConnectMode() ? null : 'servercredentials4'; var credentialProvider = new credentialProviderFactory(credentialKey); - window.ConnectionManager = new MediaBrowser.ConnectionManager(credentialProvider, AppInfo.appName, AppInfo.appVersion, AppInfo.deviceName, AppInfo.deviceId, capabilities, window.devicePixelRatio); + return getSyncProfile().then(function (deviceProfile) { - if (window.location.href.toLowerCase().indexOf('wizardstart.html') != -1) { - window.ConnectionManager.clearData(); - } + capabilities.DeviceProfile = deviceProfile; - Events.on(ConnectionManager, 'apiclientcreated', function (e, newApiClient) { + window.ConnectionManager = new MediaBrowser.ConnectionManager(credentialProvider, AppInfo.appName, AppInfo.appVersion, AppInfo.deviceName, AppInfo.deviceId, capabilities, window.devicePixelRatio); - initializeApiClient(newApiClient); - }); + if (window.location.href.toLowerCase().indexOf('wizardstart.html') != -1) { + window.ConnectionManager.clearData(); + } - return new Promise(function (resolve, reject) { + Events.on(ConnectionManager, 'apiclientcreated', onApiClientCreated); if (Dashboard.isConnectMode()) { @@ -1646,28 +1690,23 @@ var AppInfo = {}; if (server && server.UserId && server.AccessToken) { Dashboard.showLoadingMsg(); - ConnectionManager.connectToServer(server).then(function (result) { + return ConnectionManager.connectToServer(server).then(function (result) { Dashboard.showLoadingMsg(); if (result.State == MediaBrowser.ConnectionState.SignedIn) { window.ApiClient = result.ApiClient; } - resolve(); }); - return; } } - resolve(); } else { - - require(['apiclient'], function(apiClientFactory) { + return getRequirePromise(['apiclient']).then(function (apiClientFactory) { var apiClient = new apiClientFactory(Dashboard.serverAddress(), AppInfo.appName, AppInfo.appVersion, AppInfo.deviceName, AppInfo.deviceId, window.devicePixelRatio); apiClient.enableAutomaticNetworking = false; ConnectionManager.addApiClient(apiClient); Dashboard.importCss(apiClient.getUrl('Branding/Css')); window.ApiClient = apiClient; - resolve(); }); } }); @@ -2059,8 +2098,8 @@ var AppInfo = {}; deps.push('credentialprovider'); deps.push('appstorage'); - deps.push('scripts/mediaplayer'); deps.push('scripts/appsettings'); + deps.push('scripts/extensions'); require(deps, function (connectionManagerExports, credentialProviderFactory) { @@ -2102,12 +2141,9 @@ var AppInfo = {}; } } - var capabilities = Dashboard.capabilities(); - - capabilities.DeviceProfile = MediaPlayer.getDeviceProfile(Math.max(screen.height, screen.width)); - var promises = []; deps = []; + deps.push('scripts/mediaplayer'); deps.push('thirdparty/jquery.unveil-custom.js'); deps.push('emby-icons'); deps.push('paper-icon-button'); @@ -2117,7 +2153,7 @@ var AppInfo = {}; promises.push(getRequirePromise(deps)); promises.push(Globalize.ensure()); - promises.push(createConnectionManager(credentialProviderFactory, capabilities)); + promises.push(createConnectionManager(credentialProviderFactory, Dashboard.capabilities())); Promise.all(promises).then(function () { @@ -2213,7 +2249,6 @@ var AppInfo = {}; deps.push('scripts/sync'); deps.push('scripts/backdrops'); deps.push('scripts/librarymenu'); - deps.push('apiclient-deferred'); deps.push('css!css/card.css'); @@ -2236,6 +2271,7 @@ var AppInfo = {}; postInitDependencies.push('scripts/remotecontrol'); postInitDependencies.push('css!css/notifications.css'); postInitDependencies.push('css!css/chromecast.css'); + postInitDependencies.push('apiclient-deferred'); if (Dashboard.isRunningInCordova()) { @@ -2376,47 +2412,36 @@ var AppInfo = {}; initRequire(); - var initialDependencies = []; + function onWebComponentsReady() { - initialDependencies.push('browser'); - initialDependencies.push('apiclient-store'); - initialDependencies.push('scripts/extensions'); + var initialDependencies = []; - var supportsNativeWebComponents = 'registerElement' in document && 'content' in document.createElement('template'); + initialDependencies.push('browser'); + initialDependencies.push('apiclient-store'); - if (!supportsNativeWebComponents) { - initialDependencies.push('webcomponentsjs'); - } + if (!window.Promise) { + initialDependencies.push('native-promise-only'); + } - if (!window.Promise) { - initialDependencies.push('native-promise-only'); - } + require(initialDependencies, function (browser) { - require(initialDependencies, function (browser) { + window.browserInfo = browser; + setAppInfo(); + setDocumentClasses(); - window.browserInfo = browser; - - function onWebComponentsReady() { - - var polymerDependencies = []; - - require(polymerDependencies, function () { - - getHostingAppInfo().then(function (hostingAppInfo) { - init(hostingAppInfo); - }); + getHostingAppInfo().then(function (hostingAppInfo) { + init(hostingAppInfo); }); - } + }); + } - setAppInfo(); - setDocumentClasses(); - - if (supportsNativeWebComponents) { - onWebComponentsReady(); - } else { - document.addEventListener('WebComponentsReady', onWebComponentsReady); - } - }); + if ('registerElement' in document && 'content' in document.createElement('template')) { + // Native web components support + onWebComponentsReady(); + } else { + document.addEventListener('WebComponentsReady', onWebComponentsReady); + require(['webcomponentsjs']); + } })();