plexsonic 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.js +62 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plexsonic",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "PlexMusic to OpenSubsonic bridge",
5
5
  "main": "./src/index.js",
6
6
  "bin": {
package/src/server.js CHANGED
@@ -3491,6 +3491,49 @@ export async function buildServer(config = loadConfig()) {
3491
3491
  });
3492
3492
  }
3493
3493
 
3494
+ function updatePlaybackSessionEstimateFromStream({
3495
+ accountId,
3496
+ clientName,
3497
+ trackId,
3498
+ durationMs = null,
3499
+ positionMs = 0,
3500
+ }) {
3501
+ const playbackClient = playbackClientContext(accountId, clientName);
3502
+ const current = playbackSessions.get(playbackClient.sessionKey);
3503
+ if (!current || current.state !== 'playing') {
3504
+ return false;
3505
+ }
3506
+
3507
+ const normalizedTrackId = String(trackId || '').trim();
3508
+ if (!normalizedTrackId || String(current.itemId || '').trim() !== normalizedTrackId) {
3509
+ return false;
3510
+ }
3511
+
3512
+ const now = Date.now();
3513
+ const normalizedDuration = Number.isFinite(durationMs) && durationMs > 0
3514
+ ? Math.max(0, Math.trunc(durationMs))
3515
+ : Number.isFinite(current.durationMs) && current.durationMs > 0
3516
+ ? Math.max(0, Math.trunc(current.durationMs))
3517
+ : null;
3518
+ const normalizedPosition = Number.isFinite(positionMs) && positionMs >= 0
3519
+ ? Math.max(0, Math.trunc(positionMs))
3520
+ : 0;
3521
+ const basePosition = Math.max(Number(current.positionMs || 0), normalizedPosition);
3522
+ const estimatedStopAt = normalizedDuration != null
3523
+ ? now + Math.max(0, normalizedDuration - basePosition)
3524
+ : current.estimatedStopAt;
3525
+
3526
+ playbackSessions.set(playbackClient.sessionKey, {
3527
+ ...current,
3528
+ durationMs: normalizedDuration,
3529
+ positionMs: basePosition,
3530
+ estimatedStopAt,
3531
+ updatedAt: now,
3532
+ });
3533
+
3534
+ return true;
3535
+ }
3536
+
3494
3537
  const playbackMaintenanceTimer = setInterval(async () => {
3495
3538
  const now = Date.now();
3496
3539
  const sessions = [...playbackSessions.entries()];
@@ -3501,8 +3544,16 @@ export async function buildServer(config = loadConfig()) {
3501
3544
  continue;
3502
3545
  }
3503
3546
 
3504
- if (now - Number(session.updatedAt || 0) > PLAYBACK_IDLE_TIMEOUT_MS) {
3547
+ const estimatedStopReached = (
3548
+ session.state === 'playing' &&
3549
+ Number.isFinite(session.estimatedStopAt) &&
3550
+ session.estimatedStopAt <= now
3551
+ );
3552
+ const idleExpired = now - Number(session.updatedAt || 0) > PLAYBACK_IDLE_TIMEOUT_MS;
3553
+
3554
+ if (estimatedStopReached || idleExpired) {
3505
3555
  if (
3556
+ !estimatedStopReached &&
3506
3557
  session.state === 'playing' &&
3507
3558
  Number.isFinite(session.estimatedStopAt) &&
3508
3559
  session.estimatedStopAt > now
@@ -7080,6 +7131,16 @@ export async function buildServer(config = loadConfig()) {
7080
7131
  const trackDurationMs = parseNonNegativeInt(track.duration, 0);
7081
7132
  const playbackStartAt = Date.now();
7082
7133
 
7134
+ if (streamPlaybackAuthorityDisabled) {
7135
+ updatePlaybackSessionEstimateFromStream({
7136
+ accountId: account.id,
7137
+ clientName,
7138
+ trackId,
7139
+ durationMs: trackDurationMs > 0 ? trackDurationMs : null,
7140
+ positionMs: offsetMs,
7141
+ });
7142
+ }
7143
+
7083
7144
  const estimatePlaybackPositionMs = (nowMs = Date.now()) => {
7084
7145
  const elapsedMs = Math.max(0, nowMs - playbackStartAt);
7085
7146
  const estimated = offsetMs + elapsedMs;