authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-06-27 22:35:03-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-10-14 02:40:45-07:00
log56a1174bf97856be619b2f7526505cc90d6a7161
tree5fb6bbb69746c95656abfa13d429673445029803
parentbba4a6d0d133e1513a1a4acbba1d6f1dd5fdd627
signature Commit is signed but in an unrecognized format.

start av1 encoding ???


1 files changed, 70 insertions(+), 5 deletions(-)

src/file-viewer/bin/scan3.ts+70-5
......@@ -394,7 +394,6 @@ const imageSubsets = [
394394const procImageSubsets: Process = {
395395 name: "encode image subsets",
396396 include: rules.extsImage,
397 enable: false,
398397 depends: ["calculate dimensions"],
399398 async run({ absPath, mediaFile, stat, spin }) {
400399 const { width, height } = UNWRAP(mediaFile.parseDimensions());
......@@ -443,11 +442,75 @@ const procImageSubsets: Process = {
443442 },
444443};
445444
446const videoFormats = [
447 {
448 name: "webm",
449 },
445type VideoEncodePreset = {
446 id: string;
447 codec: "av1";
448 mbit: number;
449 crf?: number;
450 maxHeight?: number;
451 audioKbit?: number;
452} | {
453 id: string;
454 codec: "vp9";
455 mbit: number;
456 maxHeight?: number;
457 audioKbit?: number;
458};
459// const av1Pass1 = [
460// '-c:v', 'libsvtav1 -b:v 2M -pass 1 -svtav1-params "rc=1:tbr=2000000" -preset 8 -f null NUL
461// ];
462// const av1BaseArgs = [
463// ["-c:v", "libsvtav1"],
464// ["-preset", "3"],
465// ["-c:a", "libopus"],
466// ["-b:a", "192k"],
467// ].flat();
468// const webmBaseArgs = [
469// "-c:v",
470// "libsvtav1",
471// ["-vf",],
472// ];
473const presets: VideoEncodePreset[] = [
474 { id: "av1-max", codec: "av1", mbit: 5 },
475 { id: "av1-hq", codec: "av1", mbit: 2, maxHeight: 900 },
476 { id: "av1-md", codec: "av1", mbit: 0.5, maxHeight: 720 },
477 { id: "av1-lq", codec: "av1", mbit: 0.2, maxHeight: 640 },
450478];
479const procVideos = presets.map((preset) => ({
480 name: "encode image subsets",
481 include: rules.extsImage,
482 async run({ absPath, mediaFile, stat, spin }) {
483 await produceAsset(`${mediaFile}/${preset.id}`, (base) => {
484 const root = path.dirname(base);
485 const pass1 = [ffmpeg!, ...ffmpegOptions, "-i", absPath];
486 if (preset.codec === "av1") {
487 pass1.push("-c:v", "libstvav1");
488 pass1.push("-b:v", preset.mbit + "M");
489 if (preset.crf) pass1.push("-crf", preset.crf.toString());
490 pass1.push(
491 "-svtav1-params",
492 ["rc=1", `tbr=${preset.mbit * 1_000_000}`].join(":"),
493 );
494 } else if (preset.codec === "vp9") {
495 pass1.push("-c:v", "libvpx-vp9");
496 } else preset satisfies never;
497
498 if (preset.maxHeight != null) {
499 pass1.push("-vf", `scale=-2:min(${preset.maxHeight}\\,ih)`);
500 }
501
502 const logfile = path.join(preset.id + ".log");
503 pass1.push("-passlogfile", logfile);
504 const pass2 = pass1.slice();
505
506 pass1.push("-f", "null");
507 pass1.push(os.devNull);
508
509 pass2.push("-c:a", "libopus");
510 pass2.push("-b:a", (preset.audioKbit ?? 192) + "k");
511 });
512 },
513} satisfies Process));
451514
452515const processors = [
453516 procDimensions,
......@@ -455,6 +518,7 @@ const processors = [
455518 procLoadTextContents,
456519 procHighlightCode,
457520 procImageSubsets,
521 ...procVideos,
458522]
459523 .map((process, id, all) => {
460524 const strIndex = (id: number) =>
......@@ -581,6 +645,7 @@ import * as path from "node:path";
581645import * as child_process from "node:child_process";
582646import * as util from "node:util";
583647import * as crypto from "node:crypto";
648import * as os from "node:os";
584649
585650import { MediaFile, MediaFileKind } from "@/file-viewer/models/MediaFile.ts";
586651import { AssetRef } from "@/file-viewer/models/AssetRef.ts";