Skip to content

Conversation

@paul-1
Copy link
Owner

@paul-1 paul-1 commented Jan 10, 2026

No description provided.

@paul-1
Copy link
Owner Author

paul-1 commented Jan 10, 2026

@copilot I would like to further optimize this branch.

When the client gets the .m3u8 playlist, it will then request a segment, from this point, I want to precache any remaining segments in the playlist. When the client pulls the next .m3u8 playlist, find the next track that needs cached and proceed.

when the client requests a cached segment, we can use it, then drop it. Playlists, and cached segments should be stored against the current channel_id.

Copy link
Contributor

Copilot AI commented Jan 10, 2026

@paul-1 I've opened a new pull request, #57, to work on those changes. Once the pull request is ready, I'll request review from you.

@paul-1 paul-1 marked this pull request as draft January 10, 2026 18:54
* Initial plan

* Implement segment precaching for playlist optimization

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Address code review feedback for segment precaching

- Fix regex to handle whitespace/control characters after .aac
- Move segment extraction before playlist modification
- Remove noisy trace log of all segments
- Optimize to only search from last requested segment to end
- Add total cache size to logging output

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Add segment count to cache logging

Include number of cached segments in addition to total size in log messages

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>
@paul-1
Copy link
Owner Author

paul-1 commented Jan 10, 2026

@copilot

# Remove the last 3 segments from the playlist if this is the first time weve seen it
# This will make ffmpeg cache a bit more without needing to use command lines options
if ( not exists $self->{playlists}->{$channel_id}->{'First'} or $self->{playlists}->{$channel_id}->{'First'} != 1 ) {
my @lines = split /\n/, $content;
# Find all lines ending with ".aac"
my @aac_lines;
for my $i (0 .. $#lines) {
if ($lines[$i] =~ /\.aac/) {
push @aac_lines, $i;
}
}
# Stop output 4 lines BEFORE the last ".aac" line
my @removed_lines;
if (@aac_lines >= 3) {
# 4th from the end of .aac lines
my $cutoff_line = $aac_lines[-4];
@removed_lines = @lines[($cutoff_line + 1) .. $#lines]; # Get the lines being removed
@lines = @lines[0 .. $cutoff_line]; # Keep only the lines up to that cutoff
}
my $rlines = join("\n", @removed_lines);
main::log_trace("First Playlist, Removed $rlines");
$self->{playlists}->{$channel_id}->{'First'} = 1;
$content = join("\n", @lines);
}

Uses a default of dropping 3 segments to force start further behind live (ffmpeg defaults to 3 segments behind live)

  1. Add a command line option to sxm.pl to set the number of segments to drop, default to 3 if not set.
  2. Add a pref to the plugin and settings page to allow the user to set the number. Probably should not be more than 30, but make the default setting of 3.

Copy link
Contributor

Copilot AI commented Jan 10, 2026

@paul-1 I've opened a new pull request, #58, to work on those changes. Once the pull request is ready, I'll request review from you.

* Initial plan

* Add configurable segment drop for playlist buffering

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Fix code review issues: typo and numeric comparison

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Use string comparison for consistency with other preferences

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Improve comment clarity for segment drop logic

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Change order on settings page

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>
@paul-1
Copy link
Owner Author

paul-1 commented Jan 10, 2026

@copilot There seems to be an issue with pre-caching. I was set to drop 6 segments, so caching of 8 segments seems about right, however as you can see from the log, it does not iterate through all 8 segments and cache them, it is only keeping one or two in the cache, and 6 or so un-cached. Only caching a couple segments at a time is good, such that it does not block client requests, but it should eventually finish getting uncached tracks

10.01.2026 15:42:47.733] INFO <siriusxm.proxy>: Starting precache of 8 segments for channel thepulse, current cache: 1 segments (0.30 MB)
[10.01.2026 15:42:47.733] DEBUG <siriusxm.proxy>: Segments to cache: thepulse_256k_1_011074478456_00603173_v3.aac, thepulse_256k_1_011074488207_00603174_v3.aac, thepulse_256k_1_011074497959_00603175_v3.aac, thepulse_256k_1_011074507710_00603176_v3.aac, thepulse_256k_1_011074517462_00603177_v3.aac, thepulse_256k_1_011074527213_00603178_v3.aac, thepulse_256k_1_011074536964_00603179_v3.aac, thepulse_256k_1_011074546716_00603180_v3.aac
[10.01.2026 15:42:47.733] DEBUG <siriusxm.proxy>: Caching segment: thepulse_256k_1_011074478456_00603173_v3.aac for channel thepulse
[10.01.2026 15:42:47.734] DEBUG <siriusxm.proxy>: [TRACE] Set cookie context for channel: thepulse
[10.01.2026 15:42:47.734] DEBUG <siriusxm.proxy>: [TRACE] SXMAK token for channel thepulse: xxxxxxxxxxxxxxxxxxxxxx
[10.01.2026 15:42:47.734] DEBUG <siriusxm.proxy>: [TRACE] GUP ID for channel thepulse: xxxxxxxxxxxxxxxxxx
[10.01.2026 15:42:47.735] INFO <siriusxm.proxy>: Getting segment: https://siriusxm-priprodlive.akamaized.net/AAC_Data/thepulse/HLS_thepulse_256k_v3/thepulse_256k_1_011074478456_00603173_v3.aac
[10.01.2026 15:42:47.735] DEBUG <siriusxm.proxy>: [TRACE] Channel ID: thepulse, Base path: AAC_Data/thepulse/HLS_thepulse_256k_v3
[10.01.2026 15:42:48.205] INFO <siriusxm.proxy>: Cached segment: thepulse_256k_1_011074478456_00603173_v3.aac (315104 bytes) for channel thepulse
[10.01.2026 15:42:48.206] DEBUG <siriusxm.proxy>: Client connection closed
[10.01.2026 15:42:48.206] DEBUG <siriusxm.proxy>: [TRACE] Server loop iteration, waiting for client connection
[10.01.2026 15:42:48.342] DEBUG <siriusxm.proxy>: Client connected, handling request
[10.01.2026 15:42:48.342] DEBUG <siriusxm.proxy>: GET request: /thepulse_256k_1_011074478456_00603173_v3.aac
[10.01.2026 15:42:48.342] DEBUG <siriusxm.proxy>: Segment request: thepulse_256k_1_011074478456_00603173_v3.aac
[10.01.2026 15:42:48.342] INFO <siriusxm.proxy>: Using cached segment: thepulse_256k_1_011074478456_00603173_v3.aac for channel thepulse
[10.01.2026 15:42:48.342] DEBUG <siriusxm.proxy>: Dropped cached segment: thepulse_256k_1_011074478456_00603173_v3.aac for channel thepulse
[10.01.2026 15:42:48.342] DEBUG <siriusxm.proxy>: Caching segment: thepulse_256k_1_011074488207_00603174_v3.aac for channel thepulse
[10.01.2026 15:42:48.343] DEBUG <siriusxm.proxy>: [TRACE] Set cookie context for channel: thepulse
[10.01.2026 15:42:48.343] DEBUG <siriusxm.proxy>: [TRACE] SXMAK token for channel thepulse: 1768079565_4686d0f7d8993a69dbb122a111cdeba6
[10.01.2026 15:42:48.343] DEBUG <siriusxm.proxy>: [TRACE] GUP ID for channel thepulse: xxxxxxxxxxxxxxxxxxxxxxx
[10.01.2026 15:42:48.343] INFO <siriusxm.proxy>: Getting segment: https://siriusxm-priprodlive.akamaized.net/AAC_Data/thepulse/HLS_thepulse_256k_v3/thepulse_256k_1_011074488207_00603174_v3.aac
[10.01.2026 15:42:48.343] DEBUG <siriusxm.proxy>: [TRACE] Channel ID: thepulse, Base path: AAC_Data/thepulse/HLS_thepulse_256k_v3
[10.01.2026 15:42:48.865] INFO <siriusxm.proxy>: Cached segment: thepulse_256k_1_011074488207_00603174_v3.aac (315104 bytes) for ch

Copy link
Contributor

Copilot AI commented Jan 10, 2026

@paul-1 I've opened a new pull request, #59, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits January 10, 2026 16:42
…59)

* Initial plan

* Fix segment pre-caching to cache multiple segments per iteration

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Refactor segment caching to use named constant and simplified loop

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Change log level

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>
@paul-1
Copy link
Owner Author

paul-1 commented Jan 11, 2026

@copilot I want to pre-cache the m3u8 files too. But we need to do a little tracking and scheduling as to when to get it.

When processing a new m3u8 file,

  • we need to look at the #EXTINF tags, which tells us the duration of each segment. Sxm uses a 10s segment most of the time.
  • We already check to see how many new segments to cache. If there is only one new segment, we need to schedule the next update of the m3u8 file for 9s later. If there are two new segments, we can schedule the update for 18 seconds later and so on.
  • Whatever the lastest version of the m3u8 file is what we return when the client requests it.

Make sure we use the functions in place to get the files from SiriusXM, as they already have proper handling of authentication.

Copy link
Contributor

Copilot AI commented Jan 11, 2026

@paul-1 I've opened a new pull request, #60, to work on those changes. Once the pull request is ready, I'll request review from you.

… timeout, optimizations, HLS compliance, and optional caching control (#60)

* Initial plan

* Implement m3u8 playlist pre-caching with scheduled updates

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Skip scheduling on first playlist load to avoid bulk segment caching delays

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Add idle timeout to stop refresh and clear cache for inactive channels

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* First load was already stored, use that instead.
Fix Copilot Syntax Errors
Remove noisy logging

* Fix playlist scheduling and background refresh issues

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Fix segment caching to be non-blocking and improve scheduling

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Change logging to output line number
Tweak scheduling durations

* Change loop and min/max delays

* Remove the one second, there is a 30s FFmpeg buffer by default.  This lets us get 2 new tracks occasionally.

* Optimize EXTINF parsing, add adaptive backoff, and defer segment caching

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Fix scheduling to work on first load while still deferring segment caching

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Tweak playlist delays

* Disable all caching when segment_drop is 0

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Tweak web page to allow 0 setting, and change some strings

* Trim playlists and use EXT-X-TARGETDURATION for segment duration

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Always trim playlist from beginning, only drop end segments on first load

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Update all playlist parsing to follow Apple HLS specification

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Optimize playlist handling and fix first-load caching behavior

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Change to medium playlist

* Remove playlist middle trimming, keep only segment_drop functionality

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>
@paul-1
Copy link
Owner Author

paul-1 commented Jan 16, 2026

@copilot SiriusXM has two different servers for distributing m3u8 playlists and segments

LIVE_PRIMARY_HLS is the default. LIVE_SECONDAY_HLS is the backup. If we have problems getting data from the primary, we need to seamlessly fail over to the secondary server. Create a method to track which server is currently being used and then a mechanism to switch if one server continues to have problems.

Copy link
Contributor

Copilot AI commented Jan 16, 2026

@paul-1 I've opened a new pull request, #61, to work on those changes. Once the pull request is ready, I'll request review from you.

…points (#61)

* Initial plan

* Implement HLS server failover mechanism

Add seamless failover between LIVE_PRIMARY_HLS and LIVE_SECONDARY_HLS servers:
- Track current active server and consecutive failure counts per server
- Automatically switch to backup server after 3 consecutive failures
- Record success/failure for all playlist and segment requests
- Switch back to primary after 5-minute cooldown period when secondary is stable
- Update all URL construction to use current active server
- Add comprehensive logging for server switches and failures

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Simplify HLS failover and fix playlist selection

Based on feedback, simplified the failover implementation:
- Removed cooldown period logic (no time-based recovery)
- Changed to per-channel failover tracking (not global)
- Reset to primary server when starting new playback session
- Stay on current server for duration of stream

Fixed playlist URL selection:
- Parse playlist array for both primary and secondary entries
- Select appropriate playlist based on channel's current server
- Remove incorrect URL substitution logic
- URLs come pre-formed from SiriusXM API

Implementation now:
- Tracks which server each channel is using (primary/secondary)
- Switches to backup after 3 consecutive failures
- Switches back to primary on opposite server failures
- Automatically resets to primary when playback restarts

Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>

* Minor logging changes

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: paul-1 <6473457+paul-1@users.noreply.github.com>
@paul-1 paul-1 marked this pull request as ready for review January 17, 2026 04:02
@paul-1 paul-1 merged commit 8bfefa3 into main Jan 17, 2026
1 check passed
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