I have recorded some videos with the same length of 40 seconds. I have old videos with the same name but the length varies between 28-38 seconds. I want the new videos to be cut to the same length as the old ones. The new and old has the same names. Is it possible with a script using ffmpeg?
Get the length of the old video then cut the new video with same name to the same length as the old. Windows powershell or command bat file.
It's only the end of the video that has to be cut
CodePudding user response:
If you have the path for ffprobe.exe
and ffmpeg.exe
in your PATH environment variable
(like 'C:\Program Files\ffmpeg\bin\'
), then you can use this code below:
# the folders where the old and the new videos can be found
$oldVideoPath = 'X:\path\to\OLD\videos'
$newVideoPath = 'X:\path\to\NEW\videos'
# get a list of the old video files; filenames only
$oldVidNames = (Get-ChildItem -Path $oldVideoPath -File).Name
# get the new video files and loop over them
(Get-ChildItem -Path $newVideoPath -File) |
Where-Object { $oldVidNames -contains $_.Name } | ForEach-Object {
# construct the full path to the old video from which we take the duration
$oldVideo = Join-Path -Path $oldVideoPath -ChildPath $_.Name
# construct the full path to the trimmed output file (append '_trimmed')
$trimmedVideo = Join-Path -Path $newVideoPath -ChildPath ('{0}_trimmed{1}' -f $_.BaseName, $_.Extension)
# get the duration of the old video in format HH:mm:ss.ffffff
$oldDuration = ffprobe -i "$oldVideo" -show_entries format=duration -v quiet -of csv="p=0" -sexagesimal
Write-Host "Trimming '$($_.FullName)' to duration $oldDuration"
# now trim the new video to the same length, overwriting the original by using switch '-y'
ffmpeg -y -ss 00:00:00 -i "$($_.FullName)" -to $oldDuration -c:v copy -c:a copy "$trimmedVideo" -loglevel quiet
}
If you do not have that PATH environment variable, you need to use variables containing the full path and filenames to both ffprobe and ffmpeg like this:
# the file paths to both ffprobe and ffmpeg if you do not have the path to the bin folder in your PATH environment variable
$ffprobe = 'C:\Program Files\ffmpeg\bin\ffprobe.exe'
$ffmpeg = 'C:\Program Files\ffmpeg\bin\ffmpeg.exe'
# the folders where the old and the new videos can be found
$oldVideoPath = 'X:\path\to\OLD\videos'
$newVideoPath = 'X:\path\to\NEW\videos'
# get a list of the old video files; filenames only
$oldVidNames = (Get-ChildItem -Path $oldVideoPath -File).Name
# get the new video files and loop over them
(Get-ChildItem -Path $newVideoPath -File) |
Where-Object { $oldVidNames -contains $_.Name } | ForEach-Object {
# construct the full path to the old video from which we take the duration
$oldVideo = Join-Path -Path $oldVideoPath -ChildPath $_.Name
# construct the full path to the trimmed output file (append '_trimmed')
$trimmedVideo = Join-Path -Path $newVideoPath -ChildPath ('{0}_trimmed{1}' -f $_.BaseName, $_.Extension)
# get the duration of the old video in format HH:mm:ss.ffffff
$oldDuration = & $ffprobe -i "$oldVideo" -show_entries format=duration -v quiet -of csv="p=0" -sexagesimal
Write-Host "Trimming '$($_.FullName)' to duration $oldDuration"
# now trim the new video to the same length, overwriting the original by using switch '-y'
& $ffmpeg -y -ss 00:00:00 -i "$($_.FullName)" -to $oldDuration -c:v copy -c:a copy "$trimmedVideo" -loglevel quiet
}
ffmpeg switches:
-y overwrite output file if exists
-i specifies the input file
-ss the startposition in the input file (here `00:00:00` to start from the very beginning)
-to specifies duration from start to end (this value is taken from the old file with the same name)
-c:v copy trim video via stream copy (fast)
-c:a copy trim audio via stream copy (fast)
-loglevel quiet do not send output via error stream to console
ffprobe switches:
-i specifies the input file
-show_entries format=duration set list of entries to show, in this case we only want duration
-v quiet do not send output via error stream to console
-of csv="p=0" set output printing format to csv; do not print section name
-sexagesimal Use sexagesimal format HH:MM:SS.MICROSECONDS for time values.