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 = [...@@ -394,7 +394,6 @@ const imageSubsets = [
394const procImageSubsets: Process = { 394const procImageSubsets: Process = {
395 name: "encode image subsets", 395 name: "encode image subsets",
396 include: rules.extsImage, 396 include: rules.extsImage,
397 enable: false,
398 depends: ["calculate dimensions"], 397 depends: ["calculate dimensions"],
399 async run({ absPath, mediaFile, stat, spin }) { 398 async run({ absPath, mediaFile, stat, spin }) {
400 const { width, height } = UNWRAP(mediaFile.parseDimensions()); 399 const { width, height } = UNWRAP(mediaFile.parseDimensions());
...@@ -443,11 +442,75 @@ const procImageSubsets: Process = {...@@ -443,11 +442,75 @@ const procImageSubsets: Process = {
443 }, 442 },
444}; 443};
445 444
446const videoFormats = [ 445type VideoEncodePreset = {
447 { 446 id: string;
448 name: "webm", 447 codec: "av1";
449 }, 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 },
450]; 478];
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));
451 514
452const processors = [ 515const processors = [
453 procDimensions, 516 procDimensions,
...@@ -455,6 +518,7 @@ const processors = [...@@ -455,6 +518,7 @@ const processors = [
455 procLoadTextContents, 518 procLoadTextContents,
456 procHighlightCode, 519 procHighlightCode,
457 procImageSubsets, 520 procImageSubsets,
521 ...procVideos,
458] 522]
459 .map((process, id, all) => { 523 .map((process, id, all) => {
460 const strIndex = (id: number) => 524 const strIndex = (id: number) =>
...@@ -581,6 +645,7 @@ import * as path from "node:path";...@@ -581,6 +645,7 @@ import * as path from "node:path";
581import * as child_process from "node:child_process"; 645import * as child_process from "node:child_process";
582import * as util from "node:util"; 646import * as util from "node:util";
583import * as crypto from "node:crypto"; 647import * as crypto from "node:crypto";
648import * as os from "node:os";
584 649
585import { MediaFile, MediaFileKind } from "@/file-viewer/models/MediaFile.ts"; 650import { MediaFile, MediaFileKind } from "@/file-viewer/models/MediaFile.ts";
586import { AssetRef } from "@/file-viewer/models/AssetRef.ts"; 651import { AssetRef } from "@/file-viewer/models/AssetRef.ts";