mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update quality options
This commit is contained in:
parent
9829e92e6d
commit
90d7da094c
17 changed files with 702 additions and 622 deletions
|
@ -15,12 +15,12 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"version": "1.0.2",
|
"version": "1.0.5",
|
||||||
"_release": "1.0.2",
|
"_release": "1.0.5",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "1.0.2",
|
"tag": "1.0.5",
|
||||||
"commit": "a4909b1637879d7e52ce9eaba8247ad98b690de9"
|
"commit": "ff6d4ba01de70b907dfa51b36aee6c63f64685c9"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
|
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
|
||||||
"_target": "~1.0.0",
|
"_target": "~1.0.0",
|
||||||
|
|
|
@ -225,6 +225,8 @@
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var videoAudioChannels = browser.safari ? '2' : '6';
|
||||||
|
|
||||||
profile.CodecProfiles.push({
|
profile.CodecProfiles.push({
|
||||||
Type: 'VideoAudio',
|
Type: 'VideoAudio',
|
||||||
Codec: 'aac',
|
Codec: 'aac',
|
||||||
|
@ -234,6 +236,17 @@
|
||||||
Condition: 'NotEquals',
|
Condition: 'NotEquals',
|
||||||
Property: 'AudioProfile',
|
Property: 'AudioProfile',
|
||||||
Value: 'HE-AAC'
|
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
|
// Disabling this is going to require us to learn why it was disabled in the first place
|
||||||
//,
|
//,
|
||||||
|
@ -252,7 +265,13 @@
|
||||||
{
|
{
|
||||||
Condition: 'LessThanEqual',
|
Condition: 'LessThanEqual',
|
||||||
Property: 'AudioChannels',
|
Property: 'AudioChannels',
|
||||||
Value: '6'
|
Value: videoAudioChannels
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Condition: 'Equals',
|
||||||
|
Property: 'IsSecondaryAudio',
|
||||||
|
Value: 'false',
|
||||||
|
IsRequired: 'false'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -260,6 +279,11 @@
|
||||||
profile.CodecProfiles.push({
|
profile.CodecProfiles.push({
|
||||||
Type: 'VideoAudio',
|
Type: 'VideoAudio',
|
||||||
Conditions: [
|
Conditions: [
|
||||||
|
{
|
||||||
|
Condition: 'LessThanEqual',
|
||||||
|
Property: 'AudioChannels',
|
||||||
|
Value: videoAudioChannels
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Condition: 'Equals',
|
Condition: 'Equals',
|
||||||
Property: 'IsSecondaryAudio',
|
Property: 'IsSecondaryAudio',
|
||||||
|
|
81
dashboard-ui/bower_components/emby-webcomponents/qualityoptions.js
vendored
Normal file
81
dashboard-ui/bower_components/emby-webcomponents/qualityoptions.js
vendored
Normal file
|
@ -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
|
||||||
|
};
|
||||||
|
});
|
|
@ -29,14 +29,14 @@
|
||||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
||||||
},
|
},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"homepage": "https://github.com/PolymerElements/iron-behaviors",
|
"homepage": "https://github.com/polymerelements/iron-behaviors",
|
||||||
"_release": "1.0.12",
|
"_release": "1.0.12",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.0.12",
|
"tag": "v1.0.12",
|
||||||
"commit": "657f526a2382a659cdf4e13be87ecc89261588a3"
|
"commit": "657f526a2382a659cdf4e13be87ecc89261588a3"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/PolymerElements/iron-behaviors.git",
|
"_source": "git://github.com/polymerelements/iron-behaviors.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
"_originalSource": "PolymerElements/iron-behaviors"
|
"_originalSource": "polymerelements/iron-behaviors"
|
||||||
}
|
}
|
|
@ -36,7 +36,7 @@
|
||||||
"tag": "v1.0.8",
|
"tag": "v1.0.8",
|
||||||
"commit": "e9a66727f3da0446f04956d4e4f1dcd51cdec2ff"
|
"commit": "e9a66727f3da0446f04956d4e4f1dcd51cdec2ff"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/PolymerElements/iron-selector.git",
|
"_source": "git://github.com/polymerelements/iron-selector.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
"_originalSource": "PolymerElements/iron-selector"
|
"_originalSource": "polymerelements/iron-selector"
|
||||||
}
|
}
|
|
@ -88,12 +88,6 @@
|
||||||
<div class="folderGroupList"></div>
|
<div class="folderGroupList"></div>
|
||||||
<div class="fieldDescription paperCheckboxFieldDescription">${LabelSelectFolderGroupsHelp}</div>
|
<div class="fieldDescription paperCheckboxFieldDescription">${LabelSelectFolderGroupsHelp}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
<paper-checkbox class="chkDisplayChannelsInline">${OptionDisplayChannelsInline}</paper-checkbox>
|
|
||||||
<div class="fieldDescription paperCheckboxFieldDescription">${OptionDisplayChannelsInlineHelp}</div>
|
|
||||||
</div>
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
'IDLE': 0,
|
'IDLE': 0,
|
||||||
'ACTIVE': 1,
|
'ACTIVE': 1,
|
||||||
'WARNING': 2,
|
'WARNING': 2,
|
||||||
'ERROR': 3,
|
'ERROR': 3
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,10 +52,11 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var applicationID = "2D4B1DA3";
|
var applicationID = "2D4B1DA3";
|
||||||
var messageNamespace = 'urn:x-cast:com.connectsdk';
|
|
||||||
|
|
||||||
//var applicationID = "F4EB2E8E";
|
// This is the beta version used for testing new changes
|
||||||
//var messageNamespace = 'urn:x-cast:com.google.cast.mediabrowser.v3';
|
//applicationID = '27C4EB5B';
|
||||||
|
|
||||||
|
var messageNamespace = 'urn:x-cast:com.connectsdk';
|
||||||
|
|
||||||
var CastPlayer = function () {
|
var CastPlayer = function () {
|
||||||
|
|
||||||
|
|
|
@ -95,9 +95,10 @@
|
||||||
|
|
||||||
elem.innerHTML = '';
|
elem.innerHTML = '';
|
||||||
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
return new Promise(function (resolve, reject) {
|
||||||
deferred.resolve();
|
|
||||||
return deferred.promise();
|
resolve();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,16 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.Policy.EnableContentDownloading && AppInfo.supportsDownloading) {
|
||||||
|
if (mediaType) {
|
||||||
|
items.push({
|
||||||
|
name: Globalize.translate('ButtonDownload'),
|
||||||
|
id: 'download',
|
||||||
|
ironIcon: 'file-download'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (commands.indexOf('delete') != -1) {
|
if (commands.indexOf('delete') != -1) {
|
||||||
items.push({
|
items.push({
|
||||||
name: Globalize.translate('ButtonDelete'),
|
name: Globalize.translate('ButtonDelete'),
|
||||||
|
@ -1091,6 +1101,14 @@
|
||||||
ironIcon: 'playlist-add'
|
ironIcon: 'playlist-add'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (user.Policy.EnableContentDownloading && AppInfo.supportsDownloading) {
|
||||||
|
//items.push({
|
||||||
|
// name: Globalize.translate('ButtonDownload'),
|
||||||
|
// id: 'download',
|
||||||
|
// ironIcon: 'file-download'
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
name: Globalize.translate('HeaderGroupVersions'),
|
name: Globalize.translate('HeaderGroupVersions'),
|
||||||
id: 'groupvideos',
|
id: 'groupvideos',
|
||||||
|
|
|
@ -140,41 +140,40 @@
|
||||||
|
|
||||||
self.showQualityFlyout = function () {
|
self.showQualityFlyout = function () {
|
||||||
|
|
||||||
var currentSrc = self.getCurrentSrc(self.currentMediaRenderer).toLowerCase();
|
require(['qualityoptions', 'actionsheet'], function (qualityoptions) {
|
||||||
var isStatic = currentSrc.indexOf('static=true') != -1;
|
|
||||||
|
|
||||||
var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) {
|
var currentSrc = self.getCurrentSrc(self.currentMediaRenderer).toLowerCase();
|
||||||
return stream.Type == "Video";
|
var isStatic = currentSrc.indexOf('static=true') != -1;
|
||||||
})[0];
|
|
||||||
var videoWidth = videoStream ? videoStream.Width : null;
|
|
||||||
var videoHeight = videoStream ? videoStream.Height : null;
|
|
||||||
|
|
||||||
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) {
|
var options = qualityoptions.getVideoQualityOptions(AppSettings.maxStreamingBitrate(), videoWidth);
|
||||||
options[0].name = "Direct";
|
|
||||||
}
|
|
||||||
|
|
||||||
var menuItems = options.map(function (o) {
|
if (isStatic) {
|
||||||
|
options[0].name = "Direct";
|
||||||
var opt = {
|
|
||||||
name: o.name,
|
|
||||||
id: o.bitrate
|
|
||||||
};
|
|
||||||
|
|
||||||
if (o.selected) {
|
|
||||||
opt.ironIcon = "check";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return opt;
|
var menuItems = options.map(function (o) {
|
||||||
});
|
|
||||||
|
|
||||||
var selectedId = options.filter(function (o) {
|
var opt = {
|
||||||
return o.selected;
|
name: o.name,
|
||||||
});
|
id: o.bitrate
|
||||||
selectedId = selectedId.length ? selectedId[0].bitrate : null;
|
};
|
||||||
require(['actionsheet'], function () {
|
|
||||||
|
|
||||||
|
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({
|
ActionSheetElement.show({
|
||||||
items: menuItems,
|
items: menuItems,
|
||||||
positionTo: $('.videoQualityButton')[0],
|
positionTo: $('.videoQualityButton')[0],
|
||||||
|
|
|
@ -36,477 +36,410 @@
|
||||||
return targets;
|
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) {
|
self.getDeviceProfile = function (maxHeight) {
|
||||||
|
|
||||||
if (!maxHeight) {
|
return new Promise(function (resolve, reject) {
|
||||||
maxHeight = self.getVideoQualityOptions().filter(function (q) {
|
|
||||||
return q.selected;
|
|
||||||
})[0].maxHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
var isVlc = AppInfo.isNativeApp && browserInfo.android;
|
require(['qualityoptions'], function (qualityoptions) {
|
||||||
var bitrateSetting = AppSettings.maxStreamingBitrate();
|
|
||||||
|
|
||||||
var supportedFormats = getSupportedFormats();
|
var bitrateSetting = AppSettings.maxStreamingBitrate();
|
||||||
|
|
||||||
var canPlayWebm = supportedFormats.indexOf('webm') != -1;
|
if (!maxHeight) {
|
||||||
var canPlayAc3 = supportedFormats.indexOf('ac3') != -1;
|
maxHeight = qualityoptions.getVideoQualityOptions(bitrateSetting).filter(function (q) {
|
||||||
var canPlayAac = supportedFormats.indexOf('aac') != -1;
|
return q.selected;
|
||||||
var canPlayMp3 = supportedFormats.indexOf('mp3') != -1;
|
})[0].maxHeight;
|
||||||
var canPlayMkv = supportedFormats.indexOf('mkv') != -1;
|
}
|
||||||
|
|
||||||
var profile = {};
|
var isVlc = AppInfo.isNativeApp && browserInfo.android;
|
||||||
|
|
||||||
profile.MaxStreamingBitrate = bitrateSetting;
|
var supportedFormats = getSupportedFormats();
|
||||||
profile.MaxStaticBitrate = 8000000;
|
|
||||||
profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000);
|
|
||||||
|
|
||||||
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) {
|
var profile = {};
|
||||||
profile.DirectPlayProfiles.push({
|
|
||||||
Container: 'mp4,m4v',
|
|
||||||
Type: 'Video',
|
|
||||||
VideoCodec: 'h264',
|
|
||||||
AudioCodec: 'aac' + (canPlayMp3 ? ',mp3' : '') + (canPlayAc3 ? ',ac3' : '')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canPlayMkv) {
|
profile.MaxStreamingBitrate = bitrateSetting;
|
||||||
profile.DirectPlayProfiles.push({
|
profile.MaxStaticBitrate = 8000000;
|
||||||
Container: 'mkv,mov',
|
profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000);
|
||||||
Type: 'Video',
|
|
||||||
VideoCodec: 'h264',
|
|
||||||
AudioCodec: 'aac' + (canPlayMp3 ? ',mp3' : '') + (canPlayAc3 ? ',ac3' : '')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var directPlayVideoContainers = AppInfo.directPlayVideoContainers;
|
profile.DirectPlayProfiles = [];
|
||||||
|
|
||||||
if (directPlayVideoContainers && directPlayVideoContainers.length) {
|
if (supportedFormats.indexOf('h264') != -1) {
|
||||||
profile.DirectPlayProfiles.push({
|
profile.DirectPlayProfiles.push({
|
||||||
Container: directPlayVideoContainers.join(','),
|
Container: 'mp4,m4v',
|
||||||
Type: 'Video'
|
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) {
|
var directPlayVideoContainers = AppInfo.directPlayVideoContainers;
|
||||||
profile.DirectPlayProfiles.push({
|
|
||||||
Container: audioFormat == 'webma' ? 'webma,webm' : audioFormat,
|
|
||||||
Type: 'Audio'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var directPlayAudioContainers = AppInfo.directPlayAudioContainers;
|
if (directPlayVideoContainers && directPlayVideoContainers.length) {
|
||||||
|
profile.DirectPlayProfiles.push({
|
||||||
|
Container: directPlayVideoContainers.join(','),
|
||||||
|
Type: 'Video'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (directPlayAudioContainers && directPlayAudioContainers.length) {
|
['opus', 'mp3', 'aac', 'webma'].forEach(function (audioFormat) {
|
||||||
profile.DirectPlayProfiles.push({
|
|
||||||
Container: directPlayAudioContainers.join(','),
|
|
||||||
Type: 'Audio'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canPlayWebm) {
|
if (supportedFormats.indexOf(audioFormat) != -1) {
|
||||||
profile.DirectPlayProfiles.push({
|
profile.DirectPlayProfiles.push({
|
||||||
Container: 'webm',
|
Container: audioFormat == 'webma' ? 'webma,webm' : audioFormat,
|
||||||
Type: 'Video'
|
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 (directPlayAudioContainers && directPlayAudioContainers.length) {
|
||||||
if (canPlayMkv && !isVlc && !browserInfo.mobile) {
|
profile.DirectPlayProfiles.push({
|
||||||
profile.TranscodingProfiles.push({
|
Container: directPlayAudioContainers.join(','),
|
||||||
Container: 'mkv',
|
Type: 'Audio'
|
||||||
Type: 'Video',
|
});
|
||||||
AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : '') + (canPlayMp3 ? ',mp3' : ''),
|
}
|
||||||
VideoCodec: 'h264',
|
|
||||||
Context: 'Streaming'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.canPlayHls()) {
|
if (canPlayWebm) {
|
||||||
profile.TranscodingProfiles.push({
|
profile.DirectPlayProfiles.push({
|
||||||
Container: 'ts',
|
Container: 'webm',
|
||||||
Type: 'Video',
|
Type: 'Video'
|
||||||
AudioCodec: 'aac' + (canPlayAc3 ? ',ac3' : ''),
|
});
|
||||||
VideoCodec: 'h264',
|
}
|
||||||
Context: 'Streaming',
|
|
||||||
Protocol: 'hls'
|
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({
|
profile.TranscodingProfiles.push({
|
||||||
Container: 'ts',
|
Container: 'mp4',
|
||||||
Type: 'Audio',
|
Type: 'Video',
|
||||||
AudioCodec: 'aac',
|
AudioCodec: 'aac',
|
||||||
|
VideoCodec: 'h264',
|
||||||
Context: 'Streaming',
|
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({
|
['opus', 'mp3', 'aac'].forEach(function (audioFormat) {
|
||||||
Container: 'webm',
|
|
||||||
Type: 'Video',
|
|
||||||
AudioCodec: 'vorbis',
|
|
||||||
VideoCodec: 'vpx',
|
|
||||||
Context: 'Streaming',
|
|
||||||
Protocol: 'http'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
profile.TranscodingProfiles.push({
|
if (supportedFormats.indexOf(audioFormat) != -1) {
|
||||||
Container: 'mp4',
|
profile.TranscodingProfiles.push({
|
||||||
Type: 'Video',
|
Container: audioFormat,
|
||||||
AudioCodec: 'aac',
|
Type: 'Audio',
|
||||||
VideoCodec: 'h264',
|
AudioCodec: audioFormat,
|
||||||
Context: 'Streaming',
|
Context: 'Streaming',
|
||||||
Protocol: 'http'
|
Protocol: 'http'
|
||||||
});
|
});
|
||||||
|
profile.TranscodingProfiles.push({
|
||||||
|
Container: audioFormat,
|
||||||
|
Type: 'Audio',
|
||||||
|
AudioCodec: audioFormat,
|
||||||
|
Context: 'Static',
|
||||||
|
Protocol: 'http'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
profile.TranscodingProfiles.push({
|
profile.ContainerProfiles = [];
|
||||||
Container: 'mp4',
|
|
||||||
Type: 'Video',
|
|
||||||
AudioCodec: 'aac',
|
|
||||||
VideoCodec: 'h264',
|
|
||||||
Context: 'Static',
|
|
||||||
Protocol: 'http'
|
|
||||||
});
|
|
||||||
|
|
||||||
['opus', 'mp3', 'aac'].forEach(function(audioFormat){
|
profile.CodecProfiles = [];
|
||||||
|
profile.CodecProfiles.push({
|
||||||
if (supportedFormats.indexOf(audioFormat) != -1) {
|
Type: 'Audio',
|
||||||
profile.TranscodingProfiles.push({
|
Conditions: [{
|
||||||
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: [
|
|
||||||
{
|
|
||||||
Condition: 'LessThanEqual',
|
Condition: 'LessThanEqual',
|
||||||
Property: 'AudioChannels',
|
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 {
|
|
||||||
|
|
||||||
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) {
|
|
||||||
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;
|
var supportsTextTracks;
|
||||||
|
@ -631,36 +564,37 @@
|
||||||
var playSessionId = getParameterByName('PlaySessionId', currentSrc);
|
var playSessionId = getParameterByName('PlaySessionId', currentSrc);
|
||||||
var liveStreamId = getParameterByName('LiveStreamId', currentSrc);
|
var liveStreamId = getParameterByName('LiveStreamId', currentSrc);
|
||||||
|
|
||||||
var deviceProfile = self.getDeviceProfile();
|
self.getDeviceProfile().then(function (deviceProfile) {
|
||||||
|
|
||||||
var audioStreamIndex = params.AudioStreamIndex == null ? (getParameterByName('AudioStreamIndex', currentSrc) || null) : params.AudioStreamIndex;
|
var audioStreamIndex = params.AudioStreamIndex == null ? (getParameterByName('AudioStreamIndex', currentSrc) || null) : params.AudioStreamIndex;
|
||||||
if (typeof (audioStreamIndex) == 'string') {
|
if (typeof (audioStreamIndex) == 'string') {
|
||||||
audioStreamIndex = parseInt(audioStreamIndex);
|
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);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1087,6 +1021,12 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var onBitrateDetected = function() {
|
||||||
|
self.getDeviceProfile().then(function(deviceProfile) {
|
||||||
|
playOnDeviceProfileCreated(deviceProfile, item, startPosition, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var bitrateDetectionKey = ApiClient.serverAddress();
|
var bitrateDetectionKey = ApiClient.serverAddress();
|
||||||
|
|
||||||
if (item.MediaType == 'Video' && AppSettings.enableAutomaticBitrateDetection() && (new Date().getTime() - (self.lastBitrateDetections[bitrateDetectionKey] || 0)) > 300000) {
|
if (item.MediaType == 'Video' && AppSettings.enableAutomaticBitrateDetection() && (new Date().getTime() - (self.lastBitrateDetections[bitrateDetectionKey] || 0)) > 300000) {
|
||||||
|
@ -1098,15 +1038,12 @@
|
||||||
self.lastBitrateDetections[bitrateDetectionKey] = new Date().getTime();
|
self.lastBitrateDetections[bitrateDetectionKey] = new Date().getTime();
|
||||||
AppSettings.maxStreamingBitrate(bitrate);
|
AppSettings.maxStreamingBitrate(bitrate);
|
||||||
|
|
||||||
playOnDeviceProfileCreated(self.getDeviceProfile(), item, startPosition, callback);
|
onBitrateDetected();
|
||||||
|
|
||||||
}, function () {
|
}, onBitrateDetected);
|
||||||
|
|
||||||
playOnDeviceProfileCreated(self.getDeviceProfile(), item, startPosition, callback);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
playOnDeviceProfileCreated(self.getDeviceProfile(), item, startPosition, callback);
|
onBitrateDetected();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,6 @@
|
||||||
|
|
||||||
page.querySelector('.chkDisplayCollectionView').checked = user.Configuration.DisplayCollectionsView || false;
|
page.querySelector('.chkDisplayCollectionView').checked = user.Configuration.DisplayCollectionsView || false;
|
||||||
page.querySelector('.chkHidePlayedFromLatest').checked = user.Configuration.HidePlayedInLatest || false;
|
page.querySelector('.chkHidePlayedFromLatest').checked = user.Configuration.HidePlayedInLatest || false;
|
||||||
page.querySelector('.chkDisplayChannelsInline').checked = user.Configuration.DisplayChannelsInline || false;
|
|
||||||
|
|
||||||
$('#selectHomeSection1', page).val(displayPreferences.CustomPrefs.home0 || '');
|
$('#selectHomeSection1', page).val(displayPreferences.CustomPrefs.home0 || '');
|
||||||
$('#selectHomeSection2', page).val(displayPreferences.CustomPrefs.home1 || '');
|
$('#selectHomeSection2', page).val(displayPreferences.CustomPrefs.home1 || '');
|
||||||
|
@ -159,8 +158,6 @@
|
||||||
user.Configuration.DisplayCollectionsView = page.querySelector('.chkDisplayCollectionView').checked;
|
user.Configuration.DisplayCollectionsView = page.querySelector('.chkDisplayCollectionView').checked;
|
||||||
user.Configuration.HidePlayedInLatest = page.querySelector('.chkHidePlayedFromLatest').checked;
|
user.Configuration.HidePlayedInLatest = page.querySelector('.chkHidePlayedFromLatest').checked;
|
||||||
|
|
||||||
user.Configuration.DisplayChannelsInline = page.querySelector('.chkDisplayChannelsInline').checked;
|
|
||||||
|
|
||||||
user.Configuration.LatestItemsExcludes = $(".chkIncludeInLatest", page).get().filter(function (i) {
|
user.Configuration.LatestItemsExcludes = $(".chkIncludeInLatest", page).get().filter(function (i) {
|
||||||
|
|
||||||
return !i.checked;
|
return !i.checked;
|
||||||
|
|
|
@ -34,25 +34,28 @@
|
||||||
page.querySelector('.chkEnableChromecastAc3').checked = AppSettings.enableChromecastAc3();
|
page.querySelector('.chkEnableChromecastAc3').checked = AppSettings.enableChromecastAc3();
|
||||||
page.querySelector('.chkExternalVideoPlayer').checked = AppSettings.enableExternalPlayers();
|
page.querySelector('.chkExternalVideoPlayer').checked = AppSettings.enableExternalPlayers();
|
||||||
|
|
||||||
var bitrateOptions = MediaPlayer.getVideoQualityOptions().map(function (i) {
|
require(['qualityoptions'], function (qualityoptions) {
|
||||||
|
|
||||||
return '<option value="' + i.bitrate + '">' + i.name + '</option>';
|
var bitrateOptions = qualityoptions.getVideoQualityOptions(AppSettings.maxStreamingBitrate()).map(function (i) {
|
||||||
|
|
||||||
}).join('');
|
return '<option value="' + i.bitrate + '">' + i.name + '</option>';
|
||||||
|
|
||||||
bitrateOptions = '<option value="">' + Globalize.translate('OptionAutomatic') + '</option>' + bitrateOptions;
|
}).join('');
|
||||||
|
|
||||||
$('#selectMaxBitrate', page).html(bitrateOptions);
|
bitrateOptions = '<option value="">' + Globalize.translate('OptionAutomatic') + '</option>' + bitrateOptions;
|
||||||
|
|
||||||
if (AppSettings.enableAutomaticBitrateDetection()) {
|
$('#selectMaxBitrate', page).html(bitrateOptions);
|
||||||
$('#selectMaxBitrate', page).val('');
|
|
||||||
} else {
|
|
||||||
$('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate());
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#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) {
|
function loadPage(page) {
|
||||||
|
|
|
@ -336,7 +336,6 @@
|
||||||
html += '<div class="itemsContainer">';
|
html += '<div class="itemsContainer">';
|
||||||
html += LibraryBrowser.getPosterViewHtml({
|
html += LibraryBrowser.getPosterViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
preferThumb: true,
|
|
||||||
shape: 'auto',
|
shape: 'auto',
|
||||||
showTitle: true,
|
showTitle: true,
|
||||||
centerText: true,
|
centerText: true,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
// Compatibility
|
// Compatibility
|
||||||
window.Logger = {
|
window.Logger = {
|
||||||
log: function(msg) {
|
log: function (msg) {
|
||||||
console.log(msg);
|
console.log(msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -310,6 +310,10 @@ var Dashboard = {
|
||||||
|
|
||||||
showServerRestartWarning: function (systemInfo) {
|
showServerRestartWarning: function (systemInfo) {
|
||||||
|
|
||||||
|
if (AppInfo.isNativeApp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var html = '<span style="margin-right: 1em;">' + Globalize.translate('MessagePleaseRestart') + '</span>';
|
var html = '<span style="margin-right: 1em;">' + Globalize.translate('MessagePleaseRestart') + '</span>';
|
||||||
|
|
||||||
if (systemInfo.CanSelfRestart) {
|
if (systemInfo.CanSelfRestart) {
|
||||||
|
@ -329,6 +333,10 @@ var Dashboard = {
|
||||||
|
|
||||||
showDashboardRefreshNotification: function () {
|
showDashboardRefreshNotification: function () {
|
||||||
|
|
||||||
|
if (AppInfo.isNativeApp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var html = '<span style="margin-right: 1em;">' + Globalize.translate('MessagePleaseRefreshPage') + '</span>';
|
var html = '<span style="margin-right: 1em;">' + Globalize.translate('MessagePleaseRefreshPage') + '</span>';
|
||||||
|
|
||||||
html += '<paper-button raised class="submit mini" onclick="this.disabled=\'disabled\';Dashboard.reloadPage();"><iron-icon icon="refresh"></iron-icon><span>' + Globalize.translate('ButtonRefresh') + '</span></paper-button>';
|
html += '<paper-button raised class="submit mini" onclick="this.disabled=\'disabled\';Dashboard.reloadPage();"><iron-icon icon="refresh"></iron-icon><span>' + Globalize.translate('ButtonRefresh') + '</span></paper-button>';
|
||||||
|
@ -364,10 +372,6 @@ var Dashboard = {
|
||||||
|
|
||||||
showFooterNotification: function (options) {
|
showFooterNotification: function (options) {
|
||||||
|
|
||||||
if (!AppInfo.enableFooterNotifications) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var removeOnHide = !options.id;
|
var removeOnHide = !options.id;
|
||||||
|
|
||||||
options.id = options.id || "notification" + new Date().getTime() + parseInt(Math.random());
|
options.id = options.id || "notification" + new Date().getTime() + parseInt(Math.random());
|
||||||
|
@ -1039,8 +1043,32 @@ var Dashboard = {
|
||||||
{
|
{
|
||||||
var args = cmd.Arguments;
|
var args = cmd.Arguments;
|
||||||
|
|
||||||
if (args.TimeoutMs) {
|
if (args.TimeoutMs && window.Notification && Notification.permission === "granted") {
|
||||||
Dashboard.showFooterNotification({ html: "<div><b>" + args.Header + "</b></div>" + args.Text, timeout: args.TimeoutMs });
|
|
||||||
|
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 {
|
else {
|
||||||
Dashboard.alert({ title: args.Header, message: args.Text });
|
Dashboard.alert({ title: args.Header, message: args.Text });
|
||||||
|
@ -1168,6 +1196,10 @@ var Dashboard = {
|
||||||
|
|
||||||
showPackageInstallNotification: function (installation, status) {
|
showPackageInstallNotification: function (installation, status) {
|
||||||
|
|
||||||
|
if (AppInfo.isNativeApp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
if (status == 'completed') {
|
if (status == 'completed') {
|
||||||
|
@ -1229,7 +1261,7 @@ var Dashboard = {
|
||||||
|
|
||||||
var newItems = data.ItemsAdded;
|
var newItems = data.ItemsAdded;
|
||||||
|
|
||||||
if (!newItems.length || AppInfo.isNativeApp || !window.Notification) {
|
if (!newItems.length || AppInfo.isNativeApp || !window.Notification || Notification.permission !== "granted") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,8 +1286,14 @@ var Dashboard = {
|
||||||
var notification = {
|
var notification = {
|
||||||
title: "New " + item.Type,
|
title: "New " + item.Type,
|
||||||
body: item.Name,
|
body: item.Name,
|
||||||
timeout: 5000,
|
timeout: 15000,
|
||||||
vibrate: true
|
vibrate: true,
|
||||||
|
|
||||||
|
data: {
|
||||||
|
options: {
|
||||||
|
url: LibraryBrowser.getHref(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var imageTags = item.ImageTags || {};
|
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) {
|
if (notification.timeout) {
|
||||||
notif.show();
|
setTimeout(function () {
|
||||||
}
|
|
||||||
|
|
||||||
if (notification.timeout) {
|
if (notif.close) {
|
||||||
setTimeout(function () {
|
notif.close();
|
||||||
|
}
|
||||||
if (notif.close) {
|
else if (notif.cancel) {
|
||||||
notif.close();
|
notif.cancel();
|
||||||
}
|
}
|
||||||
else if (notif.cancel) {
|
}, notification.timeout);
|
||||||
notif.cancel();
|
|
||||||
}
|
|
||||||
}, notification.timeout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1572,7 +1607,6 @@ var AppInfo = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AppInfo.enableFooterNotifications = true;
|
|
||||||
AppInfo.enableSupporterMembership = true;
|
AppInfo.enableSupporterMembership = true;
|
||||||
|
|
||||||
if (!isAndroid && !isIOS) {
|
if (!isAndroid && !isIOS) {
|
||||||
|
@ -1618,24 +1652,34 @@ var AppInfo = {};
|
||||||
Events.on(apiClient, 'requestfail', Dashboard.onRequestFail);
|
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();
|
//localStorage.clear();
|
||||||
function createConnectionManager(credentialProviderFactory, capabilities) {
|
function createConnectionManager(credentialProviderFactory, capabilities) {
|
||||||
|
|
||||||
var credentialKey = Dashboard.isConnectMode() ? null : 'servercredentials4';
|
var credentialKey = Dashboard.isConnectMode() ? null : 'servercredentials4';
|
||||||
var credentialProvider = new credentialProviderFactory(credentialKey);
|
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) {
|
capabilities.DeviceProfile = deviceProfile;
|
||||||
window.ConnectionManager.clearData();
|
|
||||||
}
|
|
||||||
|
|
||||||
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()) {
|
if (Dashboard.isConnectMode()) {
|
||||||
|
|
||||||
|
@ -1646,28 +1690,23 @@ var AppInfo = {};
|
||||||
if (server && server.UserId && server.AccessToken) {
|
if (server && server.UserId && server.AccessToken) {
|
||||||
Dashboard.showLoadingMsg();
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
ConnectionManager.connectToServer(server).then(function (result) {
|
return ConnectionManager.connectToServer(server).then(function (result) {
|
||||||
Dashboard.showLoadingMsg();
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
if (result.State == MediaBrowser.ConnectionState.SignedIn) {
|
if (result.State == MediaBrowser.ConnectionState.SignedIn) {
|
||||||
window.ApiClient = result.ApiClient;
|
window.ApiClient = result.ApiClient;
|
||||||
}
|
}
|
||||||
resolve();
|
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resolve();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
return getRequirePromise(['apiclient']).then(function (apiClientFactory) {
|
||||||
require(['apiclient'], function(apiClientFactory) {
|
|
||||||
var apiClient = new apiClientFactory(Dashboard.serverAddress(), AppInfo.appName, AppInfo.appVersion, AppInfo.deviceName, AppInfo.deviceId, window.devicePixelRatio);
|
var apiClient = new apiClientFactory(Dashboard.serverAddress(), AppInfo.appName, AppInfo.appVersion, AppInfo.deviceName, AppInfo.deviceId, window.devicePixelRatio);
|
||||||
apiClient.enableAutomaticNetworking = false;
|
apiClient.enableAutomaticNetworking = false;
|
||||||
ConnectionManager.addApiClient(apiClient);
|
ConnectionManager.addApiClient(apiClient);
|
||||||
Dashboard.importCss(apiClient.getUrl('Branding/Css'));
|
Dashboard.importCss(apiClient.getUrl('Branding/Css'));
|
||||||
window.ApiClient = apiClient;
|
window.ApiClient = apiClient;
|
||||||
resolve();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1804,6 +1843,7 @@ var AppInfo = {};
|
||||||
connectionmanagerfactory: apiClientBowerPath + '/connectionmanager',
|
connectionmanagerfactory: apiClientBowerPath + '/connectionmanager',
|
||||||
browserdeviceprofile: embyWebComponentsBowerPath + "/browserdeviceprofile",
|
browserdeviceprofile: embyWebComponentsBowerPath + "/browserdeviceprofile",
|
||||||
browser: embyWebComponentsBowerPath + "/browser",
|
browser: embyWebComponentsBowerPath + "/browser",
|
||||||
|
qualityoptions: embyWebComponentsBowerPath + "/qualityoptions",
|
||||||
connectservice: apiClientBowerPath + '/connectservice'
|
connectservice: apiClientBowerPath + '/connectservice'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2058,8 +2098,8 @@ var AppInfo = {};
|
||||||
deps.push('credentialprovider');
|
deps.push('credentialprovider');
|
||||||
|
|
||||||
deps.push('appstorage');
|
deps.push('appstorage');
|
||||||
deps.push('scripts/mediaplayer');
|
|
||||||
deps.push('scripts/appsettings');
|
deps.push('scripts/appsettings');
|
||||||
|
deps.push('scripts/extensions');
|
||||||
|
|
||||||
require(deps, function (connectionManagerExports, credentialProviderFactory) {
|
require(deps, function (connectionManagerExports, credentialProviderFactory) {
|
||||||
|
|
||||||
|
@ -2101,12 +2141,9 @@ var AppInfo = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var capabilities = Dashboard.capabilities();
|
|
||||||
|
|
||||||
capabilities.DeviceProfile = MediaPlayer.getDeviceProfile(Math.max(screen.height, screen.width));
|
|
||||||
|
|
||||||
var promises = [];
|
var promises = [];
|
||||||
deps = [];
|
deps = [];
|
||||||
|
deps.push('scripts/mediaplayer');
|
||||||
deps.push('thirdparty/jquery.unveil-custom.js');
|
deps.push('thirdparty/jquery.unveil-custom.js');
|
||||||
deps.push('emby-icons');
|
deps.push('emby-icons');
|
||||||
deps.push('paper-icon-button');
|
deps.push('paper-icon-button');
|
||||||
|
@ -2116,7 +2153,7 @@ var AppInfo = {};
|
||||||
promises.push(getRequirePromise(deps));
|
promises.push(getRequirePromise(deps));
|
||||||
|
|
||||||
promises.push(Globalize.ensure());
|
promises.push(Globalize.ensure());
|
||||||
promises.push(createConnectionManager(credentialProviderFactory, capabilities));
|
promises.push(createConnectionManager(credentialProviderFactory, Dashboard.capabilities()));
|
||||||
|
|
||||||
Promise.all(promises).then(function () {
|
Promise.all(promises).then(function () {
|
||||||
|
|
||||||
|
@ -2212,7 +2249,6 @@ var AppInfo = {};
|
||||||
deps.push('scripts/sync');
|
deps.push('scripts/sync');
|
||||||
deps.push('scripts/backdrops');
|
deps.push('scripts/backdrops');
|
||||||
deps.push('scripts/librarymenu');
|
deps.push('scripts/librarymenu');
|
||||||
deps.push('apiclient-deferred');
|
|
||||||
|
|
||||||
deps.push('css!css/card.css');
|
deps.push('css!css/card.css');
|
||||||
|
|
||||||
|
@ -2235,6 +2271,7 @@ var AppInfo = {};
|
||||||
postInitDependencies.push('scripts/remotecontrol');
|
postInitDependencies.push('scripts/remotecontrol');
|
||||||
postInitDependencies.push('css!css/notifications.css');
|
postInitDependencies.push('css!css/notifications.css');
|
||||||
postInitDependencies.push('css!css/chromecast.css');
|
postInitDependencies.push('css!css/chromecast.css');
|
||||||
|
postInitDependencies.push('apiclient-deferred');
|
||||||
|
|
||||||
if (Dashboard.isRunningInCordova()) {
|
if (Dashboard.isRunningInCordova()) {
|
||||||
|
|
||||||
|
@ -2375,47 +2412,36 @@ var AppInfo = {};
|
||||||
|
|
||||||
initRequire();
|
initRequire();
|
||||||
|
|
||||||
var initialDependencies = [];
|
function onWebComponentsReady() {
|
||||||
|
|
||||||
initialDependencies.push('browser');
|
var initialDependencies = [];
|
||||||
initialDependencies.push('apiclient-store');
|
|
||||||
initialDependencies.push('scripts/extensions');
|
|
||||||
|
|
||||||
var supportsNativeWebComponents = 'registerElement' in document && 'content' in document.createElement('template');
|
initialDependencies.push('browser');
|
||||||
|
initialDependencies.push('apiclient-store');
|
||||||
|
|
||||||
if (!supportsNativeWebComponents) {
|
if (!window.Promise) {
|
||||||
initialDependencies.push('webcomponentsjs');
|
initialDependencies.push('native-promise-only');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.Promise) {
|
require(initialDependencies, function (browser) {
|
||||||
initialDependencies.push('native-promise-only');
|
|
||||||
}
|
|
||||||
|
|
||||||
require(initialDependencies, function (browser) {
|
window.browserInfo = browser;
|
||||||
|
setAppInfo();
|
||||||
|
setDocumentClasses();
|
||||||
|
|
||||||
window.browserInfo = browser;
|
getHostingAppInfo().then(function (hostingAppInfo) {
|
||||||
|
init(hostingAppInfo);
|
||||||
function onWebComponentsReady() {
|
|
||||||
|
|
||||||
var polymerDependencies = [];
|
|
||||||
|
|
||||||
require(polymerDependencies, function () {
|
|
||||||
|
|
||||||
getHostingAppInfo().then(function (hostingAppInfo) {
|
|
||||||
init(hostingAppInfo);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setAppInfo();
|
if ('registerElement' in document && 'content' in document.createElement('template')) {
|
||||||
setDocumentClasses();
|
// Native web components support
|
||||||
|
onWebComponentsReady();
|
||||||
if (supportsNativeWebComponents) {
|
} else {
|
||||||
onWebComponentsReady();
|
document.addEventListener('WebComponentsReady', onWebComponentsReady);
|
||||||
} else {
|
require(['webcomponentsjs']);
|
||||||
document.addEventListener('WebComponentsReady', onWebComponentsReady);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@
|
||||||
|
|
||||||
Dashboard.alert({
|
Dashboard.alert({
|
||||||
|
|
||||||
message: Globalize.translate('ErrorAddingEmbyConnectAccount')
|
message: Globalize.translate('ErrorAddingEmbyConnectAccount', 'apps@emby.media')
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -402,7 +402,7 @@
|
||||||
"MessagePleaseRestart": "Please restart to finish updating.",
|
"MessagePleaseRestart": "Please restart to finish updating.",
|
||||||
"ButtonRestart": "Restart",
|
"ButtonRestart": "Restart",
|
||||||
"ButtonRefresh": "Refresh",
|
"ButtonRefresh": "Refresh",
|
||||||
"MessagePleaseRefreshPage": "Please refresh this page to receive new updates from the server.",
|
"MessagePleaseRefreshPage": "Please refresh this page to receive new updates from Emby Server.",
|
||||||
"ButtonHide": "Hide",
|
"ButtonHide": "Hide",
|
||||||
"MessageSettingsSaved": "Settings saved.",
|
"MessageSettingsSaved": "Settings saved.",
|
||||||
"ButtonSignOut": "Sign Out",
|
"ButtonSignOut": "Sign Out",
|
||||||
|
@ -928,7 +928,7 @@
|
||||||
"PleaseAddAtLeastOneFolder": "Please add at least one folder to this library by clicking the Add button.",
|
"PleaseAddAtLeastOneFolder": "Please add at least one folder to this library by clicking the Add button.",
|
||||||
"ErrorAddingMediaPathToVirtualFolder": "There was an error adding the media path. Please ensure the path is valid and the Emby Server process has access to that location.",
|
"ErrorAddingMediaPathToVirtualFolder": "There was an error adding the media path. Please ensure the path is valid and the Emby Server process has access to that location.",
|
||||||
"ErrorRemovingEmbyConnectAccount": "There was an error removing the Emby Connect account. Please ensure you have an active internet connection and try again.",
|
"ErrorRemovingEmbyConnectAccount": "There was an error removing the Emby Connect account. Please ensure you have an active internet connection and try again.",
|
||||||
"ErrorAddingEmbyConnectAccount": "There was an error adding the Emby Connect account. Please ensure the Emby account has been activated by following the instructions in the email sent after creating the account. If this email was not received please send an email to apps@emby.media from the email address used with the Emby account.",
|
"ErrorAddingEmbyConnectAccount": "There was an error adding the Emby Connect account. Please ensure the Emby account has been activated by following the instructions in the email sent after creating the account. If you did not receive this email then please send an email to {0} from the email address used with the Emby account.",
|
||||||
"HeaderFavoriteArtists": "Favorite Artists",
|
"HeaderFavoriteArtists": "Favorite Artists",
|
||||||
"HeaderFavoriteSongs": "Favorite Songs",
|
"HeaderFavoriteSongs": "Favorite Songs",
|
||||||
"HeaderConfirmPluginInstallation": "Confirm Plugin Installation",
|
"HeaderConfirmPluginInstallation": "Confirm Plugin Installation",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue