Create an FFmpeg Automated Watch Folder Script
Automating your media workflow with a watch folder saves time by automatically transcoding new video or audio files as soon as they are saved to a specific directory. This article demonstrates how to build a lightweight, cross-platform automation script using FFmpeg, utilizing Bash for Linux and macOS systems, and PowerShell for Windows environments.
Prerequisites
Before starting, ensure you have the following installed on your
system: * FFmpeg: Must be installed and added to your
system’s PATH. * Inotify-tools (for Linux): Required to
monitor file system events. Install it via your package manager (e.g.,
sudo apt install inotify-tools on Ubuntu/Debian).
Note: Always set your watch folder and output folder to different directories to prevent the script from entering an infinite loop of transcoding its own output.
Method 1: Linux and macOS (Bash Script)
On Unix-like systems, the most efficient way to monitor a directory
is by using inotifywait (Linux) or fswatch
(macOS). This method triggers the transcoding process only when a file
write operation is fully completed.
Create a file named watch_folder.sh and paste the
following script:
#!/bin/bash
# Define directories (use absolute paths)
WATCH_DIR="/path/to/watch_folder"
OUTPUT_DIR="/path/to/output_folder"
# Ensure output directory exists
mkdir -p "$OUTPUT_DIR"
echo "Watching directory: $WATCH_DIR"
# Monitor for newly closed (written) files
inotifywait -m "$WATCH_DIR" -e close_write | while read -r path action file; do
# Check if the file has a video extension
if [[ "$file" =~ \.(mp4|mkv|mov|avi)$ ]]; then
echo "New file detected: $file"
INPUT_FILE="$WATCH_DIR/$file"
OUTPUT_FILE="$OUTPUT_DIR/${file%.*}.mp4"
echo "Transcoding $file to MP4..."
# Run FFmpeg transcoding (H.264 video and AAC audio)
ffmpeg -i "$INPUT_FILE" -c:v libx264 -crf 23 -c:a aac -b:a 128k "$OUTPUT_FILE" -y
if [ $? -eq 0 ]; then
echo "Successfully transcoded: $file"
# Optional: Delete the source file after successful transcoding
# rm "$INPUT_FILE"
else
echo "Error transcoding: $file"
fi
fi
doneTo run this script, make it executable and run it in the background:
chmod +x watch_folder.sh
./watch_folder.sh &Method 2: Windows (PowerShell Script)
On Windows, you can utilize the .NET FileSystemWatcher
class within PowerShell to monitor directory changes in real-time.
Create a file named watch_folder.ps1 and paste the
following script:
# Define directories
$WatchDir = "C:\path\to\watch_folder"
$OutputDir = "C:\path\to\output_folder"
# Ensure output directory exists
if (!(Test-Path $OutputDir)) {
New-Item -ItemType Directory -Force -Path $OutputDir
}
# Create FileSystemWatcher object
$Watcher = New-Object System.IO.FileSystemWatcher
$Watcher.Path = $WatchDir
$Watcher.Filter = "*.*" # Filters can be specified here, e.g., "*.mkv"
$Watcher.EnableRaisingEvents = $true
Write-Host "Watching directory: $WatchDir"
# Action to take when a file is created
$Action = {
$Path = $Event.SourceEventArgs.FullPath
$Name = $Event.SourceEventArgs.Name
$Extension = [System.IO.Path]::GetExtension($Path)
# Process only specific video extensions
if ($Extension -match '\.(mp4|mkv|mov|avi)$') {
Write-Host "New file detected: $Name"
# Wait briefly to ensure the file is completely written to disk
Start-Sleep -Seconds 3
$OutputFile = Join-Path $OutputDir ([System.IO.Path]::GetFileNameWithoutExtension($Name) + ".mp4")
Write-Host "Transcoding $Name..."
# Run FFmpeg
& ffmpeg -i $Path -c:v libx264 -crf 23 -c:a aac -b:a 128k $OutputFile -y
if ($LASTEXITCODE -eq 0) {
Write-Host "Successfully transcoded: $Name"
# Optional: Remove source file
# Remove-Item $Path
} else {
Write-Host "Error transcoding: $Name"
}
}
}
# Bind event
Register-ObjectEvent $Watcher "Created" -Action $Action
# Keep the script running
while ($true) {
Start-Sleep -Seconds 1
}To run this script on Windows, open PowerShell and execute:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\watch_folder.ps1