Skip to content

Revert "Recover the total length for formats that omit contentLength (#235)" - #237

Open
lpaiu-cs wants to merge 1 commit into
lavalink-devs:mainfrom
lpaiu-cs:revert-probe
Open

Revert "Recover the total length for formats that omit contentLength (#235)"#237
lpaiu-cs wants to merge 1 commit into
lavalink-devs:mainfrom
lpaiu-cs:revert-probe

Conversation

@lpaiu-cs

Copy link
Copy Markdown
Contributor

Reverts #235, which I opened and which you merged with the reservation that the extra request gives YouTube one more thing to fingerprint. That reservation was right, and the request turns out not to be necessary.

Why it is no longer needed

The probe existed because the stream ended at the first range boundary when a format arrived without a contentLength. The cause is in lavaplayer rather than here: PersistentHttpStream.attemptConnect fills in an unknown length from the response's Content-Length, and since YoutubePersistentHttpStream carries its range in the query, that response is a plain 200 whose Content-Length describes the window rather than the resource. The unknown marker is replaced by one window's worth on the first connect, and the stream stops there.

lavalink-devs/lavaplayer#198 leaves the length alone when the request was narrowed by the subclass. Nothing is needed here: with the length left unknown, CONTENT_LENGTH_UNKNOWN being Long.MAX_VALUE means the clamp in getNextRangeUrl() does not fire, and internalRead's rangeEnd == contentLength check falls through to reconnecting for the next window, which is what carries the stream to the end.

Measured

Lavalink 4.2.2 built against a lavaplayer carrying that fix, running this revert. A 298s track played 297s and ended finished; it was losing 7s before. No MpegAacTrackConsumer EOF in the window, and no probe request anywhere.

The range sequence shows the difference:

range=0-11862014
range=142493-12004507
range=12026824-23888838      <- asks past the end, because no length was ever learned

With #235 in place the same track ended range=12026824-12164812, clamped to a total the probe had fetched.

Sequencing

This should not be merged before lavaplayer#198 lands and Lavalink ships a build carrying it. Until then, this repo running against a released lavaplayer would lose the last seconds of any track that falls back to itag 18 — which is what #235 was fixing. Raising it now so the two can be lined up; happy for it to sit until the other side is in, or to close it and re-open later if that is tidier.

…avalink-devs#235)"

This reverts commit f45bbb7.

The probe compensated for the stream adopting a partial response's
Content-Length as the length of the resource, which is fixed in
lavaplayer instead. With that fix the length simply stays unknown and
the existing range handling carries the stream to the end, so the extra
request is no longer buying anything.
@Ch33zyNut

Copy link
Copy Markdown

Ran into something on my stack that might be worth adding here, missing clen doesn't only truncate the end of a track, but also causes a full mid-track re-resolve and replay from 0:00.

Lavalink 4.2.2, lavaplayer 2.2.6 youtube-source b33460b, clients MUSIC, TV, WEBEMBEDDED, ANDROID_VR, WEB, TVHTML5_SIMPLY, IOS.

Three unique tracks with a total of five track starts

client itag clen dur outcome
TVHTML5 18 absent 226.8 restarted from 0:00 at ~171s
IOS 140 3670368 226.7 played through (this is the re-resolve)
TVHTML5 18 absent 297.4 restarted from 0:00 at ~244s
IOS 140 4813885 297.4 played through (the re-resolve)
TVHTML5 18 13827310 319.3 played through

Row 5 is the control: same client, same itag 18, longest of the three, no restart, because that URL carried a clen. Seems that the discriminator is the missing length, not itag 18 and not duration.

Appears as silent with no TrackException, no TrackEnd, and the reported position keeps advancing past the audio before snapping backwards when it updates. Watching the connections across a restart shows the media connected to one googlevideo host disappear, a brief request to a different Google host, then a new media connection to a different IP, which was a fresh resolve rather than a resumed range request.

Seeking forward after the track starts seems to avoid re-resolve entirely. A track that normally restarts when played straight through will play to the end if the position is moved manually early on, including seeking to before the point where it would otherwise break and allowing it to playthrough.

I couldn't characterize the break point in terms of time, and #235's description of stopping at the first range boundary may be why, since a byte offset would land at a different fraction of every file, which fits the ~75% and ~82% above against the 1.6% in lavaplayer#198. Converting mine to bytes isn't possible from this side, since the affected URLs are the ones with no clen.

Pinning f45bbb7 seems to have fixed it on the tracks that reproduced it reliably.

#234 describes the same missing-length condition as losing only the final seconds.

JustinFreitas added a commit to JustinFreitas/youtube-source that referenced this pull request Sep 9, 2026
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