mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
added and fix some of things
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
@@ -99,4 +99,52 @@ function remuxToFaststartMp4(inputUrl, { timeoutMs = 30 * 60 * 1000 } = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { needsRemux, remuxToFaststartMp4 };
|
||||
// Grabs a single frame from a video as a JPEG thumbnail — used when a video
|
||||
// asset lands with no client-provided thumbnail (see finalizeAssetFromStorage
|
||||
// in assets.controller.js). Unlike remuxToFaststartMp4 above, this is cheap
|
||||
// enough (one frame, not a full re-encode/copy) to run inline during the
|
||||
// upload-finalize request rather than as a background job.
|
||||
//
|
||||
// input: presigned GET URL for the video, + its duration (seconds, from
|
||||
// ffprobe) to pick a safe seek point.
|
||||
// output: local filesystem path to the extracted .jpg (caller owns cleanup).
|
||||
function extractFrameThumbnail(inputUrl, duration, { timeoutMs = 30 * 1000 } = {}) {
|
||||
// Seek 1s in, or the midpoint for clips shorter than ~2s — avoids grabbing
|
||||
// frame 0, which is often black/blank on screen recordings and slates.
|
||||
const atSeconds = !duration || duration <= 0 ? 0 : Math.min(1, duration / 2);
|
||||
const outputPath = path.join(os.tmpdir(), `thumb_${Date.now()}_${crypto.randomBytes(4).toString("hex")}.jpg`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let settled = false;
|
||||
|
||||
const command = ffmpeg(inputUrl)
|
||||
.seekInput(atSeconds) // input-side seek — fast, keyframe-based
|
||||
.outputOptions(["-frames:v 1", "-q:v 2"]);
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
command.kill("SIGKILL");
|
||||
fs.promises.unlink(outputPath).catch(() => {});
|
||||
reject(new Error(`Thumbnail extraction timed out after ${timeoutMs}ms`));
|
||||
}, timeoutMs);
|
||||
|
||||
command
|
||||
.on("error", (err) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
fs.promises.unlink(outputPath).catch(() => {});
|
||||
reject(err);
|
||||
})
|
||||
.on("end", () => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
resolve(outputPath);
|
||||
})
|
||||
.save(outputPath);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { needsRemux, remuxToFaststartMp4, extractFrameThumbnail };
|
||||
|
||||
Reference in New Issue
Block a user