mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Fix queue when playing on remote device (partial) (#3381)
This commit is contained in:
parent
2564902573
commit
8b3a02c727
2 changed files with 138 additions and 7 deletions
|
@ -493,6 +493,10 @@ export default function () {
|
||||||
|
|
||||||
function loadPlaylist(context, player) {
|
function loadPlaylist(context, player) {
|
||||||
getPlaylistItems(player).then(function (items) {
|
getPlaylistItems(player).then(function (items) {
|
||||||
|
if (items.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let html = '';
|
let html = '';
|
||||||
let favoritesEnabled = true;
|
let favoritesEnabled = true;
|
||||||
if (layoutManager.mobile) {
|
if (layoutManager.mobile) {
|
||||||
|
|
|
@ -84,6 +84,58 @@ function unsubscribeFromPlayerUpdates(instance) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updatePlaylist(instance, queue) {
|
||||||
|
const options = {
|
||||||
|
ids: queue.map(i => i.Id),
|
||||||
|
serverId: getCurrentApiClient(instance).serverId()
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await playbackManager.getItemsForPlayback(options.serverId, {
|
||||||
|
Ids: options.ids.join(',')
|
||||||
|
});
|
||||||
|
|
||||||
|
const items = await playbackManager.translateItemsForPlayback(result.Items, options);
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
items[i].PlaylistItemId = queue[i].PlaylistItemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.playlist = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareQueues(q1, q2) {
|
||||||
|
if (q1.length !== q2.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < q1.length; i++) {
|
||||||
|
if (q1[i].Id !== q2[i].Id || q1[i].PlaylistItemId !== q2[i].PlaylistItemId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCurrentQueue(instance, session) {
|
||||||
|
const current = session.NowPlayingQueue;
|
||||||
|
if (instance.isUpdatingPlaylist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance.lastPlayerData && !compareQueues(current, instance.playlist)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.isUpdatingPlaylist = true;
|
||||||
|
|
||||||
|
const finish = () => {
|
||||||
|
instance.isUpdatingPlaylist = false;
|
||||||
|
instance.isPlaylistRendered = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
updatePlaylist(instance, current).then(finish, finish);
|
||||||
|
}
|
||||||
|
|
||||||
function processUpdatedSessions(instance, sessions, apiClient) {
|
function processUpdatedSessions(instance, sessions, apiClient) {
|
||||||
const serverId = apiClient.serverId();
|
const serverId = apiClient.serverId();
|
||||||
|
|
||||||
|
@ -103,11 +155,13 @@ function processUpdatedSessions(instance, sessions, apiClient) {
|
||||||
normalizeImages(session, apiClient);
|
normalizeImages(session, apiClient);
|
||||||
|
|
||||||
const eventNames = getChangedEvents(instance.lastPlayerData);
|
const eventNames = getChangedEvents(instance.lastPlayerData);
|
||||||
|
updateCurrentQueue(instance, session);
|
||||||
|
|
||||||
instance.lastPlayerData = session;
|
instance.lastPlayerData = session;
|
||||||
|
|
||||||
for (let i = 0, length = eventNames.length; i < length; i++) {
|
eventNames.forEach(eventName => {
|
||||||
Events.trigger(instance, eventNames[i], [session]);
|
Events.trigger(instance, eventName, [session]);
|
||||||
}
|
});
|
||||||
} else {
|
} else {
|
||||||
instance.lastPlayerData = session;
|
instance.lastPlayerData = session;
|
||||||
|
|
||||||
|
@ -178,6 +232,8 @@ function normalizeImages(state, apiClient) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SessionPlayer {
|
class SessionPlayer {
|
||||||
|
lastPlaylistItemId;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
|
@ -186,6 +242,10 @@ class SessionPlayer {
|
||||||
this.isLocalPlayer = false;
|
this.isLocalPlayer = false;
|
||||||
this.id = 'remoteplayer';
|
this.id = 'remoteplayer';
|
||||||
|
|
||||||
|
this.playlist = [];
|
||||||
|
this.isPlaylistRendered = true;
|
||||||
|
this.isUpdatingPlaylist = false;
|
||||||
|
|
||||||
Events.on(serverNotifications, 'Sessions', function (e, apiClient, data) {
|
Events.on(serverNotifications, 'Sessions', function (e, apiClient, data) {
|
||||||
processUpdatedSessions(self, data, apiClient);
|
processUpdatedSessions(self, data, apiClient);
|
||||||
});
|
});
|
||||||
|
@ -484,16 +544,83 @@ class SessionPlayer {
|
||||||
return state.MediaType === 'Audio';
|
return state.MediaType === 'Audio';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTrackIndex(playlistItemId) {
|
||||||
|
for (let i = 0; i < this.playlist.length; i++) {
|
||||||
|
if (this.playlist[i].PlaylistItemId === playlistItemId) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPlaylist() {
|
getPlaylist() {
|
||||||
|
let itemId;
|
||||||
|
|
||||||
|
if (this.lastPlayerData) {
|
||||||
|
itemId = this.lastPlayerData.PlaylistItemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.playlist.length > 0 && (this.isPlaylistRendered || itemId !== this.lastPlaylistItemId)) {
|
||||||
|
this.isPlaylistRendered = false;
|
||||||
|
this.lastPlaylistItemId = itemId;
|
||||||
|
return Promise.resolve(this.playlist);
|
||||||
|
}
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentPlaylistItemId() {
|
movePlaylistItem(playlistItemId, newIndex) {
|
||||||
// not supported?
|
const index = this.getTrackIndex(playlistItemId);
|
||||||
|
if (index === newIndex) return;
|
||||||
|
|
||||||
|
const current = this.getCurrentPlaylistItemId();
|
||||||
|
let currentIndex = 0;
|
||||||
|
|
||||||
|
if (current === playlistItemId) {
|
||||||
|
currentIndex = newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
const append = (newIndex + 1 >= this.playlist.length);
|
||||||
|
|
||||||
|
if (newIndex > index) newIndex++;
|
||||||
|
|
||||||
|
const ids = [];
|
||||||
|
const item = this.playlist[index];
|
||||||
|
|
||||||
|
for (let i = 0; i < this.playlist.length; i++) {
|
||||||
|
if (i === index) continue;
|
||||||
|
|
||||||
|
if (i === newIndex) {
|
||||||
|
ids.push(item.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.playlist[i].PlaylistItemId === current) {
|
||||||
|
currentIndex = ids.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
ids.push(this.playlist[i].Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (append) {
|
||||||
|
ids.push(item.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
ids,
|
||||||
|
startIndex: currentIndex
|
||||||
|
};
|
||||||
|
|
||||||
|
return sendPlayCommand(getCurrentApiClient(this), options, 'PlayNow');
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentPlaylistItem() {
|
getCurrentPlaylistItemId() {
|
||||||
return Promise.resolve();
|
return this.lastPlayerData.PlaylistItemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentPlaylistItem(playlistItemId) {
|
||||||
|
const options = {
|
||||||
|
ids: this.playlist.map(i => i.Id),
|
||||||
|
startIndex: this.getTrackIndex(playlistItemId)
|
||||||
|
};
|
||||||
|
return sendPlayCommand(getCurrentApiClient(this), options, 'PlayNow');
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromPlaylist() {
|
removeFromPlaylist() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue