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

3.0.5621.2

This commit is contained in:
Luke Pulverenti 2015-05-25 13:32:22 -04:00
parent 2e982826bb
commit 4e86a39f8c
25 changed files with 651 additions and 550 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Before After
Before After

View file

@ -175,10 +175,8 @@
<div> <div>
<fieldset data-role="controlgroup"> <fieldset data-role="controlgroup">
<legend>${LabelExternalPlayers}</legend> <legend>${LabelExternalPlayers}</legend>
<!--<input type="checkbox" id="chkGoodplayer" class="chkExternalPlayer" data-name="GoodPlayer" data-scheme="goodplayer://{0}" /> <input type="checkbox" id="chkExternalVideoPlayer" />
<label for="chkGoodplayer">GoodPlayer</label>--> <label for="chkExternalVideoPlayer">${OptionEnableExternalVideoPlayers}</label>
<input type="checkbox" id="chkVlc" class="chkExternalPlayer" data-name="Vlc" data-scheme="vlc://{0}" />
<label for="chkVlc">Vlc</label>
</fieldset> </fieldset>
<div style="padding: 0 2px;">${LabelExternalPlayersHelp}</div> <div style="padding: 0 2px;">${LabelExternalPlayersHelp}</div>
</div> </div>

View file

@ -809,11 +809,9 @@
}); });
} }
if ($.browser.chrome) {
requirejs(["thirdparty/cast_sender"], function () { requirejs(["thirdparty/cast_sender"], function () {
initializeChromecast(); initializeChromecast();
}); });
}
})(window, window.chrome, console); })(window, window.chrome, console);

View file

@ -1012,8 +1012,7 @@
} }
}; };
$(document).on('pagebeforeshowready', "#dashboardPage", DashboardPage.onPageShow) $(document).on('pageshowready', "#dashboardPage", DashboardPage.onPageShow).on('pagehide', "#dashboardPage", DashboardPage.onPageHide);
.on('pagehide', "#dashboardPage", DashboardPage.onPageHide);
(function ($, document, window) { (function ($, document, window) {
@ -1308,7 +1307,7 @@ $(document).on('pagebeforeshowready', "#dashboardPage", DashboardPage.onPageShow
result.CustomPrefs[welcomeTourKey] = welcomeDismissValue; result.CustomPrefs[welcomeTourKey] = welcomeDismissValue;
ApiClient.updateDisplayPreferences('dashboard', result, userId, 'dashboard'); ApiClient.updateDisplayPreferences('dashboard', result, userId, 'dashboard');
$(page).off('pagebeforeshow.checktour'); $(page).off('.checktour');
}); });
} }
@ -1373,7 +1372,7 @@ $(document).on('pagebeforeshowready', "#dashboardPage", DashboardPage.onPageShow
takeTour(page, Dashboard.getCurrentUserId()); takeTour(page, Dashboard.getCurrentUserId());
}); });
}).on('pagebeforeshowready.checktour', "#dashboardPage", function () { }).on('pageshowready.checktour', "#dashboardPage", function () {
var page = this; var page = this;
@ -1389,7 +1388,7 @@ $(document).on('pagebeforeshowready', "#dashboardPage", DashboardPage.onPageShow
(function () { (function () {
$(document).on('pagebeforeshowready', ".type-interior", function () { $(document).on('pageshowready', ".type-interior", function () {
var page = this; var page = this;

View file

@ -1,315 +1,301 @@
(function (window, store) { (function (window, store) {
function getExternalPlayers() { function getDeviceProfile(serverAddress, deviceId, item, startPositionTicks, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex) {
return JSON.parse(store.getItem('externalplayers') || '[]');
var bitrateSetting = AppSettings.maxStreamingBitrate();
var profile = {};
profile.MaxStreamingBitrate = bitrateSetting;
profile.MaxStaticBitrate = 40000000;
profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000);
profile.DirectPlayProfiles = [];
profile.DirectPlayProfiles.push({
Container: 'mkv,mov,mp4,m4v,wmv',
Type: 'Video'
});
profile.DirectPlayProfiles.push({
Container: 'aac,mp3,flac,wma',
Type: 'Audio'
});
profile.TranscodingProfiles = [];
profile.TranscodingProfiles.push({
Container: 'ts',
Type: 'Video',
AudioCodec: 'aac',
VideoCodec: 'h264',
Context: 'Streaming',
Protocol: 'hls'
});
profile.TranscodingProfiles.push({
Container: 'aac',
Type: 'Audio',
AudioCodec: 'aac',
Context: 'Streaming',
Protocol: 'hls'
});
profile.ContainerProfiles = [];
var audioConditions = [];
var maxAudioChannels = '6';
audioConditions.push({
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: maxAudioChannels
});
profile.CodecProfiles = [];
profile.CodecProfiles.push({
Type: 'Audio',
Conditions: audioConditions
});
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'mp3',
Conditions: [{
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: maxAudioChannels
}]
});
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'aac',
Conditions: [
{
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: maxAudioChannels
}
]
});
profile.CodecProfiles.push({
Type: 'Video',
Codec: 'h264',
Conditions: [
{
Condition: 'EqualsAny',
Property: 'VideoProfile',
Value: 'high|main|baseline|constrained baseline'
},
{
Condition: 'LessThanEqual',
Property: 'VideoLevel',
Value: '41'
}]
});
// Subtitle profiles
profile.SubtitleProfiles = [];
profile.ResponseProfiles = [];
return profile;
} }
function getUrl(player, item) { function validatePlaybackInfoResult(result) {
return 'vlc://http://www.google.com'; if (result.ErrorCode) {
} MediaController.showPlaybackInfoErrorMessage(result.ErrorCode);
function getCodecLimits(maxBitrate) {
var maxWidth;
if (maxBitrate <= 1000000) {
maxWidth = 720;
}
else if (maxBitrate <= 5000000) {
maxWidth = 1280;
} else {
maxWidth = 1280;
}
return {
maxVideoAudioChannels: 6,
maxAudioChannels: 2,
maxVideoLevel: 50,
maxWidth: maxWidth,
maxSampleRate: 48000
};
}
function canDirectStream(mediaType, mediaSource, maxBitrate) {
// If bitrate is unknown don't direct stream
if (!mediaSource.Bitrate || mediaSource.Bitrate > maxBitrate) {
return false; return false;
} }
var codecLimits = getCodecLimits(maxBitrate);
if (mediaType == "Audio") {
return true;
}
else if (mediaType == "Video") {
var videoStream = mediaSource.MediaStreams.filter(function (s) {
return s.Type == 'Video';
})[0];
if (!videoStream) {
return false;
}
if (videoStream.Width && videoStream.Width > codecLimits.maxWidth) {
return false;
}
if (mediaSource.VideoType != 'VideoFile') {
return false;
}
return mediaSource.Protocol == 'File';
}
throw new Error('Unrecognized MediaType');
}
function canPlayAudioStreamDirect(audioStream, isVideo, maxBitrate) {
var audioCodec = (audioStream.Codec || '').toLowerCase().replace('-', '');
if (audioCodec.indexOf('aac') == -1 &&
audioCodec.indexOf('mp3') == -1 &&
audioCodec.indexOf('mpeg') == -1) {
return false;
}
var codecLimits = getCodecLimits(maxBitrate);
var maxChannels = isVideo ? codecLimits.maxVideoAudioChannels : codecLimits.maxAudioChannels;
if (!audioStream.Channels || audioStream.Channels > maxChannels) {
return false;
}
if (!audioStream.SampleRate || audioStream.SampleRate > codecLimits.maxSampleRate) {
return false;
}
var bitrate = audioStream.BitRate;
if (!bitrate) {
return false;
}
if (isVideo) {
if (audioCodec.indexOf('aac') != -1 && bitrate > 768000) {
return false;
}
if (audioCodec.indexOf('mp3') != -1 || audioCodec.indexOf('mpeg') != -1) {
if (bitrate > 320000) {
return false;
}
}
} else {
if (bitrate > 320000) {
return false;
}
}
return true; return true;
} }
function isSupportedCodec(mediaType, mediaSource) { function getOptimalMediaSource(mediaType, versions) {
if (mediaType == "Audio") { var optimalVersion = versions.filter(function (v) {
return false;
}
else if (mediaType == "Video") {
return mediaSource.MediaStreams.filter(function (m) { v.enableDirectPlay = MediaController.supportsDirectPlay(v);
return m.Type == "Video" && (m.Codec || '').toLowerCase() == 'h264'; return v.enableDirectPlay;
}).length > 0; })[0];
}
throw new Error('Unrecognized MediaType'); if (!optimalVersion) {
} optimalVersion = versions.filter(function (v) {
function getStreamByIndex(streams, type, index) { return v.SupportsDirectStream;
return streams.filter(function (s) {
return s.Type == type && s.Index == index;
})[0]; })[0];
} }
function getMediaSourceInfo(item, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex) { return optimalVersion || versions.filter(function (s) {
return s.SupportsTranscoding;
var sources = item.MediaSources.filter(function (m) {
m.audioStream = mediaSourceId == m.Id && audioStreamIndex != null ?
getStreamByIndex(m.MediaStreams, 'Audio', audioStreamIndex) :
getStreamByIndex(m.MediaStreams, 'Audio', m.DefaultAudioStreamIndex);
if (item.MediaType == "Audio" && !m.audioStream) {
m.audioStream = m.MediaStreams.filter(function (s) {
return s.Type == 'Audio';
})[0]; })[0];
} }
m.subtitleStream = mediaSourceId == m.Id && subtitleStreamIndex != null ? var currentMediaSource;
getStreamByIndex(m.MediaStreams, 'Subtitle', subtitleStreamIndex) : var currentItem;
getStreamByIndex(m.MediaStreams, 'Subtitle', m.DefaultSubtitleStreamIndex); var basePlayerState;
var progressInterval;
return !mediaSourceId || m.Id == mediaSourceId; function getVideoStreamInfo(item) {
var deferred = $.Deferred();
Dashboard.showModalLoadingMsg();
var deviceProfile = getDeviceProfile();
var startPosition = 0;
MediaController.getPlaybackInfo(item.Id, deviceProfile, startPosition).done(function (playbackInfoResult) {
if (validatePlaybackInfoResult(playbackInfoResult)) {
var mediaSource = getOptimalMediaSource(item.MediaType, playbackInfoResult.MediaSources);
if (mediaSource) {
if (mediaSource.RequiresOpening) {
MediaController.getLiveStream(item.Id, playbackInfoResult.PlaySessionId, deviceProfile, startPosition, mediaSource, null, null).done(function (openLiveStreamResult) {
openLiveStreamResult.MediaSource.enableDirectPlay = MediaController.supportsDirectPlay(openLiveStreamResult.MediaSource);
playInternalPostMediaSourceSelection(item, openLiveStreamResult.MediaSource, startPosition, deferred);
});
} else {
playInternalPostMediaSourceSelection(item, mediaSource, startPosition, deferred);
}
} else {
Dashboard.hideModalLoadingMsg();
MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream');
}
}
}); });
// Find first one that can be direct streamed return deferred.promise();
var source = sources.filter(function (m) {
var audioStream = m.audioStream;
if (!audioStream || !canPlayAudioStreamDirect(audioStream, item.MediaType == 'Video', maxBitrate)) {
return false;
} }
if (m.subtitleStream && m.subtitleStream.IsExternal) { function playInternalPostMediaSourceSelection(item, mediaSource, startPosition, deferred) {
return false;
Dashboard.hideModalLoadingMsg();
currentItem = item;
currentMediaSource = mediaSource;
basePlayerState = {
PlayState: {
} }
return canDirectStream(item.MediaType, m, maxBitrate, audioStream);
})[0];
if (source) {
return {
mediaSource: source,
isStatic: true,
streamContainer: source.Container
}; };
var streamInfo = MediaPlayer.createStreamInfo('Video', item, mediaSource, startPosition);
var currentSrc = streamInfo.url;
var audioStreamIndex = getParameterByName('AudioStreamIndex', currentSrc);
if (audioStreamIndex) {
basePlayerState.PlayState.AudioStreamIndex = parseInt(audioStreamIndex);
}
basePlayerState.PlayState.SubtitleStreamIndex = self.currentSubtitleStreamIndex;
basePlayerState.PlayState.PlayMethod = getParameterByName('static', currentSrc) == 'true' ?
'DirectStream' :
'Transcode';
basePlayerState.PlayState.LiveStreamId = getParameterByName('LiveStreamId', currentSrc);
basePlayerState.PlayState.PlaySessionId = getParameterByName('PlaySessionId', currentSrc);
basePlayerState.PlayState.MediaSourceId = mediaSource.Id;
basePlayerState.PlayState.CanSeek = false;
basePlayerState.NowPlayingItem = MediaPlayer.getNowPlayingItemForReporting(item, mediaSource);
deferred.resolveWith(null, [streamInfo]);
} }
// Find first one with supported codec function getPlayerState(positionTicks) {
source = sources.filter(function (m) {
return isSupportedCodec(item.MediaType, m); var state = basePlayerState;
})[0]; state.PlayState.PositionTicks = positionTicks;
source = source || sources[0]; return state;
}
var container = item.MediaType == 'Audio' ? 'mp3' : 'm3u8'; function onPlaybackStart() {
// Default to first one closePlayMenu();
return {
mediaSource: source, var state = getPlayerState();
isStatic: false,
streamContainer: container var info = {
ItemId: state.NowPlayingItem.Id,
NowPlayingItem: state.NowPlayingItem
}; };
info = $.extend(info, state.PlayState);
ApiClient.reportPlaybackStart(info);
// This is really just a ping to let the server know we're still playing
progressInterval = setInterval(function () {
onPlaybackProgress(null);
}, 10000);
setTimeout(function () {
showPostPlayMenu(currentItem);
}, 500);
} }
function getStreamInfo(serverAddress, deviceId, item, startPositionTicks, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex) { function onPlaybackProgress(positionTicks) {
var mediaSourceInfo = getMediaSourceInfo(item, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex); var state = getPlayerState(positionTicks);
var url = getStreamUrl(serverAddress, deviceId, item.MediaType, item.Id, mediaSourceInfo, startPositionTicks, maxBitrate); var info = {
ItemId: state.NowPlayingItem.Id,
NowPlayingItem: state.NowPlayingItem
};
if (mediaSourceInfo.subtitleStream && mediaSourceInfo.subtitleStream.IsExternal) { info = $.extend(info, state.PlayState);
url += "&SubtitleStreamIndex=" + mediaSourceInfo.Index;
ApiClient.reportPlaybackProgress(info);
} }
mediaSourceInfo.url = url; function onPlaybackStopped(positionTicks) {
return mediaSourceInfo; var state = getPlayerState(positionTicks);
var stopInfo = {
itemId: state.NowPlayingItem.Id,
mediaSourceId: state.PlayState.MediaSourceId,
positionTicks: state.PlayState.PositionTicks
};
if (state.PlayState.LiveStreamId) {
stopInfo.LiveStreamId = state.PlayState.LiveStreamId;
} }
function getStreamUrl(serverAddress, deviceId, mediaType, itemId, mediaSourceInfo, startPositionTicks, maxBitrate) { if (state.PlayState.PlaySessionId) {
stopInfo.PlaySessionId = state.PlayState.PlaySessionId;
var url;
var codecLimits = getCodecLimits(maxBitrate);
if (mediaType == 'Audio') {
url = serverAddress + '/audio/' + itemId + '/stream.' + mediaSourceInfo.streamContainer;
url += '?mediasourceid=' + mediaSourceInfo.mediaSource.Id;
if (mediaSourceInfo.isStatic) {
url += '&static=true';
} else {
url += '&maxaudiochannels=' + codecLimits.maxAudioChannels;
if (startPositionTicks) {
url += '&startTimeTicks=' + startPositionTicks.toString();
} }
if (maxBitrate) { ApiClient.reportPlaybackStopped(stopInfo);
url += '&audiobitrate=' + Math.min(maxBitrate, 320000).toString();
if (progressInterval) {
clearInterval(progressInterval);
progressInterval = null;
}
} }
url += '&deviceId=' + deviceId; function showPostPlayMenu(item) {
}
return url;
}
else if (mediaType == 'Video') {
if (mediaSourceInfo.isStatic) {
url = serverAddress + '/videos/' + itemId + '/stream.' + mediaSourceInfo.streamContainer + '?static=true';
}
else {
url = serverAddress + '/videos/' + itemId + '/stream.' + mediaSourceInfo.streamContainer + '?static=false';
}
url += '&maxaudiochannels=' + codecLimits.maxVideoAudioChannels;
if (maxBitrate) {
var audioRate = 320000;
url += '&audiobitrate=' + audioRate.toString();
url += '&videobitrate=' + (maxBitrate - audioRate).toString();
}
url += '&profile=high';
url += '&level=41';
url += '&maxwidth=' + codecLimits.maxWidth;
url += '&videoCodec=h264';
url += '&audioCodec=aac';
url += '&mediasourceid=' + mediaSourceInfo.mediaSource.Id;
url += '&deviceId=' + deviceId;
return url;
}
throw new Error('Unrecognized MediaType');
}
function getVideoUrl(item) {
var maxBitrate = AppSettings.maxStreamingBitrate();
var info = getStreamInfo(ApiClient.serverAddress(), ApiClient.deviceId(), item, null, maxBitrate);
return info.url;
}
function getPlayerUrl(item, player) {
return player.scheme.replace('{0}', getVideoUrl(item));
}
function showPostPlayMenu(item, userId) {
$('.externalPlayerPostPlayFlyout').popup("close").remove(); $('.externalPlayerPostPlayFlyout').popup("close").remove();
@ -379,23 +365,24 @@
$('.externalPlayerPostPlayFlyout').popup("close").remove(); $('.externalPlayerPostPlayFlyout').popup("close").remove();
ApiClient.stopActiveEncodings(); var position = 0;
if ($('#radioMarkInProgress', elem).checked()) { if ($('#radioMarkInProgress', elem).checked()) {
var pct = $(".playstateSlider", elem).val(); var pct = $(".playstateSlider", elem).val();
var ticks = item.RunTimeTicks * (Number(pct) * .01); var ticks = item.RunTimeTicks * (Number(pct) * .01);
ApiClient.markPlayed(userId, item.Id, new Date()); position = ticks;
} }
else if (autoMarkWatched || $('#radioMarkWatched', elem).checked()) { else if (autoMarkWatched || $('#radioMarkWatched', elem).checked()) {
ApiClient.markPlayed(userId, item.Id, new Date()); position = currentMediaSource.RunTimeTicks;
} }
else if ($('#radioMarkUnwatched', elem).checked()) { else if ($('#radioMarkUnwatched', elem).checked()) {
ApiClient.markUnplayed(userId, item.Id); position = 0;
} }
onPlaybackStopped(position);
}); });
$(".playstateSlider", elem).on("change", function (e) { $(".playstateSlider", elem).on("change", function (e) {
@ -417,11 +404,11 @@
$('.externalPlayerFlyout').popup("close").remove(); $('.externalPlayerFlyout').popup("close").remove();
} }
function showMenuForItem(item, userId) { function showMenuForItem(item, players) {
closePlayMenu(); closePlayMenu();
var html = '<div data-role="popup" class="externalPlayerFlyout" data-theme="a">'; var html = '<div data-role="popup" class="externalPlayerFlyout" data-theme="a" data-dismissible="false">';
html += '<ul data-role="listview" style="min-width: 200px;">'; html += '<ul data-role="listview" style="min-width: 200px;">';
html += '<li data-role="list-divider" style="padding: 1em;text-align:center;">' + Globalize.translate('HeaderSelectExternalPlayer') + '</li>'; html += '<li data-role="list-divider" style="padding: 1em;text-align:center;">' + Globalize.translate('HeaderSelectExternalPlayer') + '</li>';
@ -429,9 +416,9 @@
html += '<div style="padding:1em;">'; html += '<div style="padding:1em;">';
html += getExternalPlayers().map(function (p) { html += players.map(function (p) {
return '<a href="' + getPlayerUrl(item, p) + '" data-role="button" data-icon="play" class="btnExternalPlayer">' + p.name + '</a>'; return '<a href="' + p.url + '" data-role="button" data-icon="play" class="btnExternalPlayer" data-theme="b" data-mini="true">' + p.name + '</a>';
}).join(''); }).join('');
@ -449,12 +436,7 @@
$('.btnExternalPlayer', elem).on('click', function () { $('.btnExternalPlayer', elem).on('click', function () {
closePlayMenu(); ExternalPlayer.onPlaybackStart();
setTimeout(function () {
showPostPlayMenu(item, userId);
}, 500);
}); });
} }
@ -464,18 +446,41 @@
ApiClient.getItem(userId, itemId).done(function (item) { ApiClient.getItem(userId, itemId).done(function (item) {
setTimeout(function () { getVideoStreamInfo(item).done(function (streamInfo) {
showMenuForItem(item, userId); setTimeout(function () {
ExternalPlayer.showPlayerSelectionMenu(item, streamInfo.url, streamInfo.mimeType);
}, 500); }, 500);
}); });
});
}
function getExternalPlayers(url, mimeType) {
var deferred = $.Deferred();
var players = [
{ name: 'Vlc', url: 'vlc://' + url, id: 'vlc' }
];
deferred.resolveWith(null, [players]);
return deferred.promise();
}
function showPlayerSelectionMenu(item, url, mimeType) {
ExternalPlayer.getExternalPlayers(url, mimeType).done(function (players) {
showMenuForItem(item, players);
});
} }
window.ExternalPlayer = { window.ExternalPlayer = {
getUrl: getUrl, showMenu: showPlayMenu,
onPlaybackStart: onPlaybackStart,
onPlaybackStopped: onPlaybackStopped,
getExternalPlayers: getExternalPlayers, getExternalPlayers: getExternalPlayers,
showMenu: showPlayMenu showPlayerSelectionMenu: showPlayerSelectionMenu
}; };
})(window, window.appStorage); })(window, window.appStorage);

View file

@ -177,8 +177,7 @@
html += '</div>'; html += '</div>';
} }
$(elem).html(html).lazyChildren(); $(elem).html(html).lazyChildren().createCardMenus();
$(elem).createCardMenus();
}); });
} }
@ -213,8 +212,7 @@
html += '</div>'; html += '</div>';
} }
$(elem).html(html).lazyChildren(); $(elem).html(html).lazyChildren().createCardMenus();
$(elem).createCardMenus();
}); });
} }
@ -316,8 +314,7 @@
html += '</div>'; html += '</div>';
} }
$(elem).html(html).lazyChildren(); $(elem).html(html).lazyChildren().createCardMenus();
$(elem).createCardMenus();
}); });
} }
@ -406,8 +403,7 @@
}); });
html += '</div>'; html += '</div>';
var elem = $('#channel' + channel.Id + '', page).html(html).lazyChildren().trigger('create'); $('#channel' + channel.Id + '', page).html(html).lazyChildren().trigger('create').createCardMenus();
$(elem).createCardMenus();
}); });
} }

View file

@ -232,13 +232,20 @@
return html; return html;
}, },
playInExternalPlayer: function(id) {
Dashboard.loadExternalPlayer().done(function () {
ExternalPlayer.showMenu(id);
});
},
showPlayMenu: function (positionTo, itemId, itemType, isFolder, mediaType, resumePositionTicks, showAddToPlaylist) { showPlayMenu: function (positionTo, itemId, itemType, isFolder, mediaType, resumePositionTicks, showAddToPlaylist) {
var externalPlayers = ExternalPlayer.getExternalPlayers(); var externalPlayers = AppSettings.enableExternalPlayers();
if (!resumePositionTicks && mediaType != "Audio" && !isFolder) { if (!resumePositionTicks && mediaType != "Audio" && !isFolder) {
if (!externalPlayers.length || mediaType != "Video") { if (!externalPlayers || mediaType != "Video") {
MediaController.play(itemId); MediaController.play(itemId);
return; return;
} }
@ -253,8 +260,8 @@
html += '<li><a href="#" onclick="MediaController.play(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">' + Globalize.translate('ButtonPlay') + '</a></li>'; html += '<li><a href="#" onclick="MediaController.play(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">' + Globalize.translate('ButtonPlay') + '</a></li>';
if (!isFolder && externalPlayers.length) { if (!isFolder && externalPlayers) {
html += '<li><a href="#" onclick="LibraryBrowser.closePlayMenu();ExternalPlayer.showMenu(\'' + itemId + '\');">' + Globalize.translate('ButtonPlayExternalPlayer') + '</a></li>'; html += '<li><a href="#" onclick="LibraryBrowser.closePlayMenu();LibraryBrowser.playInExternalPlayer(\'' + itemId + '\');">' + Globalize.translate('ButtonPlayExternalPlayer') + '</a></li>';
} }
if (resumePositionTicks) { if (resumePositionTicks) {

View file

@ -284,7 +284,7 @@
var id = this.getAttribute('data-itemid'); var id = this.getAttribute('data-itemid');
ExternalPlayer.showMenu(id); LibraryBrowser.playInExternalPlayer(id);
return false; return false;
} }
@ -420,7 +420,7 @@
} }
} }
if (mediaType == 'Video' && ExternalPlayer.getExternalPlayers().length) { if (mediaType == 'Video' && AppSettings.enableExternalPlayers()) {
html += '<li data-icon="play"><a href="#" class="btnExternalPlayer" data-itemid="' + itemId + '">' + Globalize.translate('ButtonPlayExternalPlayer') + '</a></li>'; html += '<li data-icon="play"><a href="#" class="btnExternalPlayer" data-itemid="' + itemId + '">' + Globalize.translate('ButtonPlayExternalPlayer') + '</a></li>';
} }

View file

@ -30,13 +30,14 @@
html += '<button id="btnCast" class="btnCast btnDefaultCast headerButton headerButtonRight" type="button" data-role="none" style="display:none;"><div class="headerSelectedPlayer"></div><div class="btnCastImage"></div></button>'; html += '<button id="btnCast" class="btnCast btnDefaultCast headerButton headerButtonRight" type="button" data-role="none" style="display:none;"><div class="headerSelectedPlayer"></div><div class="btnCastImage"></div></button>';
} }
html += '<button onclick="Search.showSearchPanel($.mobile.activePage);" type="button" data-role="none" class="headerButton headerButtonRight headerSearchButton" style="display:none;"><div class="fa fa-search" style="font-size:21px;"></div></button>'; html += '<button onclick="Search.showSearchPanel();" type="button" data-role="none" class="headerButton headerButtonRight headerSearchButton" style="display:none;"><div class="fa fa-search" style="font-size:21px;"></div></button>';
html += '<div class="viewMenuSearch hide">';
html += '<div class="viewMenuSearch hide"><form class="viewMenuSearchForm">'; html += '<form class="viewMenuSearchForm">';
html += '<input type="text" data-role="none" data-type="search" class="headerSearchInput" autocomplete="off" spellcheck="off" />'; html += '<input type="text" data-role="none" data-type="search" class="headerSearchInput" autocomplete="off" spellcheck="off" />';
html += '<div class="searchInputIcon fa fa-search"></div>'; html += '<div class="searchInputIcon fa fa-search"></div>';
html += '<button data-role="none" type="button" data-iconpos="notext" class="imageButton btnCloseSearch"><i class="fa fa-close"></i></button>'; html += '<button data-role="none" type="button" data-iconpos="notext" class="imageButton btnCloseSearch"><i class="fa fa-close"></i></button>';
html += '</form></div>'; html += '</form>';
html += '</div>';
html += '<button class="headerButton headerButtonRight headerUserButton" type="button" data-role="none" onclick="Dashboard.showUserFlyout(this);">'; html += '<button class="headerButton headerButtonRight headerUserButton" type="button" data-role="none" onclick="Dashboard.showUserFlyout(this);">';
@ -50,8 +51,8 @@
html += '</div>'; html += '</div>';
$(document.body).prepend(html); $(document.body).append(html);
$('.viewMenuBar').trigger('create').lazyChildren(); $('.viewMenuBar').lazyChildren();
$(document).trigger('headercreated'); $(document).trigger('headercreated');
bindMenuEvents(); bindMenuEvents();
@ -100,18 +101,21 @@
if (AppInfo.isTouchPreferred) { if (AppInfo.isTouchPreferred) {
$('.libraryMenuButton').on('click', function () { $('.libraryMenuButton').on('click', showLibraryMenu);
showLibraryMenu(false); $('.dashboardMenuButton').on('click', showDashboardMenu);
});
$('.dashboardMenuButton').on('click', function () {
showDashboardMenu(false);
});
} else { } else {
$('.libraryMenuButton').createHoverTouch().on('hovertouch', showLibraryMenu); $('.libraryMenuButton').createHoverTouch().on('hovertouch', showLibraryMenu);
$('.dashboardMenuButton').createHoverTouch().on('hovertouch', showDashboardMenu); $('.dashboardMenuButton').createHoverTouch().on('hovertouch', showDashboardMenu);
} }
// Have to wait for document ready here because otherwise
// we may see the jQM redirect back and forth problem
$(initViewMenuBarHeadroom);
}
function initViewMenuBarHeadroom() {
// grab an element // grab an element
var viewMenuBar = document.getElementsByClassName("viewMenuBar")[0]; var viewMenuBar = document.getElementsByClassName("viewMenuBar")[0];
initHeadRoom(viewMenuBar); initHeadRoom(viewMenuBar);
@ -478,19 +482,16 @@
function updateContextText(page) { function updateContextText(page) {
var name = $(page)[0].getAttribute('data-contextname'); var jPage = $(page);
var name = jPage.attr('data-contextname');
if (name) { if (name) {
$('.libraryMenuButtonText').html('<span>' + name + '</span>'); $('.libraryMenuButtonText').html('<span>' + name + '</span>');
} }
//else if ($(page).hasClass('type-interior')) { else if (jPage.hasClass('allLibraryPage') || jPage.hasClass('type-interior')) {
// $('.libraryMenuButtonText').html('<span>' + 'Dashboard' + '</span>');
//}
else if ($(page).hasClass('allLibraryPage') || $(page).hasClass('type-interior')) {
$('.libraryMenuButtonText').html('<span class="logoLibraryMenuButtonText">EMBY</span>'); $('.libraryMenuButtonText').html('<span class="logoLibraryMenuButtonText">EMBY</span>');
} }
} }
@ -511,7 +512,7 @@
function buildViewMenuBar(page) { function buildViewMenuBar(page) {
if ($(page).hasClass('standalonePage')) { if ($(page).hasClass('standalonePage')) {
$('.viewMenuBar').remove(); $('.viewMenuBar').hide();
return; return;
} }
@ -519,7 +520,7 @@
$('.viewMenuBar').remove(); $('.viewMenuBar').remove();
} }
var viewMenuBar = $('.viewMenuBar'); var viewMenuBar = $('.viewMenuBar').show();
if (!$('.viewMenuBar').length) { if (!$('.viewMenuBar').length) {
renderHeader(); renderHeader();
@ -539,24 +540,55 @@
updateViewMenuBarHeadroom(page, viewMenuBar); updateViewMenuBarHeadroom(page, viewMenuBar);
requiresViewMenuRefresh = false; requiresViewMenuRefresh = false;
} }
} }
// The first time we create the view menu bar, wait until doc ready + login validated
// Otherwise we run into the jQM redirect back and forth problem
var updateViewMenuBarBeforePageShow = false;
$(document).on('pageinit', ".page", function () { $(document).on('pageinit', ".page", function () {
var page = this; var page = this;
$('.libraryViewNav', page).wrapInner('<div class="libraryViewNavInner"></div>'); $(function () {
onPageInitDocumentReady(page);
$('.libraryViewNav a', page).each(function () {
this.innerHTML = '<span class="libraryViewNavLinkContent">' + this.innerHTML + '</span>';
}); });
}).on('pagebeforeshowready', ".page", function () { }).on('pagebeforeshowready', ".page", function () {
var page = this; var page = this;
if (updateViewMenuBarBeforePageShow) {
onPageBeforeShowDocumentReady(page);
}
}).one('pageshowready', ".page", function () {
var page = this;
$(function () {
onPageBeforeShowDocumentReady(page);
updateViewMenuBarBeforePageShow = true;
});
}).on('pageshowready', ".page", function () {
var page = this;
onPageShowDocumentReady(page);
});
function onPageInitDocumentReady(page) {
$('.libraryViewNav', page).wrapInner('<div class="libraryViewNavInner"></div>');
$('.libraryViewNav a', page).each(function () {
this.innerHTML = '<span class="libraryViewNavLinkContent">' + this.innerHTML + '</span>';
});
}
function onPageBeforeShowDocumentReady(page) {
buildViewMenuBar(page); buildViewMenuBar(page);
var jpage = $(page); var jpage = $(page);
@ -587,11 +619,9 @@
} else { } else {
$(document.body).removeClass('dashboardDocument').removeClass('libraryDocument'); $(document.body).removeClass('dashboardDocument').removeClass('libraryDocument');
} }
}
}).on('pageshow', ".libraryPage", function () { function onPageShowDocumentReady(page) {
var page = this;
var elem = $('.libraryViewNavInner .ui-btn-active:visible', page); var elem = $('.libraryViewNavInner .ui-btn-active:visible', page);
if (elem.length) { if (elem.length) {
@ -600,7 +630,7 @@
// Scroll back up so in case vertical scroll was messed with // Scroll back up so in case vertical scroll was messed with
$(document).scrollTop(0); $(document).scrollTop(0);
} }
}); }
function initHeadRoom(elem) { function initHeadRoom(elem) {

View file

@ -229,7 +229,7 @@
self.play = function (options) { self.play = function (options) {
doWithPlaybackValidation(function() { doWithPlaybackValidation(function () {
if (typeof (options) === 'string') { if (typeof (options) === 'string') {
options = { ids: [options] }; options = { ids: [options] };
} }
@ -480,6 +480,82 @@
}, 300); }, 300);
}; };
self.getPlaybackInfo = function (itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId) {
var postData = {
DeviceProfile: deviceProfile
};
var query = {
UserId: Dashboard.getCurrentUserId(),
StartTimeTicks: startPosition || 0
};
if (audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex;
}
if (subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex;
}
if (mediaSource) {
query.MediaSourceId = mediaSource.Id;
}
if (liveStreamId) {
query.LiveStreamId = liveStreamId;
}
return ApiClient.ajax({
url: ApiClient.getUrl('Items/' + itemId + '/PlaybackInfo', query),
type: 'POST',
data: JSON.stringify(postData),
contentType: "application/json",
dataType: "json"
});
}
self.getLiveStream = function (itemId, playSessionId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) {
var postData = {
DeviceProfile: deviceProfile,
OpenToken: mediaSource.OpenToken
};
var query = {
UserId: Dashboard.getCurrentUserId(),
StartTimeTicks: startPosition || 0,
ItemId: itemId,
PlaySessionId: playSessionId
};
if (audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex;
}
if (subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex;
}
return ApiClient.ajax({
url: ApiClient.getUrl('LiveStreams/Open', query),
type: 'POST',
data: JSON.stringify(postData),
contentType: "application/json",
dataType: "json"
});
};
self.supportsDirectPlay = function (mediaSource) {
if (mediaSource.SupportsDirectPlay && mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) {
// TODO: Need to verify the host is going to be reachable
return true;
}
return false;
};
} }
window.MediaController = new mediaController(); window.MediaController = new mediaController();

View file

@ -605,10 +605,11 @@
}); });
}); });
var idleHandlerTimeout;
function idleHandler() { function idleHandler() {
if (timeout) { if (idleHandlerTimeout) {
window.clearTimeout(timeout); window.clearTimeout(idleHandlerTimeout);
} }
if (idleState == true) { if (idleState == true) {
@ -618,7 +619,7 @@
idleState = false; idleState = false;
timeout = window.setTimeout(function () { idleHandlerTimeout = window.setTimeout(function () {
idleState = true; idleState = true;
$('.hiddenOnIdle').addClass("inactive"); $('.hiddenOnIdle').addClass("inactive");
$('#videoPlayer').addClass('idlePlayer'); $('#videoPlayer').addClass('idlePlayer');
@ -978,11 +979,10 @@
function bindEventsForPlayback() { function bindEventsForPlayback() {
var hideElementsOnIdle = !$.browser.mobile; var hideElementsOnIdle = true;
if (hideElementsOnIdle) { if (hideElementsOnIdle) {
$('.itemVideo').off('mousemove.videoplayer keydown.videoplayer scroll.videoplayer', idleHandler); $('.itemVideo').off('mousemove.videoplayer keydown.videoplayer scroll.videoplayer mousedown.videoplayer', idleHandler).on('mousemove.videoplayer keydown.videoplayer scroll.videoplayer mousedown.videoplayer', idleHandler).trigger('mousemove');
$('.itemVideo').on('mousemove.videoplayer keydown.videoplayer scroll.videoplayer', idleHandler).trigger('mousemove');
} }
$(document).on('webkitfullscreenchange.videoplayer mozfullscreenchange.videoplayer msfullscreenchange.videoplayer fullscreenchange.videoplayer', function (e) { $(document).on('webkitfullscreenchange.videoplayer mozfullscreenchange.videoplayer msfullscreenchange.videoplayer fullscreenchange.videoplayer', function (e) {
@ -1012,14 +1012,14 @@
function unbindEventsForPlayback() { function unbindEventsForPlayback() {
$(document).off('webkitfullscreenchange.videoplayer mozfullscreenchange.videoplayer msfullscreenchange.videoplayer fullscreenchange.videoplayer'); $(document).off('.videoplayer');
// Stop playback on browser back button nav // Stop playback on browser back button nav
$(window).off("popstate.videoplayer"); $(window).off("popstate.videoplayer");
$(document.body).off("mousemove.videoplayer"); $(document.body).off("mousemove.videoplayer");
$('.itemVideo').off('mousemove.videoplayer keydown.videoplayer scroll.videoplayer'); $('.itemVideo').off('mousemove.videoplayer keydown.videoplayer scroll.videoplayer mousedown.videoplayer');
} }
self.canAutoPlayVideo = function () { self.canAutoPlayVideo = function () {
@ -1084,7 +1084,7 @@
self.playVideoInternal = function (item, mediaSource, startPosition, streamInfo) { self.playVideoInternal = function (item, mediaSource, startPosition, streamInfo) {
var videoUrl = streamInfo.url; var videoUrl = streamInfo.url;
var contentType = streamInfo.contentType; var contentType = streamInfo.mimeType;
var startPositionInSeekParam = streamInfo.startPositionInSeekParam; var startPositionInSeekParam = streamInfo.startPositionInSeekParam;
self.startTimeTicksOffset = streamInfo.startTimeTicksOffset; self.startTimeTicksOffset = streamInfo.startTimeTicksOffset;
@ -1296,7 +1296,6 @@
}).on("dblclick.mediaplayerevent", function () { }).on("dblclick.mediaplayerevent", function () {
self.toggleFullscreen(); self.toggleFullscreen();
}); });
bindEventsForPlayback(); bindEventsForPlayback();

View file

@ -183,7 +183,7 @@
Protocol: 'hls' Protocol: 'hls'
}); });
if (canPlayAac) { if (canPlayAac && $.browser.safari) {
profile.TranscodingProfiles.push({ profile.TranscodingProfiles.push({
Container: 'aac', Container: 'aac',
Type: 'Audio', Type: 'Audio',
@ -471,7 +471,7 @@
subtitleStreamIndex = parseInt(subtitleStreamIndex); subtitleStreamIndex = parseInt(subtitleStreamIndex);
} }
getPlaybackInfo(self.currentItem.Id, deviceProfile, ticks, self.currentMediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId).done(function (result) { MediaController.getPlaybackInfo(self.currentItem.Id, deviceProfile, ticks, self.currentMediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId).done(function (result) {
if (validatePlaybackInfoResult(result)) { if (validatePlaybackInfoResult(result)) {
@ -685,22 +685,11 @@
}); });
}; };
function supportsDirectPlay(mediaSource) {
if (mediaSource.SupportsDirectPlay && mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) {
// TODO: Need to verify the host is going to be reachable
return true;
}
return false;
}
function getOptimalMediaSource(mediaType, versions) { function getOptimalMediaSource(mediaType, versions) {
var optimalVersion = versions.filter(function (v) { var optimalVersion = versions.filter(function (v) {
v.enableDirectPlay = supportsDirectPlay(v); v.enableDirectPlay = MediaController.supportsDirectPlay(v);
return v.enableDirectPlay; return v.enableDirectPlay;
@ -719,71 +708,6 @@
})[0]; })[0];
} }
function getPlaybackInfo(itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId) {
var postData = {
DeviceProfile: deviceProfile
};
var query = {
UserId: Dashboard.getCurrentUserId(),
StartTimeTicks: startPosition || 0
};
if (audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex;
}
if (subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex;
}
if (mediaSource) {
query.MediaSourceId = mediaSource.Id;
}
if (liveStreamId) {
query.LiveStreamId = liveStreamId;
}
return ApiClient.ajax({
url: ApiClient.getUrl('Items/' + itemId + '/PlaybackInfo', query),
type: 'POST',
data: JSON.stringify(postData),
contentType: "application/json",
dataType: "json"
});
}
function getLiveStream(itemId, playSessionId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) {
var postData = {
DeviceProfile: deviceProfile,
OpenToken: mediaSource.OpenToken
};
var query = {
UserId: Dashboard.getCurrentUserId(),
StartTimeTicks: startPosition || 0,
ItemId: itemId,
PlaySessionId: playSessionId
};
if (audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex;
}
if (subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex;
}
return ApiClient.ajax({
url: ApiClient.getUrl('LiveStreams/Open', query),
type: 'POST',
data: JSON.stringify(postData),
contentType: "application/json",
dataType: "json"
});
}
self.createStreamInfo = function (type, item, mediaSource, startPosition) { self.createStreamInfo = function (type, item, mediaSource, startPosition) {
var mediaUrl; var mediaUrl;
@ -867,7 +791,7 @@
return { return {
url: mediaUrl, url: mediaUrl,
contentType: contentType, mimeType: contentType,
startTimeTicksOffset: startTimeTicksOffset, startTimeTicksOffset: startTimeTicksOffset,
startPositionInSeekParam: startPositionInSeekParam, startPositionInSeekParam: startPositionInSeekParam,
playMethod: playMethod playMethod: playMethod
@ -900,7 +824,7 @@
Dashboard.showModalLoadingMsg(); Dashboard.showModalLoadingMsg();
} }
getPlaybackInfo(item.Id, deviceProfile, startPosition).done(function (playbackInfoResult) { MediaController.getPlaybackInfo(item.Id, deviceProfile, startPosition).done(function (playbackInfoResult) {
if (validatePlaybackInfoResult(playbackInfoResult)) { if (validatePlaybackInfoResult(playbackInfoResult)) {
@ -910,9 +834,9 @@
if (mediaSource.RequiresOpening) { if (mediaSource.RequiresOpening) {
getLiveStream(item.Id, playbackInfoResult.PlaySessionId, deviceProfile, startPosition, mediaSource, null, null).done(function (openLiveStreamResult) { MediaController.getLiveStream(item.Id, playbackInfoResult.PlaySessionId, deviceProfile, startPosition, mediaSource, null, null).done(function (openLiveStreamResult) {
openLiveStreamResult.MediaSource.enableDirectPlay = supportsDirectPlay(openLiveStreamResult.MediaSource); openLiveStreamResult.MediaSource.enableDirectPlay = MediaController.supportsDirectPlay(openLiveStreamResult.MediaSource);
playInternalPostMediaSourceSelection(item, openLiveStreamResult.MediaSource, startPosition, callback); playInternalPostMediaSourceSelection(item, openLiveStreamResult.MediaSource, startPosition, callback);
}); });
@ -1474,8 +1398,17 @@
if (item) { if (item) {
state.NowPlayingItem = state.NowPlayingItem || {}; state.NowPlayingItem = self.getNowPlayingItemForReporting(item, mediaSource);
var nowPlayingItem = state.NowPlayingItem; }
return state;
};
self.getNowPlayingItemForReporting = function (item, mediaSource) {
var nowPlayingItem = {};
nowPlayingItem.RunTimeTicks = mediaSource.RunTimeTicks;
nowPlayingItem.Id = item.Id; nowPlayingItem.Id = item.Id;
nowPlayingItem.MediaType = item.MediaType; nowPlayingItem.MediaType = item.MediaType;
@ -1540,9 +1473,8 @@
nowPlayingItem.LogoItemId = item.ParentLogoItemId; nowPlayingItem.LogoItemId = item.ParentLogoItemId;
nowPlayingItem.LogoImageTag = item.ParentLogoImageTag; nowPlayingItem.LogoImageTag = item.ParentLogoImageTag;
} }
}
return state; return nowPlayingItem;
}; };
self.beginPlayerUpdates = function () { self.beginPlayerUpdates = function () {

View file

@ -2,21 +2,10 @@
function loadForm(page, userId, displayPreferences) { function loadForm(page, userId, displayPreferences) {
var externalPlayers = JSON.parse(appStorage.getItem('externalplayers') || '[]');
$('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate()).selectmenu("refresh"); $('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate()).selectmenu("refresh");
$('#selectMaxChromecastBitrate', page).val(AppSettings.maxChromecastBitrate()).selectmenu("refresh"); $('#selectMaxChromecastBitrate', page).val(AppSettings.maxChromecastBitrate()).selectmenu("refresh");
$('.chkExternalPlayer', page).each(function () { $('#chkExternalVideoPlayer', page).checked(AppSettings.enableExternalPlayers()).checkboxradio("refresh");
var chk = this;
chk.checked = externalPlayers.filter(function (p) {
return p.name == chk.getAttribute('data-name');
}).length > 0;
}).checkboxradio('refresh');
$('#selectThemeSong', page).val(appStorage.getItem('enableThemeSongs-' + userId) || '').selectmenu("refresh"); $('#selectThemeSong', page).val(appStorage.getItem('enableThemeSongs-' + userId) || '').selectmenu("refresh");
$('#selectBackdrop', page).val(appStorage.getItem('enableBackdrops-' + userId) || '').selectmenu("refresh"); $('#selectBackdrop', page).val(appStorage.getItem('enableBackdrops-' + userId) || '').selectmenu("refresh");
@ -55,16 +44,7 @@
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
var externalPlayers = $('.chkExternalPlayer:checked', page).get().map(function (i) { AppSettings.enableExternalPlayers($('#chkExternalVideoPlayer', page).checked());
return {
name: i.getAttribute('data-name'),
scheme: i.getAttribute('data-scheme')
};
});
appStorage.setItem('externalplayers', JSON.stringify(externalPlayers));
AppSettings.maxStreamingBitrate($('#selectMaxBitrate', page).val()); AppSettings.maxStreamingBitrate($('#selectMaxBitrate', page).val());
AppSettings.maxChromecastBitrate($('#selectMaxChromecastBitrate', page).val()); AppSettings.maxChromecastBitrate($('#selectMaxChromecastBitrate', page).val());
@ -133,6 +113,14 @@
} }
return parseInt(store.getItem('chromecastBitrate') || '') || 3000000; return parseInt(store.getItem('chromecastBitrate') || '') || 3000000;
},
enableExternalPlayers: function (val) {
if (val != null) {
store.setItem('externalplayers', val.toString());
}
return store.getItem('externalplayers') == 'true';
} }
}; };

View file

@ -58,9 +58,11 @@
var self = this; var self = this;
self.showSearchPanel = function (page) { self.showSearchPanel = function () {
$('.viewMenuSearch').removeClass('hide'); var viewMenuSearch = $('.viewMenuSearch');
viewMenuSearch.removeClass('hide');
$('.headerSearchInput').focus(); $('.headerSearchInput').focus();
}; };
} }

View file

@ -191,7 +191,6 @@ var Dashboard = {
} else { } else {
loginPage = 'login.html'; loginPage = 'login.html';
} }
Dashboard.navigate(loginPage); Dashboard.navigate(loginPage);
} }
@ -1491,6 +1490,25 @@ var Dashboard = {
Dashboard.ready(function () { Dashboard.ready(function () {
$(page).trigger(name); $(page).trigger(name);
}); });
},
loadExternalPlayer: function () {
var deferred = DeferredBuilder.Deferred();
require(['scripts/externalplayer.js'], function () {
if (Dashboard.isRunningInCordova()) {
require(['thirdparty/cordova/externalplayer.js'], function () {
deferred.resolve();
});
} else {
deferred.resolve();
}
});
return deferred.promise();
} }
}; };
@ -1560,6 +1578,10 @@ var AppInfo = {};
else { else {
AppInfo.enableFooterNotifications = true; AppInfo.enableFooterNotifications = true;
AppInfo.enableSupporterMembership = true; AppInfo.enableSupporterMembership = true;
if (!$.browser.android && !$.browser.ipad && !$.browser.iphone) {
AppInfo.enableAppLayouts = true;
}
} }
AppInfo.enableUserImage = true; AppInfo.enableUserImage = true;
@ -1576,6 +1598,7 @@ var AppInfo = {};
.on("websocketmessage.dashboard", Dashboard.onWebSocketMessageReceived) .on("websocketmessage.dashboard", Dashboard.onWebSocketMessageReceived)
.on('requestfail.dashboard', Dashboard.onRequestFail); .on('requestfail.dashboard', Dashboard.onRequestFail);
} }
//localStorage.clear(); //localStorage.clear();
function createConnectionManager(appInfo) { function createConnectionManager(appInfo) {
@ -1771,9 +1794,6 @@ var AppInfo = {};
$(document.body).append(footerHtml); $(document.body).append(footerHtml);
var footerElem = $('.footer', document.body);
footerElem.trigger('create');
$(window).on("beforeunload", function () { $(window).on("beforeunload", function () {
var apiClient = window.ApiClient; var apiClient = window.ApiClient;
@ -1928,20 +1948,6 @@ $(document).on('pagecreate', ".page", function () {
$('.localnav a, .libraryViewNav a').attr('data-transition', 'none'); $('.localnav a, .libraryViewNav a').attr('data-transition', 'none');
}).on('pageshow', ".page", function () {
var page = this;
var require = this.getAttribute('data-require');
if (require) {
requirejs(require.split(','), function () {
Dashboard.firePageEvent(page, 'pageshowready');
});
} else {
Dashboard.firePageEvent(page, 'pageshowready');
}
}).on('pagebeforeshow', ".page", function () { }).on('pagebeforeshow', ".page", function () {
var page = this; var page = this;
@ -1956,7 +1962,21 @@ $(document).on('pagecreate', ".page", function () {
Dashboard.firePageEvent(page, 'pagebeforeshowready'); Dashboard.firePageEvent(page, 'pagebeforeshowready');
} }
}).on('pagebeforeshowready', ".page", function () { }).on('pageshow', ".page", function () {
var page = this;
var require = this.getAttribute('data-require');
if (require) {
requirejs(require.split(','), function () {
Dashboard.firePageEvent(page, 'pageshowbeginready');
});
} else {
Dashboard.firePageEvent(page, 'pageshowbeginready');
}
}).on('pageshowbeginready', ".page", function () {
var page = $(this); var page = $(this);
@ -1977,9 +1997,6 @@ $(document).on('pagecreate', ".page", function () {
Dashboard.ensureToolsMenu(page, user); Dashboard.ensureToolsMenu(page, user);
} }
}); });
Dashboard.ensureHeader(page);
Dashboard.ensurePageTitle(page);
} }
else { else {
@ -1989,7 +2006,7 @@ $(document).on('pagecreate', ".page", function () {
if (isConnectMode) { if (isConnectMode) {
if (!Dashboard.isServerlessPage()) { if (!Dashboard.isServerlessPage()) {
Dashboard.logout(true); Dashboard.logout();
return; return;
} }
} }
@ -1997,13 +2014,15 @@ $(document).on('pagecreate', ".page", function () {
if (!isConnectMode && this.id !== "loginPage" && !page.hasClass('forgotPasswordPage') && !page.hasClass('wizardPage')) { if (!isConnectMode && this.id !== "loginPage" && !page.hasClass('forgotPasswordPage') && !page.hasClass('wizardPage')) {
console.log('Not logged into server. Redirecting to login.'); console.log('Not logged into server. Redirecting to login.');
Dashboard.logout(true); Dashboard.logout();
return; return;
} }
}
Dashboard.firePageEvent(page, 'pageshowready');
Dashboard.ensureHeader(page); Dashboard.ensureHeader(page);
Dashboard.ensurePageTitle(page); Dashboard.ensurePageTitle(page);
}
if (apiClient && !apiClient.isWebSocketOpen()) { if (apiClient && !apiClient.isWebSocketOpen()) {
Dashboard.refreshSystemInfoFromServer(); Dashboard.refreshSystemInfoFromServer();

View file

@ -2,11 +2,13 @@
globalScope.AjaxApi = { globalScope.AjaxApi = {
param: function(params) { param: function (params) {
return jQuery.param(params); return jQuery.param(params);
}, },
ajax: function(request) { ajax: function (request) {
request.timeout = request.timeout || 30000;
try { try {
return jQuery.ajax(request); return jQuery.ajax(request);

View file

@ -0,0 +1,50 @@
(function () {
function showPlayerSelectionMenu(item, url, mimeType) {
window.plugins.launcher.launch({
uri: url,
dataType: mimeType
}, function () {
console.log('plugin launch success');
ExternalPlayer.onPlaybackStart();
}, function () {
console.log('plugin launch error');
ExternalPlayer.onPlaybackStart();
});
}
function getExternalPlayers(url, mimeType) {
var deferred = $.Deferred();
window.plugins.launcher.canLaunch({
uri: url,
dataType: mimeType,
getAppList: true
}, function (data) {
console.log('plugin canLaunch succcess');
var players = data.appList.map(function (p) {
});
deferred.resolveWith(null, [players]);
}, function () {
console.log('plugin canLaunch error');
deferred.reject();
});
deferred.resolveWith(null, [players]);
return deferred.promise();
}
window.ExternalPlayer.getExternalPlayers = getExternalPlayers;
window.ExternalPlayer.showPlayerSelectionMenu = showPlayerSelectionMenu;
})();