mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-07-29 01:01:34 -07:00
fix: stop stale YouTube cache downloads
This commit is contained in:
@@ -3,5 +3,5 @@ area: youtube
|
|||||||
|
|
||||||
- Improved YouTube card media generation by sending safer ffmpeg request options for resolved streams and skipping stale stream maps, including cached YouTube files.
|
- Improved YouTube card media generation by sending safer ffmpeg request options for resolved streams and skipping stale stream maps, including cached YouTube files.
|
||||||
- Added `youtube.mediaCache.mode` with `direct` and `background` modes so YouTube card audio/image extraction can optionally use a background yt-dlp media cache when direct stream extraction is unreliable; background mode now announces cache download start/readiness through queued overlay/OSD notifications, creates text-only cards while the cache downloads, queues media updates for the mined note IDs, fills audio/image fields once the cached file is ready, and caps background downloads at `youtube.mediaCache.maxHeight` 720p by default while honoring height changes between downloads.
|
- Added `youtube.mediaCache.mode` with `direct` and `background` modes so YouTube card audio/image extraction can optionally use a background yt-dlp media cache when direct stream extraction is unreliable; background mode now announces cache download start/readiness through queued overlay/OSD notifications, creates text-only cards while the cache downloads, queues media updates for the mined note IDs, fills audio/image fields once the cached file is ready, and caps background downloads at `youtube.mediaCache.maxHeight` 720p by default while honoring height changes between downloads.
|
||||||
- Cleaned stale YouTube background media cache files on startup and before new background downloads so only the active cached media file remains.
|
- Cleaned stale YouTube background media cache files on startup and before new background downloads, and stopped in-flight background downloads when switching back to direct mode.
|
||||||
- Hardened YouTube media cache downloads with IPv4/extractor retry flags and made failed background downloads notify users and clear queued media updates instead of leaving them pending silently.
|
- Hardened YouTube media cache downloads with IPv4/extractor retry flags and made failed background downloads notify users and clear queued media updates instead of leaving them pending silently.
|
||||||
|
|||||||
@@ -149,6 +149,49 @@ test('YouTube media cache clears the active cache when direct mode starts', asyn
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('YouTube media cache cancels the active download when direct mode starts', async () => {
|
||||||
|
const cacheRoot = makeTempCacheRoot();
|
||||||
|
const spawnedProcesses: FakeYtDlpProcess[] = [];
|
||||||
|
const spawnCalls: SpawnCall[] = [];
|
||||||
|
const readyEvents: Array<{ url: string; path: string }> = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cache = createYoutubeMediaCacheService({
|
||||||
|
cacheRoot,
|
||||||
|
getYtDlpCommand: () => 'yt-dlp',
|
||||||
|
onReady: (event) => {
|
||||||
|
readyEvents.push(event);
|
||||||
|
},
|
||||||
|
spawn: (command, args, options) => {
|
||||||
|
spawnCalls.push({ command, args, options });
|
||||||
|
const proc = new FakeYtDlpProcess();
|
||||||
|
spawnedProcesses.push(proc);
|
||||||
|
return proc;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
cache.start('https://youtu.be/background', { mode: 'background' });
|
||||||
|
const outputTemplate = spawnCalls[0]?.args[spawnCalls[0].args.indexOf('-o') + 1];
|
||||||
|
assert.equal(typeof outputTemplate, 'string');
|
||||||
|
const outputDir = path.dirname(outputTemplate!);
|
||||||
|
const outputPath = path.join(outputDir, 'media.mkv');
|
||||||
|
fs.mkdirSync(outputDir, { recursive: true });
|
||||||
|
fs.writeFileSync(outputPath, 'cached media');
|
||||||
|
|
||||||
|
cache.start('https://youtu.be/direct', { mode: 'direct' });
|
||||||
|
spawnedProcesses[0]?.emit('close', 0);
|
||||||
|
|
||||||
|
await new Promise((resolve) => setImmediate(resolve));
|
||||||
|
|
||||||
|
assert.equal(spawnedProcesses[0]?.killed, true);
|
||||||
|
assert.deepEqual(readyEvents, []);
|
||||||
|
assert.equal(await cache.getActiveCachedMediaPath(), null);
|
||||||
|
assert.equal(await cache.getCachedMediaPath('https://youtu.be/background'), null);
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(cacheRoot, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('YouTube media cache reports failed background downloads', async () => {
|
test('YouTube media cache reports failed background downloads', async () => {
|
||||||
const cacheRoot = makeTempCacheRoot();
|
const cacheRoot = makeTempCacheRoot();
|
||||||
const spawnedProcesses: FakeYtDlpProcess[] = [];
|
const spawnedProcesses: FakeYtDlpProcess[] = [];
|
||||||
|
|||||||
@@ -197,6 +197,12 @@ export function createYoutubeMediaCacheService(deps: YoutubeMediaCacheServiceDep
|
|||||||
|
|
||||||
const start = (url: string, options: YoutubeMediaCacheStartOptions): void => {
|
const start = (url: string, options: YoutubeMediaCacheStartOptions): void => {
|
||||||
if (options.mode !== 'background') {
|
if (options.mode !== 'background') {
|
||||||
|
if (activeKey) {
|
||||||
|
const activeSession = sessions.get(activeKey);
|
||||||
|
if (activeSession?.state === 'running') {
|
||||||
|
removeSession(activeKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
activeKey = null;
|
activeKey = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user