MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / toGif

Function toGif

e2e/scripts/pr-media.ts:235–287  ·  view source on GitHub ↗
(artifact: Artifact)

Source from the content-addressed store, hash-verified

233};
234
235const toGif = async (artifact: Artifact): Promise<string> => {
236 if (artifact.path.endsWith(".png")) return artifact.path;
237 const out = join(tmpdir(), `${artifact.slug}.gif`);
238 if (artifact.path.endsWith(".cast")) {
239 run("agg", ["--idle-time-limit", "2", "--font-size", "14", artifact.path, out]);
240 } else {
241 // Two-pass palette keeps UI text crisp at a size GitHub will render.
242 const duration = videoDuration(artifact.path);
243 const segments = urlSegments(artifact, duration);
244 if (segments.length > 0) {
245 const workDir = mkdtempSync(join(tmpdir(), "pr-media-urlbar-"));
246 try {
247 const bars = await renderUrlBars(segments, workDir);
248 const scaled =
249 `[0:v]fps=8,scale=${GIF_WIDTH}:-2:flags=lanczos,` +
250 `pad=iw:ih+${CHROME_HEIGHT}:0:${CHROME_HEIGHT}:color=0x111318,setsar=1[v0]`;
251 const overlays = bars.map(({ segment }, index) => {
252 const input = index + 1;
253 const previous = `v${index}`;
254 const next = `v${index + 1}`;
255 const from = segment.from.toFixed(3);
256 const to = segment.to.toFixed(3);
257 return `[${previous}][${input}:v]overlay=0:0:enable='between(t,${from},${to})'[${next}]`;
258 });
259 const finalVideo = `v${bars.length}`;
260 const palette =
261 `[${finalVideo}]split[a][b];` +
262 "[a]palettegen=max_colors=128[p];[b][p]paletteuse=dither=bayer:bayer_scale=5[out]";
263 run("ffmpeg", [
264 "-y",
265 "-loglevel",
266 "error",
267 "-i",
268 artifact.path,
269 ...bars.flatMap((bar) => ["-i", bar.path]),
270 "-filter_complex",
271 [scaled, ...overlays, palette].join(";"),
272 "-map",
273 "[out]",
274 out,
275 ]);
276 } finally {
277 rmSync(workDir, { recursive: true, force: true });
278 }
279 } else {
280 const filter =
281 `fps=8,scale=${GIF_WIDTH}:-2:flags=lanczos,split[a][b];` +
282 "[a]palettegen=max_colors=128[p];[b][p]paletteuse=dither=bayer:bayer_scale=5";
283 run("ffmpeg", ["-y", "-loglevel", "error", "-i", artifact.path, "-vf", filter, out]);
284 }
285 }
286 return out;
287};
288
289/** Commit a file to the media branch via the git database API; returns its raw URL. */
290const upload = (repo: string, localPath: string, mediaPath: string): string => {

Callers 1

pr-media.tsFile · 0.85

Calls 4

videoDurationFunction · 0.85
urlSegmentsFunction · 0.85
renderUrlBarsFunction · 0.85
runFunction · 0.70

Tested by

no test coverage detected