import { execFile } from 'child_process'; import { mkdtemp, readFile, rm } from 'fs/promises'; import { tmpdir } from 'os'; import { basename, join } from 'path'; import { promisify } from 'util'; const execFileAsync = promisify(execFile); export default async function createVideoPoster(videoPath: string): Promise { if (process.platform !== 'darwin') return null; const outputDirectory = await mkdtemp(join(tmpdir(), 'joplin-video-thumbnail-')); try { await execFileAsync('/usr/bin/qlmanage', ['-t', '-s', '920', '-o', outputDirectory, videoPath], { timeout: 15_000, maxBuffer: 1024 * 1024, }); const thumbnail = await readFile(join(outputDirectory, `${basename(videoPath)}.png`)); return `data:image/png;base64,${thumbnail.toString('base64')}`; } catch { return null; } finally { await rm(outputDirectory, { force: true, recursive: true }); } }