When I run the following PowerShell script, to concatenate the .avi files in a folder, I get an error.
Script:
# Set the folder path where the AVI files are located
$folderPath = "C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam"
# Get all AVI files in the folder
$aviFiles = Get-ChildItem -Path $folderPath -Filter "*.avi" | Sort-Object Name
# Check if there are at least 2 AVI files for concatenation
if ($aviFiles.Count -ge 2) {
$videoFiles = $aviFiles.FullName
Write-Host "Input Files for Concatenation:"
foreach ($file in $aviFiles) {
Write-Host $file.Name
}
$outputFile = Join-Path -Path $folderPath -ChildPath "concatenated.avi"
# Create the FFmpeg command for concatenation
$concatArguments = "-f", "concat", "-i", "`"concat:$videoFiles`"", "-c", "copy", "`"$outputFile`""
$command = "ffmpeg $concatArguments"
Write-Host "FFmpeg Command: $command"
try {
$process = Start-Process -FilePath "ffmpeg" -ArgumentList $concatArguments -NoNewWindow -PassThru -Wait -ErrorAction Stop
Write-Host "Concatenation complete. Output file: $outputFile"
} catch {
Write-Host "Error occurred while executing FFmpeg command:"
Write-Host "Error message: $($_.Exception.Message)"
}
} else {
Write-Host "Not enough AVI files found in the folder for concatenation."
}
Output with error, (and no concatenated file is actually produced, needless to say):
Input Files for Concatenation:
webcam0.avi
webcam1.avi
FFmpeg Command: ffmpeg -f concat -i "concat:C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam\webcam0.avi C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam\webcam1.avi" -c copy "C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam\concatenated.avi"
ffmpeg version 2023-06-27-git-9b6d191a66-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 12.2.0 (Rev10, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libvpl --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
libavutil 58. 13.101 / 58. 13.101
libavcodec 60. 21.100 / 60. 21.100
libavformat 60. 9.100 / 60. 9.100
libavdevice 60. 2.100 / 60. 2.100
libavfilter 9. 8.102 / 9. 8.102
libswscale 7. 3.100 / 7. 3.100
libswresample 4. 11.100 / 4. 11.100
libpostproc 57. 2.100 / 57. 2.100
[in#0 @ 000001d2f05f1b00] Error opening input: Invalid argument
Concatenation complete. Output file: C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam\concatenated.avi
But this script, which ostensibly does the same thing to the same files, works fine:
$file1 = "C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam\webcam0.avi" # Path to the first video file
$file2 = "C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam\webcam1.avi" # Path to the second video file
$outputFile = "C:\Users\HomePC\hswlab\Desktop\videos\eyeblink\022223\2023_04_24\16_15_23\My_WebCam\concat.avi" # Path to the output concatenated video file
# Create a temporary batch script
$batchScriptPath = [System.IO.Path]::GetTempFileName() + ".bat"
@'
@echo off
ffmpeg -i "%~1" -i "%~2" -filter_complex "[0:v][1:v]concat=n=2:v=1[outv]" -map "[outv]" "%~3"
'@ | Set-Content -Path $batchScriptPath
# Execute the temporary batch script
try {
& $batchScriptPath $file1 $file2 $outputFile
Write-Host "Concatenation complete. Output file: $outputFile"
} catch {
Write-Host "Error occurred while executing FFmpeg command:"
Write-Host $_.Exception.Message
}
# Remove the temporary batch script
Remove-Item -Path $batchScriptPath -Force
I can't figure out what is wrong with the first script. I tried many variations of the first script but cannot get it to work.
Any help?
Judging by the Concatenating media files documentation page:
concat
subcommand OR the concat:
protocol, to which you pass a list of file paths separated with |
.Therefore:
ffmpeg -f -i ('concat:' + ($videoFiles -join '|')) -c copy $outputFile
# Use $LASTEXITCODE -ne 0 to test for failure.
Note the use of direct invocation of ffmpeg
, which by default runs in the same window and synchronously, and additionally allows you to capture any output, while reflecting the process exit code in the automatic $LASTEXITCODE
variable.
An additional benefit of direct invocation is that you don't have to worry about explicit quoting of arguments - PowerShell does that for you (if an argument contains spaces, it is automatically enclosed in "..."
on the process command line constructed behind the scenes).
For invocation of console applications such as ffmpeg
, Start-Process
is rarely the right tool - see GitHub docs issue #6239 for guidance on when use of Start-Process
is and isn't appropriate.