Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Oct 17, 2024
2 parents f70f551 + 8b3a02c commit 6ed793d
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 33 deletions.
42 changes: 21 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"stylelint-order": "6.0.4",
"stylelint-scss": "5.3.2",
"ts-loader": "9.5.1",
"typescript": "5.6.2",
"typescript": "5.6.3",
"vitest": "2.1.2",
"webpack": "5.94.0",
"webpack-bundle-analyzer": "4.10.2",
Expand All @@ -79,7 +79,7 @@
"@fontsource/noto-sans-sc": "5.1.0",
"@fontsource/noto-sans-tc": "5.1.0",
"@jellyfin/libass-wasm": "4.2.3",
"@jellyfin/sdk": "0.0.0-unstable.202410150501",
"@jellyfin/sdk": "0.0.0-unstable.202410160502",
"@mui/icons-material": "5.16.7",
"@mui/material": "5.16.7",
"@mui/x-date-pickers": "7.18.0",
Expand All @@ -100,7 +100,7 @@
"flv.js": "1.6.2",
"headroom.js": "0.12.0",
"history": "5.3.0",
"hls.js": "1.5.15",
"hls.js": "1.5.16",
"intersection-observer": "0.12.2",
"jellyfin-apiclient": "1.11.0",
"jquery": "3.7.1",
Expand Down
4 changes: 4 additions & 0 deletions src/components/remotecontrol/remotecontrol.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,10 @@ export default function () {

function loadPlaylist(context, player) {
getPlaylistItems(player).then(function (items) {
if (items.length === 0) {
return;
}

let html = '';
let favoritesEnabled = true;
if (layoutManager.mobile) {
Expand Down
139 changes: 133 additions & 6 deletions src/plugins/sessionPlayer/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
const serverId = apiClient.serverId();

Expand All @@ -103,11 +155,13 @@ function processUpdatedSessions(instance, sessions, apiClient) {
normalizeImages(session, apiClient);

const eventNames = getChangedEvents(instance.lastPlayerData);
updateCurrentQueue(instance, session);

instance.lastPlayerData = session;

for (let i = 0, length = eventNames.length; i < length; i++) {
Events.trigger(instance, eventNames[i], [session]);
}
eventNames.forEach(eventName => {
Events.trigger(instance, eventName, [session]);
});
} else {
instance.lastPlayerData = session;

Expand Down Expand Up @@ -178,6 +232,8 @@ function normalizeImages(state, apiClient) {
}

class SessionPlayer {
lastPlaylistItemId;

constructor() {
const self = this;

Expand All @@ -186,6 +242,10 @@ class SessionPlayer {
this.isLocalPlayer = false;
this.id = 'remoteplayer';

this.playlist = [];
this.isPlaylistRendered = true;
this.isUpdatingPlaylist = false;

Events.on(serverNotifications, 'Sessions', function (e, apiClient, data) {
processUpdatedSessions(self, data, apiClient);
});
Expand Down Expand Up @@ -484,16 +544,83 @@ class SessionPlayer {
return state.MediaType === 'Audio';
}

getTrackIndex(playlistItemId) {
for (let i = 0; i < this.playlist.length; i++) {
if (this.playlist[i].PlaylistItemId === playlistItemId) {
return i;
}
}
}

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([]);
}

movePlaylistItem(playlistItemId, newIndex) {
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');
}

getCurrentPlaylistItemId() {
// not supported?
return this.lastPlayerData.PlaylistItemId;
}

setCurrentPlaylistItem() {
return Promise.resolve();
setCurrentPlaylistItem(playlistItemId) {
const options = {
ids: this.playlist.map(i => i.Id),
startIndex: this.getTrackIndex(playlistItemId)
};
return sendPlayCommand(getCurrentApiClient(this), options, 'PlayNow');
}

removeFromPlaylist() {
Expand Down
16 changes: 15 additions & 1 deletion src/strings/en-gb.json
Original file line number Diff line number Diff line change
Expand Up @@ -1971,5 +1971,19 @@
"LabelScreensaverTime": "Screensaver Time",
"AlwaysBurnInSubtitleWhenTranscoding": "Always burn in subtitle when transcoding",
"AlwaysBurnInSubtitleWhenTranscodingHelp": "Burn in all subtitles when transcoding is triggered. This ensures subtitle synchronisation after transcoding at the cost of reduced transcoding speed.",
"LabelScreensaverTimeHelp": "The amount of time in seconds of inactivity required to start the screensaver."
"LabelScreensaverTimeHelp": "The amount of time in seconds of inactivity required to start the screensaver.",
"LabelQsvDevice": "QSV Device",
"HeaderEditPlaylist": "Edit Playlist",
"HeaderNewPlaylist": "New Playlist",
"LabelMediaSegmentsType": "{0} Segments",
"LabelQsvDeviceHelp": "Specify the device for Intel QSV on a multi-GPU system. On Linux, this is the render node, e.g., /dev/dri/renderD128. On Windows, this is the device index starting from 0. Leave blank unless you know what you are doing.",
"MediaSegmentAction.None": "None",
"MediaSegmentAction.Skip": "Skip",
"MediaSegmentType.Commercial": "Ad",
"HeaderMediaSegmentActions": "Media Segment Actions",
"MediaSegmentType.Intro": "Intro",
"MediaSegmentType.Outro": "Outro",
"MediaSegmentType.Preview": "Preview",
"MediaSegmentType.Recap": "Recap",
"PlaylistError.UpdateFailed": "Error updating playlist"
}
26 changes: 25 additions & 1 deletion src/strings/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -1353,5 +1353,29 @@
"LabelNoChangelog": "לא סופק תיעוד שינויים לשחרור זה.",
"LabelNotInstalled": "לא מותקן",
"HeaderMediaSegmentActions": "פעולות על מקטע מדיה",
"LabelMediaSegmentsType": "{0} מקטעים"
"LabelMediaSegmentsType": "{0} מקטעים",
"LabelScreensaverTime": "זמן לשומר מסך",
"HeaderEditPlaylist": "עריכת רשימת ניגון",
"HeaderNewPlaylist": "רשימת ניגון חדשה",
"LabelPleaseRestart": "השינויים יחולו אחרי טעינה מחדש של הדפדפן.",
"LabelPostProcessor": "תוכנת עיבוד-אוחר",
"LabelPostProcessorArguments": "ארגומנטים לשורת הפקודה של תוכנת עיבוד-אוחר",
"LabelPostProcessorArgumentsHelp": "השתמש ב-{path} כמסלול לקובץ ההקלטה.",
"LabelPublicHttpsPort": "מספר פורט HTTPS פומבי",
"LabelPublicHttpsPortHelp": "מספר הפורט הפומבי אשר ימופה לפורט HTTPS המקומי.",
"LabelPublishedServerUri": "כתובות URI של השרת שיפורסמו",
"LabelPublishedServerUriHelp": "דרוס את ה-URI שבשימוש ג'ליפין, בהתבסס על כרטיס הרשת, או כתובת IP של הלקוח. למשל: internal=http://jellyfin.example.com, external=https://jellyfin.example.com, או all=https://jellyfin.example.com",
"LabelParallelImageEncodingLimit": "גבול קידוד תמונות במקביל",
"LabelParallelImageEncodingLimitHelp": "המספר המקסימלי של קידודי תמונות שירוצו במקביל. הגדרה של 0 תבחר ערך בהתאם למספר המעבדים במערכת שלך.",
"LabelPlayDefaultAudioTrack": "ניגון פס הקול הדיפולטי ללא תלות בשפה",
"LabelPublicHttpPortHelp": "מספר הפורט הפומבי אשר ימופה לפורט HTTP המקומי.",
"LabelQsvDevice": "רכיב QSV",
"LabelRecordingPathHelp": "הגדרת מסלול ברירת מחדל לשמירת הקלטות. אם ריק, ייעשה שימוש בתיקיית המידע של השרת.",
"LabelQsvDeviceHelp": "הגדרת רכיב עבור Intel QSV ומערכת מרובת מעבדים גרפיים. בלינוקס, זה יהיה רכיב הרינדור, למשל /dev/dri/renderD128. בווינדוס, זה יהיה אינדקס הרכיב החל מ-0. יש להשאיר ריק אלא אם אתם יודעים מה אתם עושים.",
"LabelRecordingPath": "מסלול הקלטה ברירת מחדל",
"LabelScreensaverTimeHelp": "מספר השניות הנחוץ של חוסר פעילות כדי להפעיל את שומר המסך.",
"LabelRepository": "מאגר",
"LabelSaveTrickplayLocally": "שמירת תמונות trickplay ליד המדיה",
"LabelSaveTrickplayLocallyHelp": "שמירת תמונות trickplay בתיקיית המדיה תשים אותם ליד המדיה שלך למיגרציה וגישה קלה.",
"LabelRemoteClientBitrateLimit": "גבול קצב הזרמת רשת (Mbps)"
}
4 changes: 3 additions & 1 deletion src/strings/hu.json
Original file line number Diff line number Diff line change
Expand Up @@ -1906,5 +1906,7 @@
"LabelAudioTagSettings": "Hangcímke-beállítások",
"LabelDelimiterWhitelist": "Elválasztók engedélyezési listája",
"LabelDelimiterWhitelistHelp": "Elemek, melyek nem lesznek figyelembe véve a címkefelosztásnál. Soronként egy elem.",
"LabelDisableVbrAudioEncoding": "Változó bitsebességű hangfelvétel letiltása"
"LabelDisableVbrAudioEncoding": "Változó bitsebességű hangfelvétel letiltása",
"AlwaysBurnInSubtitleWhenTranscoding": "Mindig égesse be a feliratot átkódoláskor",
"AlwaysBurnInSubtitleWhenTranscodingHelp": "Minden felirat beégetése átkódolás aktiválásakor. Ez biztosítja a feliratok szinkronját átkodólás után a kódolás sebességének rovására."
}

0 comments on commit 6ed793d

Please sign in to comment.