Add Phase B: cookies, aria2c, proxy/rate-limit, restrict-filenames & archive
Implements the remaining Phase B (Access & networking) items from ROADMAP.md: cookie sources (browser cookie-store import, or a built-in sign-in window that exports a Netscape cookie file via a persisted Electron session partition), the aria2c external downloader, proxy/rate-limit, restrict-filenames, and a download-archive to skip repeats. Wires download.ts to the buildArgs() module added in the previous commit (it wasn't hooked up yet) and renames its options param NetworkOptions -> AccessOptions to reflect the wider scope now that cookies and filename/archive flags joined proxy/rate-limit/aria2c. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+46
-2
@@ -11,7 +11,8 @@
|
||||
import {
|
||||
BEST_FORMAT_ID,
|
||||
type StartDownloadOptions,
|
||||
type DownloadOptions
|
||||
type DownloadOptions,
|
||||
type CookieBrowser
|
||||
} from '@shared/ipc'
|
||||
|
||||
// --- Quality → yt-dlp selector mapping --------------------------------------
|
||||
@@ -76,6 +77,47 @@ export const CROP_SQUARE_PPA =
|
||||
'EmbedThumbnail+ffmpeg_o:-c:v mjpeg -vf ' +
|
||||
'crop="\'if(gt(ih,iw),iw,ih)\':\'if(gt(iw,ih),ih,iw)\'"'
|
||||
|
||||
/**
|
||||
* Phase B "Access & networking" settings — not per-download options, always
|
||||
* applied from the global settings (there's no per-download override for
|
||||
* these, unlike DownloadOptions).
|
||||
*/
|
||||
export interface AccessOptions {
|
||||
/** yt-dlp --proxy value; empty disables it */
|
||||
proxy: string
|
||||
/** yt-dlp --limit-rate value, e.g. '2M'; empty means unlimited */
|
||||
rateLimit: string
|
||||
/** absolute path to aria2c.exe; omit to use yt-dlp's built-in downloader */
|
||||
aria2cPath?: string
|
||||
/** read auth cookies from an installed browser's own cookie store */
|
||||
cookiesFromBrowser?: CookieBrowser
|
||||
/** absolute path to a Netscape-format cookie file (the sign-in window's export) */
|
||||
cookiesFile?: string
|
||||
/** sanitize output filenames to a portable ASCII-only subset */
|
||||
restrictFilenames: boolean
|
||||
/** absolute path to a --download-archive file; omit to disable archive tracking */
|
||||
downloadArchivePath?: string
|
||||
}
|
||||
|
||||
// Tuned for typical CDN-served video: 16 connections split across 16 segments,
|
||||
// each at least 1MB so tiny files don't get split pointlessly.
|
||||
export const ARIA2C_ARGS = 'aria2c:-x 16 -s 16 -k 1M'
|
||||
|
||||
function accessArgs(a: AccessOptions): string[] {
|
||||
const args: string[] = []
|
||||
if (a.proxy.trim()) args.push('--proxy', a.proxy.trim())
|
||||
if (a.rateLimit.trim()) args.push('--limit-rate', a.rateLimit.trim())
|
||||
if (a.aria2cPath) args.push('--downloader', a.aria2cPath, '--downloader-args', ARIA2C_ARGS)
|
||||
// cookiesFromBrowser and cookiesFile are mutually exclusive sources — the UI
|
||||
// only ever sets one (driven by Settings.cookieSource), but browser wins if
|
||||
// a caller somehow sets both.
|
||||
if (a.cookiesFromBrowser) args.push('--cookies-from-browser', a.cookiesFromBrowser)
|
||||
else if (a.cookiesFile) args.push('--cookies', a.cookiesFile)
|
||||
if (a.restrictFilenames) args.push('--restrict-filenames')
|
||||
if (a.downloadArchivePath) args.push('--download-archive', a.downloadArchivePath)
|
||||
return args
|
||||
}
|
||||
|
||||
/** Subtitle / SponsorBlock / chapter / metadata flags shared by both kinds. */
|
||||
function postProcessArgs(opts: StartDownloadOptions, o: DownloadOptions): string[] {
|
||||
const args: string[] = []
|
||||
@@ -109,7 +151,8 @@ export function buildArgs(
|
||||
opts: StartDownloadOptions,
|
||||
outputTemplate: string,
|
||||
o: DownloadOptions,
|
||||
binDir: string
|
||||
binDir: string,
|
||||
access: AccessOptions
|
||||
): string[] {
|
||||
const args = [
|
||||
'--newline',
|
||||
@@ -130,6 +173,7 @@ export function buildArgs(
|
||||
'--no-simulate'
|
||||
]
|
||||
|
||||
args.push(...accessArgs(access))
|
||||
args.push(...postProcessArgs(opts, o))
|
||||
|
||||
if (opts.kind === 'audio') {
|
||||
|
||||
Reference in New Issue
Block a user