Skip to content

Instantly share code, notes, and snippets.

@speedoholic
Created February 15, 2026 01:22
Show Gist options
  • Select an option

  • Save speedoholic/858b4fde0a32d66d46eaef41b1aff2aa to your computer and use it in GitHub Desktop.

Select an option

Save speedoholic/858b4fde0a32d66d46eaef41b1aff2aa to your computer and use it in GitHub Desktop.
PowerShell Script to Prepare and Combine MP4 files using FFmpeg
# PowerShell Script to Prepare Files and Combine Them Using FFmpeg (https://ardalis.com/combine-mp4-files-ffmpeg-windows/)
try {
# Step 1: Get all .mp4 files in the current folder and check the total duration
$files = Get-ChildItem -Filter *.mp4
# Check if there are no .mp4 files in the folder
if ($files.Count -eq 0) {
Write-Host "No .mp4 files found in the current folder. Exiting script."
exit
}
# Initialize total duration of all original files
$totalDuration = 0
foreach ($file in Get-ChildItem -Filter *.mp4) {
# Extract the duration of each file using FFmpeg
$duration = ffmpeg -i $file.FullName 2>&1 | Select-String "Duration" | ForEach-Object { ($_ -split ",")[0] -replace "Duration: ", "" }
$timeParts = $duration -split ":" # Split duration into hours, minutes, and seconds
$totalDuration += [double]($timeParts[0]) * 3600 + [double]($timeParts[1]) * 60 + [double]($timeParts[2]) # Convert to seconds and sum up
}
Write-Host "Total Duration of Original Files (seconds): $totalDuration"
# Step 2: Rename files to replace spaces with underscores
foreach ($file in $files) {
# Replace spaces in filenames with underscores for FFmpeg compatibility
$newName = $file.Name -replace ' ', '_'
if ($newName -ne $file.Name) {
Rename-Item -Path $file.FullName -NewName $newName
}
}
# Step 3: Create file_list.txt
$fileListPath = Join-Path $PWD "file_list.txt"
# Remove existing file_list.txt if it exists to avoid appending to an old file
Remove-Item -Path $fileListPath -ErrorAction SilentlyContinue
# Add a header comment to the file_list.txt (optional)
Add-Content -Path $fileListPath -Value "# File list for FFmpeg concatenation"
foreach ($file in Get-ChildItem -Filter *.mp4) {
# Add each file to the file_list.txt in the required format
Add-Content -Path $fileListPath -Value "file '$($file.Name)'"
}
Write-Host "Preparation complete. file_list.txt created."
# Step 4: Combine files using FFmpeg
$outputFile = "Long_File_Combined.mp4" # Name of the output file
$ffmpegCommand = "ffmpeg -f concat -safe 0 -i file_list.txt -c copy $outputFile"
Write-Host "Running FFmpeg to combine files..."
Invoke-Expression $ffmpegCommand # Execute the FFmpeg command
# Check if the output file was successfully created
if (Test-Path $outputFile) {
Write-Host "Files successfully combined into $outputFile."
# Step 5: Verify the result by comparing durations
# Extract the duration of the combined file
$combinedDurationRaw = ffmpeg -i $outputFile 2>&1 | Select-String "Duration" | ForEach-Object { ($_ -split ",")[0] -replace "Duration: ", "" }
$combinedTimeParts = $combinedDurationRaw -split ":" # Split duration into hours, minutes, and seconds
$combinedDuration = [double]($combinedTimeParts[0]) * 3600 + [double]($combinedTimeParts[1]) * 60 + [double]($combinedTimeParts[2]) # Convert to seconds
Write-Host "Total Duration of Original Files (seconds): $totalDuration"
Write-Host "Duration of Combined File (seconds): $combinedDuration"
# Compare the total duration of original files with the combined file's duration
# Use a tolerance of 0.1 seconds to account for floating-point precision issues
if ([math]::Abs($totalDuration - $combinedDuration) -lt 0.1) {
Write-Host "Verification successful: Combined file duration matches the total duration of original files."
} else {
Write-Host "Warning: Combined file duration does not match the total duration of original files."
}
} else {
Write-Host "Error: FFmpeg failed to create the combined file."
}
} catch {
# Catch and display any errors that occur during script execution
Write-Host "An error occurred: $_"
}
@speedoholic
Copy link
Copy Markdown
Author

For combining .TS files, simply use the following command in Terminal:

copy /b *.ts merged.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment