mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:49:49 +00:00
Merge pull request #1820 from heygen-com/fix/snapshot-remote-video-frames
fix(cli): snapshot renders remote http(s) <video> frames (not just local files)
This commit is contained in:
@@ -355,23 +355,41 @@ async function captureSnapshots(
|
||||
|
||||
const updates: Array<{ videoId: string; dataUri: string }> = [];
|
||||
for (const v of active) {
|
||||
let filePath: string | null = null;
|
||||
// Resolve the <video> src to an FFmpeg input. Prefer a project-local
|
||||
// file (fast, sandboxed); fall back to the absolute http(s) URL for
|
||||
// remote assets (e.g. an S3-hosted clip embedded by an upstream agent)
|
||||
// — FFmpeg reads http(s) input directly, and Chrome-headless can't seek
|
||||
// it either, so without this those videos render blank in snapshots.
|
||||
let ffmpegInput: string | null = null;
|
||||
let inputIsLocal = false;
|
||||
try {
|
||||
const url = new URL(v.src);
|
||||
const decodedPath = decodeURIComponent(url.pathname).replace(/^\//, "");
|
||||
const candidate = resolve(projectDir, decodedPath);
|
||||
const rel = relative(projectDir, candidate);
|
||||
if (!rel.startsWith("..") && !isAbsolute(rel) && existsSync(candidate)) {
|
||||
filePath = candidate;
|
||||
ffmpegInput = candidate;
|
||||
inputIsLocal = true;
|
||||
} else if (url.protocol === "http:" || url.protocol === "https:") {
|
||||
ffmpegInput = url.href;
|
||||
}
|
||||
} catch {
|
||||
/* unresolvable src (e.g. blob:, data:) — skip */
|
||||
}
|
||||
if (!filePath) continue;
|
||||
if (!ffmpegInput) continue;
|
||||
// VP9-alpha detection shells out to ffprobe, which has no timeout.
|
||||
// Only probe local files (filesystem-bounded); for remote URLs skip it
|
||||
// (pass false) so a stalled host can't wedge snapshot in ffprobe before
|
||||
// the bounded extractVideoFrameToBuffer below ever runs. Remote
|
||||
// VP9-alpha overlays aren't a current path — revisit with a bounded
|
||||
// ffprobe if one appears.
|
||||
const useVp9AlphaDecoder = inputIsLocal
|
||||
? await shouldUseVp9AlphaDecoder(ffmpegInput)
|
||||
: false;
|
||||
const png = await extractVideoFrameToBuffer(
|
||||
filePath,
|
||||
ffmpegInput,
|
||||
Math.max(0, v.relTime),
|
||||
await shouldUseVp9AlphaDecoder(filePath),
|
||||
useVp9AlphaDecoder,
|
||||
);
|
||||
if (!png) continue;
|
||||
updates.push({
|
||||
|
||||
Reference in New Issue
Block a user