Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 08fef051b78888d31baeb4f784d9c91a1553df4c
parent b99630d909dab9bfca1e0cdb36a9898d92a562a4
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sun,  4 Oct 2026 16:09:37 -0400

common: video_720 download preset; clipFormatSelector moves to downloadFormat; source-video quality resolver

video_720 resolves to the 720p clip selector, then the same at 480p, then
bv*+ba/b. clipFormatSelector now lives in downloadFormat.ts and
fetchWindowManaged.ts re-exports it. SourceVideoQuality (original |
video_720), sourceVideoFormatSelector and resolveSourceVideoQuality
(override > channel > global > original) are the one effective-quality API.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Acommon/ytdlp/downloadFormat.test.ts | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcommon/ytdlp/downloadFormat.ts | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mcommon/ytdlp/fetchWindowManaged.ts | 23++++-------------------
3 files changed, 200 insertions(+), 21 deletions(-)

diff --git a/common/ytdlp/downloadFormat.test.ts b/common/ytdlp/downloadFormat.test.ts @@ -0,0 +1,86 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { + DOWNLOAD_FORMAT_LABELS, + DOWNLOAD_FORMAT_PRESETS, + ORIGINAL_SOURCE_FORMAT_SELECTOR, + SOURCE_VIDEO_QUALITIES, + VIDEO_720_PRESET, + clipFormatSelector, + isDownloadFormatPreset, + isSourceVideoQuality, + resolveDownloadFormatSelector, + resolveSourceVideoQuality, + sourceVideoFormatSelector, +} from "./downloadFormat"; +import { clipFormatSelector as reexported } from "./fetchWindowManaged"; + +// Run with: +// pnpm --filter yt-dlp-transcript-common exec tsx --test ytdlp/downloadFormat.test.ts + +const CLIP_720 = + "bv*[vcodec^=avc1][height<=720]+ba[acodec^=mp4a]/" + + "bv*[ext=mp4][height<=720]+ba[ext=m4a]/" + + "b[ext=mp4][height<=720]/" + + "b[height<=720]"; +const CLIP_480 = CLIP_720.replaceAll("720", "480"); + +test("clipFormatSelector is the selector umtool uses, and the old import path still serves it", () => { + assert.equal(clipFormatSelector(720), CLIP_720); + assert.equal(reexported, clipFormatSelector); +}); + +test("video_720: the 720 rungs, then the 480 rungs, then the last resort", () => { + assert.equal(VIDEO_720_PRESET, "video_720"); + assert.ok(isDownloadFormatPreset("video_720")); + assert.ok(DOWNLOAD_FORMAT_PRESETS.includes("video_720")); + assert.equal(DOWNLOAD_FORMAT_LABELS.video_720, "Video 720p (H.264, for clips/editing)"); + const expected = `${CLIP_720}/${CLIP_480}/bv*+ba/b`; + assert.equal(resolveDownloadFormatSelector("video_720", null), expected); + // An explicit preset ignores the platform, as every explicit preset does. + assert.equal(resolveDownloadFormatSelector("video_720", "odysee"), expected); +}); + +test("the existing presets resolve exactly as before", () => { + assert.equal(resolveDownloadFormatSelector("auto", "youtube"), "bestaudio/worst"); + assert.equal(resolveDownloadFormatSelector("auto", "odysee"), "original/bestaudio/worst"); + assert.equal(resolveDownloadFormatSelector("original", null), "original/bestaudio/worst"); + assert.equal(resolveDownloadFormatSelector("bestaudio", null), "bestaudio/worst"); + assert.equal(resolveDownloadFormatSelector("bestvideo_audio", null), "bestvideo*+bestaudio/best"); +}); + +test("sourceVideoFormatSelector: original is today's persist selector, byte for byte", () => { + assert.deepEqual([...SOURCE_VIDEO_QUALITIES], ["original", "video_720"]); + assert.equal(ORIGINAL_SOURCE_FORMAT_SELECTOR, "bestvideo*+bestaudio/best"); + assert.equal(sourceVideoFormatSelector("original"), "bestvideo*+bestaudio/best"); + assert.equal( + sourceVideoFormatSelector("video_720"), + resolveDownloadFormatSelector("video_720", null), + ); +}); + +test("resolveSourceVideoQuality: override beats channel beats global; original when unset", () => { + assert.equal(resolveSourceVideoQuality({}), "original"); + assert.equal(resolveSourceVideoQuality({ global: "video_720" }), "video_720"); + // The channel wins over the global, either way round. + assert.equal( + resolveSourceVideoQuality({ channel: "original", global: "video_720" }), + "original", + ); + assert.equal( + resolveSourceVideoQuality({ channel: "video_720", global: "original" }), + "video_720", + ); + assert.equal( + resolveSourceVideoQuality({ override: "original", channel: "video_720", global: "video_720" }), + "original", + ); + // Junk at any level falls through to the next, never reaching yt-dlp. + assert.equal( + resolveSourceVideoQuality({ override: "1080p", channel: undefined, global: "video_720" }), + "video_720", + ); + assert.equal(resolveSourceVideoQuality({ override: "", channel: 720 }), "original"); + assert.ok(isSourceVideoQuality("video_720")); + assert.ok(!isSourceVideoQuality("bestvideo_audio")); +}); diff --git a/common/ytdlp/downloadFormat.ts b/common/ytdlp/downloadFormat.ts @@ -9,13 +9,20 @@ export type DownloadFormatPreset = | "auto" | "original" | "bestaudio" - | "bestvideo_audio"; + | "bestvideo_audio" + | "video_720"; + +// The clip/editing preset's id, named once for every caller that asks for it +// by name (the persist control, the source-video quality setting, the batch +// persist and the clip fetch). +export const VIDEO_720_PRESET = "video_720" as const; export const DOWNLOAD_FORMAT_PRESETS: ReadonlyArray<DownloadFormatPreset> = [ "auto", "original", "bestaudio", "bestvideo_audio", + VIDEO_720_PRESET, ]; export function isDownloadFormatPreset( @@ -33,8 +40,46 @@ export const DOWNLOAD_FORMAT_LABELS: Record<DownloadFormatPreset, string> = { original: "Original (full file)", bestaudio: "Best audio only", bestvideo_audio: "Best video + audio", + video_720: "Video 720p (H.264, for clips/editing)", }; +// THE FORMAT SELECTOR A CLIP IS CUT FROM, and why it is not "bestvideo_audio". +// +// "bestvideo_audio" answers "what should we ARCHIVE" — best available, +// container-agnostic. This answers "what can ffmpeg cut and re-encode cheaply, +// right now". Those differ on one specific trap: left alone yt-dlp picks +// VP9+Opus at these heights, and since --force-keyframes-at-cuts re-encodes, +// that means libvpx-vp9 — 27 s to cut a 5 s clip, measured — and it writes +// .webm, which it then appends to the -o name. So H.264/AAC in mp4 is pinned, +// with three progressively looser fallbacks. Byte-identical to the selector +// umtool's build-video.mjs uses, on purpose: a window this fetches and a window +// that fetched must be the same file, or the two caches diverge. +// +// Lives here (not in fetchWindowManaged.ts, which re-exports it) because the +// "video_720" preset below is built from it, and a persist must not import the +// clip-window fetch to learn a selector. +export function clipFormatSelector(maxHeight: number): string { + return [ + `bv*[vcodec^=avc1][height<=${maxHeight}]+ba[acodec^=mp4a]`, + `bv*[ext=mp4][height<=${maxHeight}]+ba[ext=m4a]`, + `b[ext=mp4][height<=${maxHeight}]`, + `b[height<=${maxHeight}]`, + ].join("/"); +} + +// The height "video_720" asks for, and the rung it falls back to. +export const VIDEO_720_MAX_HEIGHT = 720; +export const VIDEO_720_FALLBACK_HEIGHT = 480; + +// The last rung of "video_720": anything at all. Reached only when the source +// has nothing the 720 and 480 rungs accept, so a file above 720p is possible — +// the download logs it (downloadOneManaged, logPersistedFormat) rather than +// letting it pass silently. +export const LAST_RESORT_FORMAT_SELECTOR = "bv*+ba/b"; + +// The source container a persist has always taken: best video + best audio. +export const ORIGINAL_SOURCE_FORMAT_SELECTOR = "bestvideo*+bestaudio/best"; + // Resolve a preset into the concrete yt-dlp `-f` selector string. The platform // only matters for "auto"; explicit presets apply literally regardless of // source (so an explicit choice always wins over the per-source default). @@ -48,7 +93,13 @@ export function resolveDownloadFormatSelector( case "bestaudio": return "bestaudio/worst"; case "bestvideo_audio": - return "bestvideo*+bestaudio/best"; + return ORIGINAL_SOURCE_FORMAT_SELECTOR; + case "video_720": + return [ + clipFormatSelector(VIDEO_720_MAX_HEIGHT), + clipFormatSelector(VIDEO_720_FALLBACK_HEIGHT), + LAST_RESORT_FORMAT_SELECTOR, + ].join("/"); case "auto": default: return platform === "odysee" @@ -66,3 +117,60 @@ export function resolveDownloadFormatPreset(opts: { }): DownloadFormatPreset { return opts.override ?? opts.channel ?? opts.global ?? "auto"; } + +// ── SOURCE-VIDEO QUALITY ─────────────────────────────────────────────────── +// +// What a FULL-SOURCE persist downloads: "original" (best video + best audio, +// the behaviour every persist had before this setting) or "video_720" (≤720p +// H.264, for clip and editing work). A separate axis from DownloadFormatPreset: +// that one picks what a download fetches to get AUDIO from; this one picks the +// container a persist keeps. Set globally (settings `sourceVideoQuality`), per +// channel (ChannelConfig.sourceVideoQuality) and per persist (the editor's +// "Persist source video" control). +export type SourceVideoQuality = "original" | typeof VIDEO_720_PRESET; + +export const SOURCE_VIDEO_QUALITIES: ReadonlyArray<SourceVideoQuality> = [ + "original", + VIDEO_720_PRESET, +]; + +export const DEFAULT_SOURCE_VIDEO_QUALITY: SourceVideoQuality = "original"; + +export const SOURCE_VIDEO_QUALITY_LABELS: Record<SourceVideoQuality, string> = { + original: "Original (best video + audio)", + video_720: DOWNLOAD_FORMAT_LABELS.video_720, +}; + +export function isSourceVideoQuality( + value: unknown, +): value is SourceVideoQuality { + return ( + typeof value === "string" && + (SOURCE_VIDEO_QUALITIES as ReadonlyArray<string>).includes(value) + ); +} + +// The `-f` selector a persist at this quality passes. "original" is the +// selector a persist has always used, byte for byte. +export function sourceVideoFormatSelector(quality: SourceVideoQuality): string { + return quality === VIDEO_720_PRESET + ? resolveDownloadFormatSelector(VIDEO_720_PRESET, null) + : ORIGINAL_SOURCE_FORMAT_SELECTOR; +} + +// THE ONE EFFECTIVE-QUALITY RESOLVER. Every surface that persists a full +// source — the persist control, the whole-recording fetch, "Persist kept now", +// the batch persist — asks this, so a channel's choice cannot win on one and +// lose on another. Per-persist override beats the channel beats the global; +// "original" when nothing is set. Each input is checked, so a stale or +// hand-typed value falls through to the next rather than reaching yt-dlp. +export function resolveSourceVideoQuality(opts: { + override?: unknown; + channel?: unknown; + global?: unknown; +}): SourceVideoQuality { + for (const v of [opts.override, opts.channel, opts.global]) { + if (isSourceVideoQuality(v)) return v; + } + return DEFAULT_SOURCE_VIDEO_QUALITY; +} diff --git a/common/ytdlp/fetchWindowManaged.ts b/common/ytdlp/fetchWindowManaged.ts @@ -42,31 +42,16 @@ import { import { channelExtraArgs } from "./channelArgs"; import { runOneYtdlp } from "./runOneYtdlp"; import { FULL_LOG_PROGRESS_ARGS } from "./downloadOneManaged"; +import { clipFormatSelector } from "./downloadFormat"; // The source height a clip is worth fetching at. 720 is umtool's number and the // reason is the render: the deliverable is 1080p with a clip inset, so pixels // above 720 are thrown away after paying for them. export const DEFAULT_CLIP_MAX_HEIGHT = 720; -// THE FORMAT SELECTOR, and why it is not downloadFormatPreset's. -// -// resolveDownloadFormatSelector answers "what should we ARCHIVE" — best -// available, container-agnostic. This answers "what can ffmpeg cut and -// re-encode cheaply, right now". Those differ on one specific trap: left alone -// yt-dlp picks VP9+Opus at these heights, and since --force-keyframes-at-cuts -// re-encodes, that means libvpx-vp9 — 27 s to cut a 5 s clip, measured — and it -// writes .webm, which it then appends to the -o name. So H.264/AAC in mp4 is -// pinned, with three progressively looser fallbacks. Byte-identical to the -// selector umtool's build-video.mjs uses, on purpose: a window this fetches and -// a window that fetched must be the same file, or the two caches diverge. -export function clipFormatSelector(maxHeight: number): string { - return [ - `bv*[vcodec^=avc1][height<=${maxHeight}]+ba[acodec^=mp4a]`, - `bv*[ext=mp4][height<=${maxHeight}]+ba[ext=m4a]`, - `b[ext=mp4][height<=${maxHeight}]`, - `b[height<=${maxHeight}]`, - ].join("/"); -} +// The clip format selector lives with the download presets (the "video_720" +// preset is built from it); re-exported so existing importers keep working. +export { clipFormatSelector }; export type FetchWindowProvenance = { requestedBy: string;