Skip to content

Align xmplaylist metadata selection, adaptive refresh timing, and cached next-track transitions with play-behind-live timestamp#80

Merged
paul-1 merged 25 commits into
mainfrom
copilot/implement-play-behind-live-support
Apr 22, 2026
Merged

Align xmplaylist metadata selection, adaptive refresh timing, and cached next-track transitions with play-behind-live timestamp#80
paul-1 merged 25 commits into
mainfrom
copilot/implement-play-behind-live-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 19, 2026

This PR aligns SiriusXM metadata behavior with play-behind-live timestamps and improves timer behavior around track transitions and async state changes.

Changes Made

  • Uses play-behind-live PDT timestamps to select the correct xmplaylist record at/before the current playback position.
  • Uses adaptive delay scheduling (next_update_delay) when a future xmplaylist track timestamp is available.
  • Hardens async metadata callbacks so stale responses cannot update metadata or re-arm timers after stop/channel/state changes.
  • Adds cached next-track metadata flow:
    • when xmplaylist already includes the next track, that metadata is cached in player state,
    • when the delayed timer fires, cached metadata is applied locally (without re-reading PDT or polling xmplaylist),
    • after applying cached metadata, normal 25s polling resumes.
  • Adds guards so cached metadata is not applied when metadata is disabled or player state is no longer active.

Validation

  • Ran baseline plugin validation suite (XML, structure, required files/templates/menu checks).
  • Ran proxy startup help validation (sxm.pl ... --help).
  • Ran targeted post-change validation.
  • Ran final parallel validation (Code Review + CodeQL).
Original prompt

Repository: paul-1/plugin-SiriusXM

Goal
Implement “play behind live” support when processing the xmplaylist.com API response in Plugins/SiriusXM/APImetadata.pm (specifically within/around sub _processResponse which starts near line 212).

Context
sxm.pl now supports playing behind live and caching. It writes the timestamp currently being played to:

<tmpdir>/siriusxm/pdt_<siriusxm_channel_id>.txt

We need to adjust metadata processing so that, when we process the API response from xmplaylist.com, we:

  1. Read the play timestamp from that file (if it exists and is valid).
  2. From the API response records, select the record whose timestamp is the most recent at or before the play timestamp (i.e., the closest record timestamp not after the play timestamp). If no record timestamp is <= the play timestamp, fall back to the default behavior (likely using the most recent/latest/current record).

Requirements

  • Make changes in Plugins/SiriusXM/APImetadata.pm.
  • Use the repo’s tmpdir location logic (whatever the plugin uses) to construct the path to siriusxm/pdt_<channel_id>.txt.
  • Parse and validate the timestamp read from file (handle missing file, empty content, parse failures).
  • Parse timestamps from xmplaylist.com records (handle missing/invalid timestamps).
  • Ensure behavior remains unchanged when the pdt file doesn’t exist or doesn’t contain a usable timestamp.
  • Add logging (at an appropriate verbosity) for: reading pdt file, selected timestamp, and fallback paths.
  • Add/update any tests if this repo has a test harness; otherwise keep changes well-scoped and add comments.

Reference

Implementation notes

  • The timestamp written by sxm.pl is the timestamp being played; assume it is epoch seconds unless the codebase indicates another format. If the API provides timestamps in another format, implement conversion.
  • The selection algorithm should pick the record with max(record_ts) such that record_ts <= play_ts. If none match, keep existing selection logic.

Deliverable
Open a PR on paul-1/plugin-SiriusXM targeting main with the implementation.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: sxm.pl now has the ability to play behind live and cache data. It writes the timestamp being played to /siriusxm/pdt_<siriusxm_channel_id>.txt.

When processing the API response from xmplaylist.com, we need to read the timestamp from the file, then find the record timestamp that is most recent to the timestamp read from the temp file.

Assistant: I’m waiting for your confirmation in the dialog (approve/deny) before I can proceed with making the repository changes for selecting the xmplaylist.com record closest to the cached play timestamp.

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Implement play behind live support in API response processing Align xmplaylist metadata selection with play-behind-live timestamp Apr 19, 2026
Copilot AI requested a review from paul-1 April 19, 2026 18:03
@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 19, 2026

@copilot

-If there is no pdt_ file or there is no timestamp in the file, just use the channel metadata.
-Since we also now know the current timestamp being played, we do not need to use METADATA_STALE_TIME check.
-Please also check that you are using the siriusxm channel_id for the pdt file, not the xmplaylist_name (For example Siriusxm Channel ID: 9608 is Channel number: 12, and the xmplaylist deeplink is: kellyclarksonconnection) So /tmp/siriusxm/pdt_9608.txt is the timestamp file when looking at kellyclarksonconnection from xmplaylist.com)

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 19, 2026

@copilot

-If there is no pdt_ file or there is no timestamp in the file, just use the channel metadata.
...

Updated in commit aca5a70.

Changes made:

  • If the pdt file is missing/unusable, metadata now falls back to channel metadata.
  • Removed the METADATA_STALE_TIME age check path.
  • Confirmed pdt lookup uses SiriusXM channel_info->{id} (/tmp/siriusxm/pdt_<channel_id>.txt), not xmplaylist_name.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 19, 2026

@copilot

metatdate refreshes seem to lag. See the attached log. It matched the correct record, but did not update for 2 cycles later>

[26-04-19 14:39:56.2409] Plugins::SiriusXM::APImetadata::_processResponse (253) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 14:39:56.2415] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (389) Read play timestamp '2026-04-19T18:37:32.404+00:00' (1776623852.404) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 14:39:56.2417] Plugins::SiriusXM::APImetadata::_processResponse (277) Selected xmplaylist record timestamp 2026-04-19T18:37:07.099Z for play timestamp 1776623852.404
[26-04-19 14:39:56.2417] Plugins::SiriusXM::APImetadata::_processResponse (293) Metadata source selection: matched record at/before play timestamp
[26-04-19 14:39:56.2418] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (320) No new metadata available and current metadata is fresh - skipping update
[26-04-19 14:40:21.0007] Plugins::SiriusXM::APImetadata::fetchMetadata (192) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 14:40:21.1697] Plugins::SiriusXM::APImetadata::_processResponse (253) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 14:40:21.1703] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (389) Read play timestamp '2026-04-19T18:37:51.907+00:00' (1776623871.907) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 14:40:21.1706] Plugins::SiriusXM::APImetadata::_processResponse (277) Selected xmplaylist record timestamp 2026-04-19T18:37:07.099Z for play timestamp 1776623871.907
[26-04-19 14:40:21.1706] Plugins::SiriusXM::APImetadata::_processResponse (293) Metadata source selection: matched record at/before play timestamp
[26-04-19 14:40:21.1707] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (320) No new metadata available and current metadata is fresh - skipping update
[26-04-19 14:40:46.0008] Plugins::SiriusXM::APImetadata::fetchMetadata (192) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 14:40:46.2578] Plugins::SiriusXM::APImetadata::_processResponse (253) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 14:40:46.2584] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (389) Read play timestamp '2026-04-19T18:38:21.161+00:00' (1776623901.161) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 14:40:46.2596] Plugins::SiriusXM::APImetadata::_processResponse (277) Selected xmplaylist record timestamp 2026-04-19T18:37:07.099Z for play timestamp 1776623901.161
[26-04-19 14:40:46.2597] Plugins::SiriusXM::APImetadata::_processResponse (293) Metadata source selection: matched record at/before play timestamp
[26-04-19 14:40:46.2599] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (334) Updating metadata for client b8:27:eb:d9:dd:0e: On Top of the World by Imagine Dragons
[26-04-19 14:40:46.2601] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (346) Stored metadata for channel thepulse in global cache

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 19, 2026

@copilot

metatdate refreshes seem to lag. See the attached log. It matched the correct record, but did not update for 2 cycles later>
...

Implemented a fix in commit 06ec31b.

Metadata update skipping is now based on a canonical signature of the actual metadata content (not xmplaylist next token), so updates are applied as soon as the selected record changes even if next stays the same. I also removed obsolete last_next tracking and added safe signature-encode handling.

No UI changes were made (backend metadata logic only).

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Align xmplaylist metadata selection with play-behind-live timestamp Align xmplaylist metadata selection and refresh timing with play-behind-live timestamp Apr 19, 2026
@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 19, 2026

@copilot when the data coming from xmplaylist.com has a track timestamp that is newer than what we are currently playing, use that time offset to schedule the metadata update rather than just the flat METADATA_UPDATE_INTERVAL. If there is no newer track in the data, then fallback to the next check based on METADATA_UPDATE_INTERVAL

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 19, 2026

@copilot when the data coming from xmplaylist.com has a track timestamp that is newer than what we are currently playing, use that time offset to schedule the metadata update rather than just the flat...

Implemented in commit fc1f000.

Metadata refresh scheduling now uses the nearest xmplaylist track timestamp newer than the current play timestamp (next_update_delay) when available, and falls back to METADATA_UPDATE_INTERVAL when no newer track timestamp exists.

No UI changes were made (backend scheduling logic only).

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Align xmplaylist metadata selection and refresh timing with play-behind-live timestamp Align xmplaylist metadata selection and adaptive refresh timing with play-behind-live timestamp Apr 19, 2026
@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 19, 2026

@copilot There seems to be a small time calculation error. The first calculated offset of ~100 at next check was still ~2s away.

[26-04-19 15:35:49.2142] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (410) Read play timestamp '2026-04-19T19:33:17.467+00:00' (1776627177.467) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:35:49.2145] Plugins::SiriusXM::APImetadata::_processResponse (289) Next xmplaylist track timestamp is in 100.280999898911s relative to play timestamp
[26-04-19 15:35:49.2145] Plugins::SiriusXM::APImetadata::_processResponse (295) Selected xmplaylist record timestamp 2026-04-19T19:30:15.632Z for play timestamp 1776627177.467
[26-04-19 15:35:49.2145] Plugins::SiriusXM::APImetadata::_processResponse (311) Metadata source selection: matched record at/before play timestamp
[26-04-19 15:35:49.2146] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (344) No new metadata available and current metadata is fresh - skipping update
[26-04-19 15:35:49.2146] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 100.280999898911s
[26-04-19 15:37:29.2818] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:29.2999] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:29.3139] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:29.3276] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:29.5429] Plugins::SiriusXM::APImetadata::_processResponse (255) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5430] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (410) Read play timestamp '2026-04-19T19:34:54.981+00:00' (1776627274.981) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5433] Plugins::SiriusXM::APImetadata::_processResponse (289) Next xmplaylist track timestamp is in 2.76699995994568s relative to play timestamp
[26-04-19 15:37:29.5433] Plugins::SiriusXM::APImetadata::_processResponse (295) Selected xmplaylist record timestamp 2026-04-19T19:30:15.632Z for play timestamp 1776627274.981
[26-04-19 15:37:29.5433] Plugins::SiriusXM::APImetadata::_processResponse (311) Metadata source selection: matched record at/before play timestamp
[26-04-19 15:37:29.5434] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (344) No new metadata available and current metadata is fresh - skipping update
[26-04-19 15:37:29.5434] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 2.76699995994568s
[26-04-19 15:37:29.5448] Plugins::SiriusXM::APImetadata::_processResponse (255) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5448] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (410) Read play timestamp '2026-04-19T19:34:54.981+00:00' (1776627274.981) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5451] Plugins::SiriusXM::APImetadata::_processResponse (289) Next xmplaylist track timestamp is in 2.76699995994568s relative to play timestamp
[26-04-19 15:37:29.5451] Plugins::SiriusXM::APImetadata::_processResponse (295) Selected xmplaylist record timestamp 2026-04-19T19:30:15.632Z for play timestamp 1776627274.981
[26-04-19 15:37:29.5451] Plugins::SiriusXM::APImetadata::_processResponse (311) Metadata source selection: matched record at/before play timestamp
[26-04-19 15:37:29.5452] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (344) No new metadata available and current metadata is fresh - skipping update
[26-04-19 15:37:29.5452] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 2.76699995994568s
[26-04-19 15:37:29.5465] Plugins::SiriusXM::APImetadata::_processResponse (255) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5466] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (410) Read play timestamp '2026-04-19T19:34:54.981+00:00' (1776627274.981) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5468] Plugins::SiriusXM::APImetadata::_processResponse (289) Next xmplaylist track timestamp is in 2.76699995994568s relative to play timestamp
[26-04-19 15:37:29.5468] Plugins::SiriusXM::APImetadata::_processResponse (295) Selected xmplaylist record timestamp 2026-04-19T19:30:15.632Z for play timestamp 1776627274.981
[26-04-19 15:37:29.5469] Plugins::SiriusXM::APImetadata::_processResponse (311) Metadata source selection: matched record at/before play timestamp
[26-04-19 15:37:29.5469] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (344) No new metadata available and current metadata is fresh - skipping update
[26-04-19 15:37:29.5469] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 2.76699995994568s
[26-04-19 15:37:29.5484] Plugins::SiriusXM::APImetadata::_processResponse (255) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5485] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (410) Read play timestamp '2026-04-19T19:34:54.981+00:00' (1776627274.981) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:29.5487] Plugins::SiriusXM::APImetadata::_processResponse (289) Next xmplaylist track timestamp is in 2.76699995994568s relative to play timestamp
[26-04-19 15:37:29.5488] Plugins::SiriusXM::APImetadata::_processResponse (295) Selected xmplaylist record timestamp 2026-04-19T19:30:15.632Z for play timestamp 1776627274.981
[26-04-19 15:37:29.5488] Plugins::SiriusXM::APImetadata::_processResponse (311) Metadata source selection: matched record at/before play timestamp
[26-04-19 15:37:29.5488] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (344) No new metadata available and current metadata is fresh - skipping update
[26-04-19 15:37:29.5488] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 2.76699995994568s
[26-04-19 15:37:31.7680] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:31.7859] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:31.8002] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:31.8150] Plugins::SiriusXM::APImetadata::fetchMetadata (193) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 15:37:31.9694] Plugins::SiriusXM::APImetadata::_processResponse (255) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:31.9699] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (410) Read play timestamp '2026-04-19T19:35:04.733+00:00' (1776627284.733) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 15:37:31.9711] Plugins::SiriusXM::APImetadata::_processResponse (295) Selected xmplaylist record timestamp 2026-04-19T19:34:37.748Z for play timestamp 1776627284.733
[26-04-19 15:37:31.9713] Plugins::SiriusXM::APImetadata::_processResponse (311) Metadata source selection: matched record at/before play timestamp
[26-04-19 15:37:31.9715] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (357) Updating metadata for client b8:27:eb:d9:dd:0e: So Easy (To Fall In Love) by Olivia Dean
[26-04-19 15:37:31.9717] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (369) Stored metadata for channel thepulse in global cache
[26-04-19 15:37:31.9720] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 25s

Copilot AI requested a review from paul-1 April 19, 2026 19:54
@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 20, 2026

@copilot when stopping a stream the metadata does not stop, but gets put in an infinite refresh loop. See attached log

[26-04-19 22:08:15.8775] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (131) Player event 'playlist:newsong' for client b8:27:eb:d9:dd:0e, URL:http://localhost:8888/thepulse.m3u8
[26-04-19 22:08:15.8775] Plugins::SiriusXM::ProtocolHandler::_stopMetadataTimer (226) Stopping metadata timer for client b8:27:eb:d9:dd:0e
[26-04-19 22:08:15.8776] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (169) No current player state, configuring
[26-04-19 22:08:15.8786] Plugins::SiriusXM::APImetadata::fetchMetadata (192) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 22:08:16.0421] Plugins::SiriusXM::APImetadata::_processResponse (254) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.0427] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (413) Read play timestamp '2026-04-20T02:05:39.706+00:00' (1776650719.706) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.0430] Plugins::SiriusXM::APImetadata::_processResponse (292) Next xmplaylist track timestamp raw delay=21.1409997940063s rounded=22s
[26-04-19 22:08:16.0430] Plugins::SiriusXM::APImetadata::_processResponse (298) Selected xmplaylist record timestamp 2026-04-20T02:02:59.815Z for play timestamp 1776650719.706
[26-04-19 22:08:16.0430] Plugins::SiriusXM::APImetadata::_processResponse (314) Metadata source selection: matched record at/before play timestamp
[26-04-19 22:08:16.0431] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (361) Updating metadata for client b8:27:eb:d9:dd:0e: When Did You Get Hot? by Sabrina Carpenter
[26-04-19 22:08:16.0432] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (373) Stored metadata for channel thepulse in global cache
[26-04-19 22:08:16.0433] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 22s
[26-04-19 22:08:16.0446] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (131) Player event 'playlist:newsong' for client b8:27:eb:d9:dd:0e, URL:http://localhost:8888/thepulse.m3u8
[26-04-19 22:08:16.0447] Plugins::SiriusXM::ProtocolHandler::_stopMetadataTimer (226) Stopping metadata timer for client b8:27:eb:d9:dd:0e
[26-04-19 22:08:16.0447] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (169) No current player state, configuring
[26-04-19 22:08:16.0457] Plugins::SiriusXM::APImetadata::fetchMetadata (192) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 22:08:16.2373] Plugins::SiriusXM::APImetadata::_processResponse (254) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.2375] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (413) Read play timestamp '2026-04-20T02:05:39.706+00:00' (1776650719.706) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.2378] Plugins::SiriusXM::APImetadata::_processResponse (292) Next xmplaylist track timestamp raw delay=21.1409997940063s rounded=22s
[26-04-19 22:08:16.2378] Plugins::SiriusXM::APImetadata::_processResponse (298) Selected xmplaylist record timestamp 2026-04-20T02:02:59.815Z for play timestamp 1776650719.706
[26-04-19 22:08:16.2378] Plugins::SiriusXM::APImetadata::_processResponse (314) Metadata source selection: matched record at/before play timestamp
[26-04-19 22:08:16.2379] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (361) Updating metadata for client b8:27:eb:d9:dd:0e: When Did You Get Hot? by Sabrina Carpenter
[26-04-19 22:08:16.2380] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (373) Stored metadata for channel thepulse in global cache
[26-04-19 22:08:16.2381] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 22s
[26-04-19 22:08:16.2394] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (131) Player event 'playlist:newsong' for client b8:27:eb:d9:dd:0e, URL:http://localhost:8888/thepulse.m3u8
[26-04-19 22:08:16.2394] Plugins::SiriusXM::ProtocolHandler::_stopMetadataTimer (226) Stopping metadata timer for client b8:27:eb:d9:dd:0e
[26-04-19 22:08:16.2395] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (169) No current player state, configuring
[26-04-19 22:08:16.2404] Plugins::SiriusXM::APImetadata::fetchMetadata (192) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 22:08:16.4054] Plugins::SiriusXM::APImetadata::_processResponse (254) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.4056] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (413) Read play timestamp '2026-04-20T02:05:39.706+00:00' (1776650719.706) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.4059] Plugins::SiriusXM::APImetadata::_processResponse (292) Next xmplaylist track timestamp raw delay=21.1409997940063s rounded=22s
[26-04-19 22:08:16.4059] Plugins::SiriusXM::APImetadata::_processResponse (298) Selected xmplaylist record timestamp 2026-04-20T02:02:59.815Z for play timestamp 1776650719.706
[26-04-19 22:08:16.4059] Plugins::SiriusXM::APImetadata::_processResponse (314) Metadata source selection: matched record at/before play timestamp
[26-04-19 22:08:16.4060] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (361) Updating metadata for client b8:27:eb:d9:dd:0e: When Did You Get Hot? by Sabrina Carpenter
[26-04-19 22:08:16.4060] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (373) Stored metadata for channel thepulse in global cache
[26-04-19 22:08:16.4061] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 22s
[26-04-19 22:08:16.4074] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (131) Player event 'playlist:newsong' for client b8:27:eb:d9:dd:0e, URL:http://localhost:8888/thepulse.m3u8
[26-04-19 22:08:16.4075] Plugins::SiriusXM::ProtocolHandler::_stopMetadataTimer (226) Stopping metadata timer for client b8:27:eb:d9:dd:0e
[26-04-19 22:08:16.4076] Plugins::SiriusXM::ProtocolHandler::onPlayerEvent (169) No current player state, configuring
[26-04-19 22:08:16.4088] Plugins::SiriusXM::APImetadata::fetchMetadata (192) Fetching metadata from xmplaylist.com for channel: thepulse
[26-04-19 22:08:16.5787] Plugins::SiriusXM::APImetadata::_processResponse (254) Checking PDT file for SiriusXM channel id thepulse: /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.5793] Plugins::SiriusXM::APImetadata::_readPlayTimestampFromFile (413) Read play timestamp '2026-04-20T02:05:39.706+00:00' (1776650719.706) from /tmp/siriusxm/pdt_thepulse.txt
[26-04-19 22:08:16.5797] Plugins::SiriusXM::APImetadata::_processResponse (292) Next xmplaylist track timestamp raw delay=21.1409997940063s rounded=22s
[26-04-19 22:08:16.5797] Plugins::SiriusXM::APImetadata::_processResponse (298) Selected xmplaylist record timestamp 2026-04-20T02:02:59.815Z for play timestamp 1776650719.706
[26-04-19 22:08:16.5797] Plugins::SiriusXM::APImetadata::_processResponse (314) Metadata source selection: matched record at/before play timestamp
[26-04-19 22:08:16.5798] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (361) Updating metadata for client b8:27:eb:d9:dd:0e: When Did You Get Hot? by Sabrina Carpenter
[26-04-19 22:08:16.5798] Plugins::SiriusXM::ProtocolHandler::_updateClientMetadata (373) Stored metadata for channel thepulse in global cache
[26-04-19 22:08:16.5799] Plugins::SiriusXM::ProtocolHandler::_scheduleNextMetadataUpdate (310) Scheduling next metadata update for client b8:27:eb:d9:dd:0e in 22s

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 20, 2026

@copilot when stopping a stream the metadata does not stop, but gets put in an infinite refresh loop. See attached log

...

Fixed in commit 7cc5f2e (core guard added in 5d4f0b7).

I added a play-state guard in ProtocolHandler::onPlayerEvent so metadata state is not re-initialized when the client is stopped/not playing, which prevents the stop-time infinite refresh loop. No UI changes were made.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 20, 2026

@copilot The last refresh loop issue was due to the way timers are set. Before this Pull Request, the timer was set before updating metadata asynchronously. So stopping a player while the async refresh was happening, would properly clear the timer, and when the async metadata exited, no new timer was set.

In this PR the next timer is not set until after the async metadata refresh occurs. The playstate safeguard in the last commit appears to work properly, but can you check that other things are not affected by the asynchronous updates of metadata, potentially exiting after a player state change.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 20, 2026

@copilot The last refresh loop issue was due to the way timers are set. Before this Pull Request, the timer was set before updating metadata asynchronously. So stopping a player while the async ref...

Checked and hardened this path in commit e01d866.

I added async callback state-safety guards so a metadata response is ignored if player state was removed/superseded, playback has stopped, or channel changed before the callback returns. I also bound each async request to a per-state request sequence token so stale responses cannot update metadata or schedule the next timer after a state transition.

No UI changes were made.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 21, 2026

@copilot we are polling xmplaylist every 25 seconds until we find new metadata for the next track. We then set the timer to the difference. We should also save that metadata state so that when that timer times we can just set the metadata to what was found, rather than reading the pdt file and polling xmplaylist again for new information. Reading the pdt file and polling xmplaylist.com would resume at the next refresh time of 25s.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 21, 2026

@copilot we are polling xmplaylist every 25 seconds until we find new metadata for the next track. We then set the timer to the difference. We should also save that metadata state so that when that...

Implemented in commit b51fd3b (core caching behavior introduced in 36c4fdd).

We now cache the nearest future track metadata returned by xmplaylist along with its delay, and when that delay timer fires we apply the cached metadata directly (no PDT read, no xmplaylist poll). After that local apply, metadata refresh resumes on the normal 25s polling interval.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Align xmplaylist metadata selection and adaptive refresh timing with play-behind-live timestamp Align xmplaylist metadata selection, adaptive refresh timing, and cached next-track transitions with play-behind-live timestamp Apr 21, 2026
@paul-1 paul-1 marked this pull request as ready for review April 22, 2026 23:24
@paul-1 paul-1 merged commit 5779f1d into main Apr 22, 2026
1 check passed
@paul-1 paul-1 deleted the copilot/implement-play-behind-live-support branch April 22, 2026 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants