feat: compression 20

This commit is contained in:
2026-09-29 00:31:33 +01:00
parent 006b8ba095
commit dfb2f98b33
4 changed files with 19 additions and 3 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ const COMPRESSION_ROOT = "/app/data/compression";
const ORIGINALS_ROOT = "/originals"; const ORIGINALS_ROOT = "/originals";
const COMPRESSION_JOB_FILE = "job.json"; const COMPRESSION_JOB_FILE = "job.json";
export type CompressionJobStatus = "compressed" | "replacing" | "replaced"; export type CompressionJobStatus = "compressing" | "compressed" | "replacing" | "replaced";
export interface CompressionJob { export interface CompressionJob {
version: 1; version: 1;
+2 -1
View File
@@ -23,7 +23,8 @@ export const runLoggedFfmpegCommand = async (
log.write(`Command: ${resolvedCommand}\n\n`); log.write(`Command: ${resolvedCommand}\n\n`);
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
const child = spawn(resolvedCommand, { shell: true }); // Replace the shell with FFmpeg so `close` signals the encoder's completion.
const child = spawn(`exec ${resolvedCommand}`, { shell: true });
let stderrTail = ""; let stderrTail = "";
let settled = false; let settled = false;
@@ -40,6 +40,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
continue; continue;
} }
if (job.ownerId !== currentUser.id) continue; if (job.ownerId !== currentUser.id) continue;
if (job.status === "compressing") continue;
try { try {
const outputPath = path.join(getCompressionDirectory(job.sourceAssetId), job.outputFileName); const outputPath = path.join(getCompressionDirectory(job.sourceAssetId), job.outputFileName);
+15 -1
View File
@@ -38,18 +38,32 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const inputPath = getOriginalAssetPath(asset.originalPath); const inputPath = getOriginalAssetPath(asset.originalPath);
const outputPath = getCompressionOutputPath(asset.id, asset.originalFileName); const outputPath = getCompressionOutputPath(asset.id, asset.originalFileName);
const outputFileName = outputPath.split("/").pop() || `${asset.id}-compressed.mp4`;
try { try {
await clearCompressionDirectory(asset.id); await clearCompressionDirectory(asset.id);
await ensureCompressionDirectory(asset.id); await ensureCompressionDirectory(asset.id);
const originalStat = await stat(inputPath); const originalStat = await stat(inputPath);
await writeCompressionJob({
version: 1,
ownerId: currentUser.id,
sourceAssetId: asset.id,
originalFileName: asset.originalFileName,
originalPath: asset.originalPath,
localDateTime: asset.localDateTime.toISOString(),
originalSize: originalStat.size,
outputFileName,
compressedSize: 0,
compressedAt: new Date().toISOString(),
status: "compressing",
});
const command = await getFfmpegCommand(currentUser.id); const command = await getFfmpegCommand(currentUser.id);
const runLoggedFfmpegCommand: typeof runFfmpegCommand = const runLoggedFfmpegCommand: typeof runFfmpegCommand =
(await import("@/helpers/ffmpeg-log.server")).runLoggedFfmpegCommand; (await import("@/helpers/ffmpeg-log.server")).runLoggedFfmpegCommand;
await runLoggedFfmpegCommand(command, inputPath, outputPath); await runLoggedFfmpegCommand(command, inputPath, outputPath);
const outputStat = await stat(outputPath); const outputStat = await stat(outputPath);
const outputFileName = outputPath.split("/").pop() || `${asset.id}-compressed.mp4`;
await writeCompressionJob({ await writeCompressionJob({
version: 1, version: 1,