Coalesce concurrent resolveStreams calls for the same video
This commit is contained in:
@@ -459,7 +459,7 @@ function parseExpiry(url) {
|
||||
// Resolve (and briefly cache) a video's playable formats via yt-dlp -J. The
|
||||
// cache spares a fresh ~2-3s yt-dlp run on every Range request the media
|
||||
// element fires; its TTL is bounded a minute inside the URLs' own expiry.
|
||||
async function resolveStreams(videoId) {
|
||||
async function resolveStreamsUncached(videoId) {
|
||||
const now = Date.now();
|
||||
const cached = streamCache.get(videoId);
|
||||
if (cached && now < cached.expiresAt) return cached;
|
||||
@@ -498,6 +498,20 @@ async function resolveStreams(videoId) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
// One yt-dlp -J per video at a time: concurrent callers (warm-up + play,
|
||||
// two devices, the media cache's getInfo) share the in-flight promise.
|
||||
const inflightStreams = new Map(); // videoId -> Promise<entry>
|
||||
function resolveStreams(videoId) {
|
||||
const cached = streamCache.get(videoId);
|
||||
if (cached && Date.now() < cached.expiresAt) return Promise.resolve(cached);
|
||||
let p = inflightStreams.get(videoId);
|
||||
if (!p) {
|
||||
p = resolveStreamsUncached(videoId).finally(() => inflightStreams.delete(videoId));
|
||||
inflightStreams.set(videoId, p);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
const isVideoFmt = (f) => f.vcodec && f.vcodec !== 'none';
|
||||
const isAudioFmt = (f) => f.acodec && f.acodec !== 'none';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user