Skip to content

Commit c801703

Browse files
update: add bandwidth estimator for sabr segments
youtube will adapt itself for your connection now
1 parent c95d81a commit c801703

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

src/sources/youtube/sabr.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ export class SabrStream extends PassThrough {
301301
this.enableTrafficDump = true;
302302
this.trafficDumpMaxBytes = 64 * 1024;
303303

304+
this.bandwidthEstimate = 5000000;
305+
this.lastBandwidthLogAt = 0;
306+
304307
this.noMediaStreak = 0;
305308
this.abortController = new AbortController();
306309

@@ -319,6 +322,21 @@ export class SabrStream extends PassThrough {
319322
void appendFile(this.trafficLogPath, JSON.stringify(entry) + '\n').catch(() => {});
320323
}
321324

325+
updateBandwidthEstimate(bytes, durationMs) {
326+
if (bytes <= 0 || durationMs <= 0) return;
327+
328+
const bits = bytes * 8;
329+
const throughput = (bits / durationMs) * 1000;
330+
331+
const alpha = 0.15;
332+
this.bandwidthEstimate = (alpha * throughput) + ((1 - alpha) * this.bandwidthEstimate);
333+
334+
if (Date.now() - this.lastBandwidthLogAt > 2000) {
335+
this.lastBandwidthLogAt = Date.now();
336+
logger('debug', 'SABR', `Bandwidth Update: measured=${(throughput/1000000).toFixed(2)}Mbps est=${(this.bandwidthEstimate/1000000).toFixed(2)}Mbps`);
337+
}
338+
}
339+
322340
start(audioItag) {
323341
const audioFormat = this.formatIds.find(f => f.itag === audioItag);
324342
if (!audioFormat) {
@@ -397,7 +415,7 @@ export class SabrStream extends PassThrough {
397415
try {
398416
await this.fetchAndProcessSegments({
399417
playerTimeMs: Math.floor(this.totalDownloadedMs),
400-
bandwidthEstimate: 15000000,
418+
bandwidthEstimate: Math.max(Math.floor(this.bandwidthEstimate), 500000),
401419
enabledTrackTypesBitfield: 1,
402420
audioTrackId: audioFormat.audioTrackId || "",
403421
playerState: 1n,
@@ -1194,11 +1212,16 @@ export class SabrStream extends PassThrough {
11941212
buffer = ump.compositeBuffer;
11951213
}
11961214
} catch (err) {
1197-
// AbortError (or equivalent) during destroy/abort should not crash the stream.
11981215
if (!(this._aborted || this.destroyed || signal.aborted)) throw err;
11991216
} finally {
12001217
try { await reader.cancel(); } catch {}
12011218
try { reader.releaseLock(); } catch {}
1219+
const totalDuration = Date.now() - t0;
1220+
if (responseBytes > 0 && totalDuration > 0) {
1221+
if (saw.media || responseBytes > 5000) {
1222+
this.updateBandwidthEstimate(responseBytes, totalDuration);
1223+
}
1224+
}
12021225
}
12031226

12041227

0 commit comments

Comments
 (0)