mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update live tv media sources
This commit is contained in:
parent
4b6692c92d
commit
9336922f29
9 changed files with 440 additions and 11 deletions
|
@ -1574,6 +1574,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
|
||||||
|
|
||||||
.detailsMenuHeaderWithLogo h3 {
|
.detailsMenuHeaderWithLogo h3 {
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
|
line-height: .5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-height:500px) {
|
@media all and (min-height:500px) {
|
||||||
|
|
|
@ -229,8 +229,6 @@
|
||||||
|
|
||||||
$(this).trigger('connect');
|
$(this).trigger('connect');
|
||||||
|
|
||||||
MediaController.setActivePlayer(PlayerName);
|
|
||||||
|
|
||||||
this.sendMessage({
|
this.sendMessage({
|
||||||
options: {},
|
options: {},
|
||||||
command: 'Identify'
|
command: 'Identify'
|
||||||
|
@ -548,6 +546,8 @@
|
||||||
|
|
||||||
$(castPlayer).on("connect", function (e) {
|
$(castPlayer).on("connect", function (e) {
|
||||||
|
|
||||||
|
MediaController.setActivePlayer(PlayerName, self.getCurrentTargetInfo());
|
||||||
|
|
||||||
console.log('cc: connect');
|
console.log('cc: connect');
|
||||||
// Reset this so the next query doesn't make it appear like content is playing.
|
// Reset this so the next query doesn't make it appear like content is playing.
|
||||||
self.lastPlayerData = {};
|
self.lastPlayerData = {};
|
||||||
|
@ -837,6 +837,13 @@
|
||||||
console.log(JSON.stringify(data));
|
console.log(JSON.stringify(data));
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.tryPair = function (target) {
|
||||||
|
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
deferred.resolve();
|
||||||
|
return deferred.promise();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeChromecast() {
|
function initializeChromecast() {
|
||||||
|
|
|
@ -532,7 +532,7 @@
|
||||||
|
|
||||||
html += '<div style="padding:1em 1em;background:rgba(20,20,20,1);margin:0;text-align:center;" class="detailsMenuHeader">';
|
html += '<div style="padding:1em 1em;background:rgba(20,20,20,1);margin:0;text-align:center;" class="detailsMenuHeader">';
|
||||||
html += '<button type="button" class="imageButton detailsMenuLeftButton" data-role="none"><i class="fa fa-arrow-left"></i></button>';
|
html += '<button type="button" class="imageButton detailsMenuLeftButton" data-role="none"><i class="fa fa-arrow-left"></i></button>';
|
||||||
html += '<h3 style="font-weight:400;margin:.5em 0;line-height:.5;"></h3>';
|
html += '<h3 style="font-weight:400;margin:.5em 0;"></h3>';
|
||||||
html += '<button type="button" class="imageButton detailsMenuRightButton" data-role="none"><i class="fa fa-arrow-right"></i></button>';
|
html += '<button type="button" class="imageButton detailsMenuRightButton" data-role="none"><i class="fa fa-arrow-right"></i></button>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
|
|
@ -118,15 +118,42 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
currentPlayer = player;
|
currentPlayer = player;
|
||||||
currentTargetInfo = targetInfo || player.getCurrentTargetInfo();
|
currentTargetInfo = targetInfo;
|
||||||
|
|
||||||
console.log('Active player: ' + JSON.stringify(currentTargetInfo));
|
console.log('Active player: ' + JSON.stringify(currentTargetInfo));
|
||||||
|
|
||||||
$(self).trigger('playerchange');
|
$(self).trigger('playerchange');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.trySetActivePlayer = function (player, targetInfo) {
|
||||||
|
|
||||||
|
if (typeof (player) === 'string') {
|
||||||
|
player = players.filter(function (p) {
|
||||||
|
return p.name == player;
|
||||||
|
})[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player) {
|
||||||
|
throw new Error('null player');
|
||||||
|
}
|
||||||
|
|
||||||
|
player.tryPair(targetInfo).done(function() {
|
||||||
|
|
||||||
|
currentPlayer = player;
|
||||||
|
currentTargetInfo = targetInfo;
|
||||||
|
|
||||||
|
console.log('Active player: ' + JSON.stringify(currentTargetInfo));
|
||||||
|
|
||||||
|
$(self).trigger('playerchange');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
self.setDefaultPlayerActive = function () {
|
self.setDefaultPlayerActive = function () {
|
||||||
self.setActivePlayer(self.getDefaultPlayer());
|
|
||||||
|
var player = self.getDefaultPlayer();
|
||||||
|
var target = player.getTargets()[0];
|
||||||
|
|
||||||
|
self.setActivePlayer(player, target);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.removeActivePlayer = function (name) {
|
self.removeActivePlayer = function (name) {
|
||||||
|
@ -597,7 +624,7 @@
|
||||||
var playableMediaTypes = this.getAttribute('data-mediatypes').split(',');
|
var playableMediaTypes = this.getAttribute('data-mediatypes').split(',');
|
||||||
var supportedCommands = this.getAttribute('data-commands').split(',');
|
var supportedCommands = this.getAttribute('data-commands').split(',');
|
||||||
|
|
||||||
MediaController.setActivePlayer(playerName, {
|
MediaController.trySetActivePlayer(playerName, {
|
||||||
id: targetId,
|
id: targetId,
|
||||||
name: targetName,
|
name: targetName,
|
||||||
playableMediaTypes: playableMediaTypes,
|
playableMediaTypes: playableMediaTypes,
|
||||||
|
|
|
@ -1731,15 +1731,18 @@
|
||||||
|
|
||||||
var getItemFields = "MediaSources,Chapters";
|
var getItemFields = "MediaSources,Chapters";
|
||||||
|
|
||||||
self.getCurrentTargetInfo = function () {
|
self.tryPair = function (target) {
|
||||||
return self.getTargets()[0];
|
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
deferred.resolve();
|
||||||
|
return deferred.promise();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
window.MediaPlayer = new mediaPlayer();
|
window.MediaPlayer = new mediaPlayer();
|
||||||
|
|
||||||
window.MediaController.registerPlayer(window.MediaPlayer);
|
window.MediaController.registerPlayer(window.MediaPlayer);
|
||||||
window.MediaController.setActivePlayer(window.MediaPlayer);
|
window.MediaController.setActivePlayer(window.MediaPlayer, window.MediaPlayer.getTargets()[0]);
|
||||||
|
|
||||||
|
|
||||||
})(document, setTimeout, clearTimeout, screen, window.store, $, setInterval, window);
|
})(document, setTimeout, clearTimeout, screen, window.store, $, setInterval, window);
|
|
@ -276,6 +276,13 @@
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.tryPair = function(target) {
|
||||||
|
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
deferred.resolve();
|
||||||
|
return deferred.promise();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = new remoteControlPlayer();
|
var player = new remoteControlPlayer();
|
||||||
|
|
|
@ -1813,7 +1813,7 @@ var AppInfo = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Dashboard.isRunningInCordova()) {
|
if (Dashboard.isRunningInCordova()) {
|
||||||
requirejs(['thirdparty/cordova/chromecast']);
|
requirejs(['thirdparty/cordova/connectsdk']);
|
||||||
} else {
|
} else {
|
||||||
if ($.browser.chrome) {
|
if ($.browser.chrome) {
|
||||||
requirejs(['scripts/chromecast']);
|
requirejs(['scripts/chromecast']);
|
||||||
|
|
349
dashboard-ui/thirdparty/cordova/chromecast.js
vendored
349
dashboard-ui/thirdparty/cordova/chromecast.js
vendored
|
@ -1 +1,348 @@
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
var PlayerName = "Chromecast";
|
||||||
|
var ApplicationID = "F4EB2E8E";
|
||||||
|
var currentDevice;
|
||||||
|
|
||||||
|
function chromecastPlayer() {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// MediaController needs this
|
||||||
|
self.name = PlayerName;
|
||||||
|
|
||||||
|
self.getItemsForPlayback = function (query) {
|
||||||
|
|
||||||
|
var userId = Dashboard.getCurrentUserId();
|
||||||
|
|
||||||
|
query.Limit = query.Limit || 100;
|
||||||
|
query.ExcludeLocationTypes = "Virtual";
|
||||||
|
|
||||||
|
return ApiClient.getItems(userId, query);
|
||||||
|
};
|
||||||
|
|
||||||
|
var castPlayer = {};
|
||||||
|
|
||||||
|
$(castPlayer).on("connect", function (e) {
|
||||||
|
|
||||||
|
console.log('cc: connect');
|
||||||
|
// Reset this so the next query doesn't make it appear like content is playing.
|
||||||
|
self.lastPlayerData = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
$(castPlayer).on("playbackstart", function (e, data) {
|
||||||
|
|
||||||
|
console.log('cc: playbackstart');
|
||||||
|
|
||||||
|
castPlayer.initializeCastPlayer();
|
||||||
|
|
||||||
|
var state = self.getPlayerStateInternal(data);
|
||||||
|
$(self).trigger("playbackstart", [state]);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(castPlayer).on("playbackstop", function (e, data) {
|
||||||
|
|
||||||
|
console.log('cc: playbackstop');
|
||||||
|
var state = self.getPlayerStateInternal(data);
|
||||||
|
|
||||||
|
$(self).trigger("playbackstop", [state]);
|
||||||
|
|
||||||
|
// Reset this so the next query doesn't make it appear like content is playing.
|
||||||
|
self.lastPlayerData = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
$(castPlayer).on("playbackprogress", function (e, data) {
|
||||||
|
|
||||||
|
console.log('cc: positionchange');
|
||||||
|
var state = self.getPlayerStateInternal(data);
|
||||||
|
|
||||||
|
$(self).trigger("positionchange", [state]);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.play = function (options) {
|
||||||
|
|
||||||
|
Dashboard.getCurrentUser().done(function (user) {
|
||||||
|
|
||||||
|
if (options.items) {
|
||||||
|
|
||||||
|
self.playWithCommand(options, 'PlayNow');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
self.getItemsForPlayback({
|
||||||
|
|
||||||
|
Ids: options.ids.join(',')
|
||||||
|
|
||||||
|
}).done(function (result) {
|
||||||
|
|
||||||
|
options.items = result.Items;
|
||||||
|
self.playWithCommand(options, 'PlayNow');
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.playWithCommand = function (options, command) {
|
||||||
|
|
||||||
|
if (!options.items) {
|
||||||
|
ApiClient.getItem(Dashboard.getCurrentUserId(), options.ids[0]).done(function (item) {
|
||||||
|
|
||||||
|
options.items = [item];
|
||||||
|
self.playWithCommand(options, command);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
castPlayer.loadMedia(options, command);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.unpause = function () {
|
||||||
|
castPlayer.playMedia();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.pause = function () {
|
||||||
|
castPlayer.pauseMedia();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.shuffle = function (id) {
|
||||||
|
|
||||||
|
var userId = Dashboard.getCurrentUserId();
|
||||||
|
|
||||||
|
ApiClient.getItem(userId, id).done(function (item) {
|
||||||
|
|
||||||
|
self.playWithCommand({
|
||||||
|
|
||||||
|
items: [item]
|
||||||
|
|
||||||
|
}, 'Shuffle');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.instantMix = function (id) {
|
||||||
|
|
||||||
|
var userId = Dashboard.getCurrentUserId();
|
||||||
|
|
||||||
|
ApiClient.getItem(userId, id).done(function (item) {
|
||||||
|
|
||||||
|
self.playWithCommand({
|
||||||
|
|
||||||
|
items: [item]
|
||||||
|
|
||||||
|
}, 'InstantMix');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.canQueueMediaType = function (mediaType) {
|
||||||
|
return mediaType == "Audio";
|
||||||
|
};
|
||||||
|
|
||||||
|
self.queue = function (options) {
|
||||||
|
self.playWithCommnd(options, 'PlayLast');
|
||||||
|
};
|
||||||
|
|
||||||
|
self.queueNext = function (options) {
|
||||||
|
self.playWithCommand(options, 'PlayNext');
|
||||||
|
};
|
||||||
|
|
||||||
|
self.stop = function () {
|
||||||
|
castPlayer.stopMedia();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.displayContent = function (options) {
|
||||||
|
|
||||||
|
castPlayer.sendMessage({
|
||||||
|
options: options,
|
||||||
|
command: 'DisplayContent'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.mute = function () {
|
||||||
|
castPlayer.mute();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.unMute = function () {
|
||||||
|
self.setVolume(getCurrentVolume() + 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.toggleMute = function () {
|
||||||
|
|
||||||
|
var state = self.lastPlayerData || {};
|
||||||
|
state = state.PlayState || {};
|
||||||
|
|
||||||
|
if (state.IsMuted) {
|
||||||
|
self.unMute();
|
||||||
|
} else {
|
||||||
|
self.mute();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getBaseTargetInfo() {
|
||||||
|
var target = {};
|
||||||
|
|
||||||
|
target.playerName = PlayerName;
|
||||||
|
target.playableMediaTypes = ["Audio", "Video"];
|
||||||
|
target.isLocalPlayer = false;
|
||||||
|
target.appName = PlayerName;
|
||||||
|
target.supportedCommands = [
|
||||||
|
"VolumeUp",
|
||||||
|
"VolumeDown",
|
||||||
|
"Mute",
|
||||||
|
"Unmute",
|
||||||
|
"ToggleMute",
|
||||||
|
"SetVolume",
|
||||||
|
"SetAudioStreamIndex",
|
||||||
|
"SetSubtitleStreamIndex",
|
||||||
|
"DisplayContent"
|
||||||
|
];
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertDeviceToTarget(device) {
|
||||||
|
|
||||||
|
var target = getBaseTargetInfo();
|
||||||
|
|
||||||
|
target.name = target.deviceName = device.getFriendlyName();
|
||||||
|
target.id = device.getId();
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.getTargets = function () {
|
||||||
|
|
||||||
|
var manager = ConnectSDK.discoveryManager;
|
||||||
|
|
||||||
|
return manager.getDeviceList().map(convertDeviceToTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.seek = function (position) {
|
||||||
|
castPlayer.seekMedia(position);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setAudioStreamIndex = function (index) {
|
||||||
|
castPlayer.sendMessage({
|
||||||
|
options: {
|
||||||
|
index: index
|
||||||
|
},
|
||||||
|
command: 'SetAudioStreamIndex'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setSubtitleStreamIndex = function (index) {
|
||||||
|
castPlayer.sendMessage({
|
||||||
|
options: {
|
||||||
|
index: index
|
||||||
|
},
|
||||||
|
command: 'SetSubtitleStreamIndex'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.nextTrack = function () {
|
||||||
|
castPlayer.sendMessage({
|
||||||
|
options: {},
|
||||||
|
command: 'NextTrack'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.previousTrack = function () {
|
||||||
|
castPlayer.sendMessage({
|
||||||
|
options: {},
|
||||||
|
command: 'PreviousTrack'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.beginPlayerUpdates = function () {
|
||||||
|
// Setup polling here
|
||||||
|
};
|
||||||
|
|
||||||
|
self.endPlayerUpdates = function () {
|
||||||
|
// Stop polling here
|
||||||
|
};
|
||||||
|
|
||||||
|
function getCurrentVolume() {
|
||||||
|
var state = self.lastPlayerData || {};
|
||||||
|
state = state.PlayState || {};
|
||||||
|
|
||||||
|
return state.VolumeLevel == null ? 100 : state.VolumeLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.volumeDown = function () {
|
||||||
|
|
||||||
|
self.setVolume(getCurrentVolume() - 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.volumeUp = function () {
|
||||||
|
|
||||||
|
self.setVolume(getCurrentVolume() + 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setVolume = function (vol) {
|
||||||
|
|
||||||
|
vol = Math.min(vol, 100);
|
||||||
|
vol = Math.max(vol, 0);
|
||||||
|
|
||||||
|
castPlayer.setReceiverVolume(false, (vol / 100));
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getPlayerState = function () {
|
||||||
|
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
|
||||||
|
var result = self.getPlayerStateInternal();
|
||||||
|
|
||||||
|
deferred.resolveWith(null, [result]);
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.lastPlayerData = {};
|
||||||
|
|
||||||
|
self.getPlayerStateInternal = function (data) {
|
||||||
|
|
||||||
|
data = data || self.lastPlayerData;
|
||||||
|
self.lastPlayerData = data;
|
||||||
|
|
||||||
|
console.log(JSON.stringify(data));
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.tryPair = function (target) {
|
||||||
|
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
deferred.resolve();
|
||||||
|
return deferred.promise();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeviceLost() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSdk() {
|
||||||
|
|
||||||
|
var manager = ConnectSDK.discoveryManager;
|
||||||
|
|
||||||
|
manager.addListener('devicelost', onDeviceLost);
|
||||||
|
|
||||||
|
MediaController.registerPlayer(new chromecastPlayer());
|
||||||
|
|
||||||
|
$(MediaController).on('playerchange', function () {
|
||||||
|
|
||||||
|
if (MediaController.getPlayerInfo().name == PlayerName) {
|
||||||
|
|
||||||
|
// launch app if needed
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initSdk();
|
||||||
|
|
||||||
|
})();
|
37
dashboard-ui/thirdparty/cordova/connectsdk.js
vendored
Normal file
37
dashboard-ui/thirdparty/cordova/connectsdk.js
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
|
||||||
|
function onDeviceFound() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeviceLost() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSdk() {
|
||||||
|
|
||||||
|
var manager = ConnectSDK.discoveryManager;
|
||||||
|
|
||||||
|
manager.setPairingLevel(ConnectSDK.PairingLevel.OFF);
|
||||||
|
manager.setAirPlayServiceMode(ConnectSDK.AirPlayServiceMode.Media);
|
||||||
|
|
||||||
|
// Show devices that support playing videos and pausing
|
||||||
|
manager.setCapabilityFilters([
|
||||||
|
new ConnectSDK.CapabilityFilter(["MediaPlayer.Display.Video", "MediaControl.Pause"])
|
||||||
|
]);
|
||||||
|
|
||||||
|
manager.addListener('devicefound', onDeviceFound);
|
||||||
|
manager.addListener('devicelost', onDeviceLost);
|
||||||
|
|
||||||
|
requirejs(['thirdparty/cordova/chromecast']);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("deviceready", function () {
|
||||||
|
|
||||||
|
initSdk();
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
Loading…
Add table
Add a link
Reference in a new issue