rm onnx
Some checks failed
ci / test (push) Failing after 3m38s
ci / build (push) Successful in 31m44s

This commit is contained in:
CJ_Clippy 2025-09-26 19:43:27 -08:00
parent b651bbe515
commit 304683ed1a
6 changed files with 49 additions and 389 deletions

View File

@ -1,5 +1,13 @@
# === Build stage ===
FROM node:22 AS builder
# build off of YOLO
FROM ultralytics/ultralytics:8.3.203-cpu AS base
# Get NodeJS
COPY --from=node:22 /usr/local/bin /usr/local/bin
# Get npm
COPY --from=node:22 /usr/local/lib/node_modules /usr/local/lib/node_modules
# Set working directory
WORKDIR /app
@ -10,11 +18,10 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
apt-get update -y && \
apt-get install -y --no-install-recommends \
build-essential \
git \
inotify-tools \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Copy and install dependencies
# Copy and install node package dependencies
COPY package.json package-lock.json ./
RUN npm install --ignore-scripts=false --foreground-scripts --verbose
@ -22,7 +29,7 @@ RUN npm install --ignore-scripts=false --foreground-scripts --verbose
COPY prisma ./prisma
RUN npx prisma generate
# Copy the rest of the code
# Copy the rest of the app code
COPY . .
# Build the app
@ -34,46 +41,43 @@ RUN npm run build
# === Runtime stage ===
FROM node:22-slim AS release
# FROM node:22-slim AS release
# Set working directory
WORKDIR /app
ENV PATH="/app/venv/bin:$PATH"
# ENV PATH="/app/venv/bin:$PATH"
# Install only runtime dependencies
# Install runtime dependencies
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update -y && \
apt-get install -y --no-install-recommends \
ca-certificates \
ffmpeg \
python3 \
python3-venv \
wget \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
RUN python3 -m venv /app/venv
# Install pip dependencies
RUN --mount=type=cache,target=/root/.cache/uv \
python3 -m pip install uv && \
uv pip install torch --index-url https://download.pytorch.org/whl/cpu && \
uv pip install torchvision && \
uv pip install ultralytics && \
uv pip install vcsi
uv pip install --system vcsi
# Install Shaka Packager
ADD https://github.com/shaka-project/shaka-packager/releases/download/v3.4.2/packager-linux-x64 /usr/local/bin/packager
# RUN wget -q https://github.com/shaka-project/shaka-packager/releases/download/v3.4.2/packager-linux-x64 \
# -O /usr/local/bin/packager \
# && chmod +x /usr/local/bin/packager \
# && packager --version
# we can't copy from the shaka-packager image because that's an alpine image missing gcc
# COPY --from=google/shaka-packager:v3.4.2 /usr/bin /usr/local/bin
# Install Shaka Packager
RUN wget -q https://github.com/shaka-project/shaka-packager/releases/download/v3.4.2/packager-linux-x64 \
-O /usr/local/bin/packager \
&& chmod +x /usr/local/bin/packager \
&& packager --version
# Install IPFS Kubo
COPY --from=ipfs/kubo:v0.36.0 /usr/local/bin/ipfs /usr/local/bin/ipfs
RUN ipfs init
# Bundle the vibeui pytorch model
RUN mkdir -p /app/vibeui \
@ -85,20 +89,24 @@ COPY --from=ghcr.io/ggml-org/whisper.cpp:main-e7bf0294ec9099b5fc21f5ba969805dfb2
ENV PATH="$PATH:/app/whisper.cpp/build/bin"
ENV LD_LIBRARY_PATH="/app/whisper.cpp/build/src:/app/whisper.cpp/build/ggml/src:/usr/local/lib:/usr/lib"
# Install b2-cli
RUN wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/download/v4.4.1/b2-linux -O /usr/local/bin/b2 && chmod +x /usr/local/bin/b2
# Install b2-cli & initialize misc
ADD https://github.com/Backblaze/B2_Command_Line_Tool/releases/download/v4.4.1/b2-linux /usr/local/bin/b2
RUN \
chmod +x /usr/local/bin/b2 && \
chmod +x /usr/local/bin/packager && \
ipfs init
# Copy runtime artifacts from builder
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/generated ./generated
COPY --from=builder /app/src ./src
COPY --from=builder /app/graphile.config.ts ./graphile.config.ts
COPY --from=builder /app/crontab ./crontab
# # Copy runtime artifacts from builder
# COPY --from=builder /app/dist ./dist
# COPY --from=builder /app/node_modules ./node_modules
# COPY --from=builder /app/package.json ./package.json
# COPY --from=builder /app/prisma ./prisma
# COPY --from=builder /app/generated ./generated
# COPY --from=builder /app/src ./src
# COPY --from=builder /app/graphile.config.ts ./graphile.config.ts
# COPY --from=builder /app/crontab ./crontab
RUN . /app/venv/bin/activate
# RUN . /app/venv/bin/activate
# Expose the port
EXPOSE 5000

View File

@ -1,12 +1,12 @@
{
"name": "futureporn-our",
"version": "2.8.12",
"version": "2.8.16",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "futureporn-our",
"version": "2.8.12",
"version": "2.8.16",
"dependencies": {
"@aws-sdk/client-s3": "3.726.1",
"@aws-sdk/s3-request-presigner": "^3.844.0",
@ -55,7 +55,6 @@
"nano-spawn": "^1.0.2",
"nanoid": "^5.1.5",
"node-fetch": "^3.3.2",
"onnxruntime-node": "1.22.0-rev",
"pino": "^9.7.0",
"pino-pretty": "^13.0.0",
"rate-limiter-flexible": "^7.1.1",
@ -4899,15 +4898,6 @@
"node": ">=0.4.0"
}
},
"node_modules/adm-zip": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
"integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
"license": "MIT",
"engines": {
"node": ">=12.0"
}
},
"node_modules/aes-decrypter": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.2.tgz",
@ -5301,13 +5291,6 @@
"integrity": "sha512-DrjdVWZemVO4iBf4tiOXjUrY5cNesjzy0t7sIiu2rdl8cOCHRxAgKjSJFc3vBZYYMMmshUAxajl8QQh/uxXTKQ==",
"license": "MIT"
},
"node_modules/boolean": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"license": "MIT"
},
"node_modules/bowser": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
@ -6402,40 +6385,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"license": "MIT",
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@ -6472,12 +6421,6 @@
"node": ">=8"
}
},
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"license": "MIT"
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@ -6630,12 +6573,6 @@
"node": ">= 0.4"
}
},
"node_modules/es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
"license": "MIT"
},
"node_modules/esbuild": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
@ -6703,6 +6640,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@ -7676,23 +7614,6 @@
"process": "^0.11.10"
}
},
"node_modules/global-agent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
"integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
"license": "BSD-3-Clause",
"dependencies": {
"boolean": "^3.0.1",
"es6-error": "^4.1.1",
"matcher": "^3.0.0",
"roarr": "^2.15.3",
"semver": "^7.3.2",
"serialize-error": "^7.0.1"
},
"engines": {
"node": ">=10.0"
}
},
"node_modules/globals": {
"version": "16.3.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz",
@ -7706,22 +7627,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globalthis": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
"integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
"license": "MIT",
"dependencies": {
"define-properties": "^1.2.1",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@ -8018,18 +7923,6 @@
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
@ -8496,12 +8389,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"license": "ISC"
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@ -8741,18 +8628,6 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"license": "ISC"
},
"node_modules/matcher": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
"license": "MIT",
"dependencies": {
"escape-string-regexp": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@ -9234,15 +9109,6 @@
"node": ">=0.10.0"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object-treeify": {
"version": "1.1.33",
"resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz",
@ -9285,29 +9151,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/onnxruntime-common": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.22.0.tgz",
"integrity": "sha512-vcuaNWgtF2dGQu/EP5P8UI5rEPEYqXG2sPPe5j9lg2TY/biJF8eWklTMwlDO08iuXq48xJo0awqIpK5mPG+IxA==",
"license": "MIT"
},
"node_modules/onnxruntime-node": {
"version": "1.22.0-rev",
"resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.22.0-rev.tgz",
"integrity": "sha512-9vh50/mnwauFUex0NYyyLf9pmRp8q6DVMG8K+xtoXv68SSB9bESa1bEbWLqfUncgB3XucQaOV+wfMPcqANMYhQ==",
"hasInstallScript": true,
"license": "MIT",
"os": [
"win32",
"darwin",
"linux"
],
"dependencies": {
"adm-zip": "^0.5.16",
"global-agent": "^3.0.0",
"onnxruntime-common": "1.22.0"
}
},
"node_modules/openapi-types": {
"version": "12.1.3",
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
@ -10226,23 +10069,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/roarr": {
"version": "2.15.4",
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
"integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
"license": "BSD-3-Clause",
"dependencies": {
"boolean": "^3.0.1",
"detect-node": "^2.0.4",
"globalthis": "^1.0.1",
"json-stringify-safe": "^5.0.1",
"semver-compare": "^1.0.0",
"sprintf-js": "^1.1.2"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/rollup": {
"version": "4.45.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.0.tgz",
@ -10396,39 +10222,6 @@
"node": ">=10"
}
},
"node_modules/semver-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
"license": "MIT"
},
"node_modules/serialize-error": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
"license": "MIT",
"dependencies": {
"type-fest": "^0.13.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/serialize-error/node_modules/type-fest": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
@ -10687,12 +10480,6 @@
"node": ">= 10.x"
}
},
"node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
"license": "BSD-3-Clause"
},
"node_modules/ssh2": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz",

View File

@ -1,7 +1,7 @@
{
"name": "futureporn-our",
"private": true,
"version": "2.8.16",
"version": "2.8.17",
"type": "module",
"scripts": {
"dev": "concurrently npm:dev:serve npm:dev:build:server npm:dev:build:client npm:dev:worker npm:dev:compose npm:dev:sftp npm:dev:qbittorrent npm:dev:tailscale",
@ -99,7 +99,6 @@
"nano-spawn": "^1.0.2",
"nanoid": "^5.1.5",
"node-fetch": "^3.3.2",
"onnxruntime-node": "1.22.0-rev",
"pino": "^9.7.0",
"pino-pretty": "^13.0.0",
"rate-limiter-flexible": "^7.1.1",
@ -117,4 +116,4 @@
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
}

View File

@ -11,7 +11,7 @@ const FIXTURE_DIR = resolve(__dirname, 'fixtures');
const DIST_DIR = resolve(__dirname, '..', '..', 'dist');
const VIBEUI_DIR = resolve(DIST_DIR, 'vibeui');
const VIDEO = resolve(FIXTURE_DIR, 'sample.mp4');
const MODEL = resolve(VIBEUI_DIR, 'vibeui.onnx');
const MODEL = resolve(VIBEUI_DIR, 'vibeui.pt');

View File

@ -1,7 +1,6 @@
import { describe, it, expect } from 'vitest';
import fs from 'fs/promises';
import path, { resolve } from 'path';
import ort from 'onnxruntime-node';
import sharp from 'sharp';
import { preprocessImage, inference } from '../utils/vibeui';

View File

@ -1,5 +1,4 @@
import path from 'node:path';
import * as ort from 'onnxruntime-node';
import { nanoid } from "nanoid";
import { join, basename, extname } from "node:path";
import { readFile, writeFile, readdir, mkdir } from 'node:fs/promises';
@ -158,119 +157,6 @@ export async function inference(videoFilePath: string): Promise<string> {
return outputPath // contains labels/ folder and predictions
}
// export async function runModelInference(session: ort.InferenceSession, inputTensor: ort.Tensor): Promise<DetectionOutput[]> {
// const feeds = { input: inputTensor };
// const results = await session.run(feeds);
// // Adjust 'output' to your model's output key
// const outputTensor = results.output;
// return postprocess(outputTensor);
// }
// export async function yoloInference(modelPath: string, videoFilePath: string) {
// const spawn = await getNanoSpawn()
// const uniqueName = nanoid()
// const customProjectDir = 'vibeui' // or any custom folder
// const outputPath = join(env.CACHE_ROOT, customProjectDir, uniqueName)
// const predictionOutput = await spawn('./venv/bin/yolo', [
// 'predict',
// `model=${modelPath}`,
// `source=${videoFilePath}`,
// 'save=False',
// 'save_txt=True',
// 'save_conf=True',
// `project=${customProjectDir}`,
// `name=${uniqueName}`,
// ], {
// cwd: env.VIBEUI_DIR,
// stdio: 'inherit',
// })
// return outputPath // contains labels/ folder and predictions
// logger.info(`prediction output ${predictionOutput}`);
// const funscriptFilePath = await buildFunscript(helpers, predictionOutput, videoFilePath)
// const s3Key = `funscripts/${vodId}.funscript`;
// const s3Url = await uploadFile(s3Client, env.S3_BUCKET, s3Key, funscriptFilePath, "application/json");
// logger.info(`Uploaded funscript to S3: ${s3Url}`);
// logger.info(`Funscript saved to database for vod ${vodId}`);
// }
// export async function vibeuiInference(
// modelPath: string,
// videoFilePath: string
// ): Promise<string> {
// if (!modelPath) throw new Error('missing modelPath, arg0');
// if (!videoFilePath) throw new Error('missing videoFilePath, arg1');
// // Load ONNX model
// logger.info(`Loading ONNX model from ${modelPath}`);
// const session = await ort.InferenceSession.create(modelPath);
// logger.info(`inputNames=${session.inputNames} outputNames=${session.outputNames}`)
// // Prepare output dir
// // const videoExt = extname(videoFilePath);
// // const videoName = basename(videoFilePath, videoExt);
// // const uniqueName = `${videoName}-${nanoid()}`;
// const outputPath = join(env.CACHE_ROOT, nanoid());
// // Extract frames
// const framesDir = join(outputPath, 'frames');
// mkdirSync(framesDir, { recursive: true })
// logger.info(`Extracting video frames from ${videoFilePath} to ${framesDir}...`);
// await extractFrames(videoFilePath, framesDir);
// // Load class names from data.yaml
// const dataYaml = await loadDataYaml(join(env.VIBEUI_DIR, 'data.yaml'));
// const classNames = dataYaml.names;
// // Read all frames and run inference
// const frameFiles = (await readdir(framesDir))
// .filter(f => f.endsWith('.jpg'))
// .sort();
// // logger.info(`frameFiles=${JSON.stringify(frameFiles)}`)
// const detectionsByFrame = new Map<number, DetectionOutput[]>();
// if (frameFiles.length === 0) throw new Error(`No frames extracted! This is likely a bug.`);
// logger.info(`Running inference on ${frameFiles.length} frames...`);
// for (const file of frameFiles) {
// const frameIndex = parseInt(file.match(/(\d+)\.jpg$/)?.[1] ?? '0', 10);
// const imagePath = join(framesDir, file);
// const inputTensor = await preprocessImage(imagePath);
// const detections = await runModelInference(session, inputTensor)
// logger.info(`[frame ${frameIndex}] detections.length = ${detections.length}`);
// detectionsByFrame.set(frameIndex, detections);
// }
// // Write YOLO format label txt files
// await writeLabels(outputPath, detectionsByFrame, classNames);
// // Optionally cleanup frames dir to save space:
// // await rmSync(framesDir, { recursive: true, force: true });
// return outputPath;
// }
/**
* Extracts video metadata (FPS and frame count) using ffprobe.
@ -307,25 +193,6 @@ export async function ffprobe(videoPath: string): Promise<{ fps: number; frames:
// export async function getModelClasses(modelPath: string): Promise<Record<string, string>> {
// const jsonPath = modelPath.replace(/\.onnx$/, '.json');
// try {
// const data = await readJson(jsonPath);
// if (data.labels && typeof data.labels === 'object') {
// // Return the labels object as-is, retaining numeric keys as strings
// return data.labels;
// } else {
// throw new Error('Invalid labels format in JSON');
// }
// } catch (err) {
// logger.error(`Failed to read labels from ${jsonPath}:`, err);
// throw err;
// }
// }
/**
* Loads basic metadata from a video file using ffprobe.