// Name: Reduce Video File Size // Description: Use FFmpeg to compress and reduce video file size // Author: zacjones93 import "@johnlindquist/kit" // Check if ffmpeg is available try { await $`ffmpeg -version` } catch (error) { await div(md(` # FFmpeg Not Found Please install FFmpeg first: **macOS (with Homebrew):** \`\`\`bash brew install ffmpeg \`\`\` **Windows:** Download from [https://ffmpeg.org/download.html](https://ffmpeg.org/download.html) **Linux:** \`\`\`bash sudo apt install ffmpeg \`\`\` `)) exit(1) } // Get input video file let inputFile = await getSelectedFile() if (!inputFile) { inputFile = await selectFile("Select a video file to compress") } // Validate it's a video file const videoExtensions = ['.mp4', '.mov', '.avi', '.mkv', '.wmv', '.flv', '.webm', '.m4v'] const fileExtension = path.extname(inputFile).toLowerCase() if (!videoExtensions.includes(fileExtension)) { await div(md(`# Error\n\nSelected file is not a supported video format.\n\nSupported formats: ${videoExtensions.join(', ')}`)) exit(1) } // Choose compression preset const preset = await arg("Choose compression level:", [ { name: "Light Compression (High Quality)", value: "light", description: "CRF 23 - Good balance of quality and size" }, { name: "Medium Compression (Balanced)", value: "medium", description: "CRF 28 - Noticeable compression but good quality" }, { name: "Heavy Compression (Small Size)", value: "heavy", description: "CRF 32 - Significant size reduction, lower quality" }, { name: "Custom CRF Value", value: "custom", description: "Specify your own CRF value (18-51)" } ]) let crfValue switch (preset) { case "light": crfValue = 23 break case "medium": crfValue = 28 break case "heavy": crfValue = 32 break case "custom": crfValue = await arg("Enter CRF value (18=highest quality, 51=lowest quality):", { placeholder: "Enter a number between 18-51" }) crfValue = parseInt(crfValue) if (isNaN(crfValue) || crfValue < 18 || crfValue > 51) { await div(md("# Error\n\nCRF value must be a number between 18 and 51")) exit(1) } break } // Generate output filename const inputDir = path.dirname(inputFile) const inputName = path.basename(inputFile, fileExtension) const outputFile = path.join(inputDir, `${inputName}_compressed${fileExtension}`) // Get original file size const originalStats = await stat(inputFile) const originalSizeMB = (originalStats.size / (1024 * 1024)).toFixed(2) await div({ html: md(` # Compressing Video **Input:** ${path.basename(inputFile)} **Original Size:** ${originalSizeMB} MB **CRF Value:** ${crfValue} **Output:** ${path.basename(outputFile)} Processing... This may take a while depending on video length and quality. `), onInit: async () => { try { // Run ffmpeg compression await $`ffmpeg -i ${inputFile} -c:v libx264 -crf ${crfValue} -c:a aac -b:a 128k -movflags +faststart ${outputFile}` // Get compressed file size const compressedStats = await stat(outputFile) const compressedSizeMB = (compressedStats.size / (1024 * 1024)).toFixed(2) const compressionRatio = ((1 - compressedStats.size / originalStats.size) * 100).toFixed(1) submit({ success: true, originalSize: originalSizeMB, compressedSize: compressedSizeMB, compressionRatio, outputFile }) } catch (error) { submit({ success: false, error: error.message }) } } }) const result = await div() if (result.success) { const shouldReveal = await arg({ placeholder: "Compression completed successfully!", hint: `Original: ${result.originalSize}MB → Compressed: ${result.compressedSize}MB (${result.compressionRatio}% reduction)` }, [ { name: "Reveal in Finder", value: "reveal", description: "Show the compressed file in Finder" }, { name: "Done", value: "done", description: "Close the script" } ]) if (shouldReveal === "reveal") { await revealFile(result.outputFile) } } else { await div(md(` # Compression Failed **Error:** ${result.error} Please check that: - The input file is a valid video - You have write permissions to the output directory - FFmpeg is properly installed `)) }