Reputation: 1563
I want to list all the filenames and durations for each video in a folder. Currently I can only target files individually:
ffmpeg -i intro_vid001.mp4 2>&1 | grep Duration
Could someone suggest how I can print this out in the terminal or to a text file for every video file within a folder ?
I have tried with a shell script but am very new to shell scripts.
if [ -z $1 ];then echo Give target directory; exit 0;fi
find "$1" -depth -name ‘*’ | while read file ; do
directory=$(dirname "$file")
oldfilename=$(basename "$file")
echo oldfilename
#ffmpeg -i $directory/$oldfilename” -ab 320k “$directory/$newfilename.mp3″ </dev/null
ffmpeg -i "$directory/$oldfilename" 2>&1 | grep Duration | echo
#rm “$directory/$oldfilename”
done
Upvotes: 0
Views: 4205
Reputation: 21
How to create a filelist of all video files in a directory containing their duration (length) in h:mm:ss?
After looking at several hints in the web, which all did not work for me, I finally was able to create this script, which works on my side under Windows 11 using power shell. Perhaps you can benefit from it as well.
How to use:
It should create a file VideoFileListWithDurations.txt as output with the desired data, that you can easily copy to Excel.
Enjoy!
Save this script in the directory with your videos - as "CreateFileListWithDuration.ps1":
# Set the path to the directory you want to list files from
$directoryPath = "[enter your dir path here where video files are located]"
# Set the path to the output file
$outputFilePath = "$directoryPath\VideoFileListWithDurations.txt"
try {
# Get all video files in the specified directory
$videoFiles = Get-ChildItem -Path $directoryPath | Where-Object {
!$_.PSIsContainer -and $_.Extension -match '\.(mp4|avi|mkv|wmv)$'
}
# Initialize an array to store file information strings
$fileInfoStrings = @()
# Add headers to the array
$fileInfoStrings += "FileName`tFileSize (MB)`tFileType`tCreated`tLastModified`tDuration"
# Loop through each video file and retrieve its information
foreach ($file in $videoFiles) {
$fileInfo = @{
FileName = $file.Name
FileSize = "{0:N3}" -f ($file.Length / 1MB) # Format in megabytes with 3 decimal places
FileType = $file.Extension
Created = $file.CreationTime
LastModified = $file.LastWriteTime
Duration = "N/A"
}
try {
Write-Host "Getting duration for $($file.Name)"
$ffprobeOutput = & [enter path to ffprobe.exe file here - without ""] -i $($file.FullName) -show_entries format=duration -v quiet -of csv="p=0"
Write-Host "ffprobe output: $ffprobeOutput"
$duration = [double]$ffprobeOutput.Trim()
$timeSpan = [TimeSpan]::FromSeconds($duration)
$fileInfo.Duration = $timeSpan.ToString("h\:mm\:ss")
} catch {
$fileInfo.Duration = "Error getting duration"
}
$fileInfoStrings += "$($fileInfo.FileName)`t$($fileInfo.Duration)`t$($fileInfo.FileSize)"
}
# Export the file information strings to the output file
$fileInfoStrings | Out-File -FilePath $outputFilePath -Append
Write-Host "File information exported to $outputFilePath"
} catch {
Write-Host "An error occurred: $_"
Read-Host "Press Enter to exit"
}
Upvotes: 1
Reputation: 4205
I suggest the following script:
find "$1" -type f | while read videoPath ; do
videoFile=$(basename "$videoPath")
duration=$(ffmpeg -i "$videoPath" 2>&1 | grep Duration)
echo "$videoFile: $duration"
done
Upvotes: 1