September 19, 2024
O. Wolfson
Managing a large collection of video files can quickly become cumbersome, especially when you need to gather technical details like codecs, resolutions, frame rates, and audio properties. Luckily, with a simple Bash script and FFmpeg’s ffprobe tool, you can automate this process and store the metadata in a JSON file. In this post, I’ll walk you through a custom script I developed for just this purpose.
Whether you’re archiving videos, prepping them for editing, or simply need an inventory, manually extracting metadata for each file can be a tedious task. You might have dozens (or hundreds!) of videos to check. Doing this manually is inefficient, and this is where automation shines.
The script I’ve created gathers key information about each video file in a specified directory and outputs it into a well-formatted JSON file. It even calculates the total runtime of all videos and includes it at the top of the output.
Here’s the breakdown of the process.
.mp4 and .mov files.ffprobe (from FFmpeg) to gather:
Here’s the full script:
bash#!/bin/bash
# Specify the directory where your video files are located
input_directory="/path/to/your/videos"
# Check if the directory exists
if [ ! -d "$input_directory" ]; then
echo "Directory $input_directory does not exist."
exit 1
fi
# Extract the folder name from the input directory path
folder_name=$(basename "$input_directory")
# Output JSON file name based on folder name, saved in the same directory as the videos
output_file="$input_directory/${folder_name}_video_data.json"
# Initialize total duration (in seconds)
total_duration=0
# Loop through all .mp4 and .mov files in the specified directory to calculate total duration
for file in "$input_directory"/*.mp4 "$input_directory"/*.mov; do
# Get the video duration in seconds and add it to the total duration
duration=$(ffprobe -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file" | awk '{print int($1)}')
# Add duration to total
total_duration=$((total_duration + duration))
done
# Convert total duration into hours, minutes, and seconds
hours=$((total_duration / 3600))
minutes=$(( (total_duration % 3600) / 60 ))
seconds=$((total_duration % 60))
# Start JSON object with total duration
echo "{
\"total_duration\": \"${hours}h ${minutes}m ${seconds}s\",
\"videos\": [" >
first=
file /*.mp4 /*.mov;
video_info=$(ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate -of default=noprint_wrappers=1:nokey=1 )
audio_info=$(ffprobe -v quiet -select_streams a:0 -show_entries stream=codec_name,channels,sample_rate -of default=noprint_wrappers=1:nokey=1 )
duration=$(ffprobe -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 | awk )
[ -z ];
codec=$( | sed -n )
width=$( | sed -n )
height=$( | sed -n )
frame_rate=$( | sed -n )
audio_codec=$( | sed -n )
audio_channels=$( | sed -n )
audio_sample_rate=$( | sed -n )
filename=$( )
[ = ];
first=
>>
>>
>>
Setting up the environment: The script first checks whether the specified directory exists. If it doesn't, the script exits early to avoid errors.
Looping through files: The script loops over each .mp4 and .mov file in the directory and uses FFmpeg's ffprobe tool to extract metadata about each video and its audio stream (if present). This data is parsed and stored in variables for later use.
Calculating total duration: The script calculates the total duration of all videos in the directory and formats it into hours, minutes, and seconds.
Generating the JSON output: The extracted metadata is structured into a JSON format and saved to a file named after the folder containing the videos.
Here’s an example of what the JSON output looks like:
json{
"total_duration": "1h 30m 25s",
"videos": [
{
"filename": "video1.mp4",
"codec": "h264",
"resolution": "1920 x 1080",
"frame_rate": "30/1",
"duration": 3600,
"audio_codec": "aac",
"audio_channels": "2",
"audio_sample_rate": "44100"
},
{
"filename": "video2.mov",
"codec": "h264",
"resolution": "1280 x 720",
"frame_rate": "30/1",
"duration": 1800,
"audio_codec": "aac"
This script makes it easy to manage and document large collections of video files. By using ffprobe from FFmpeg, you can extract detailed metadata quickly and accurately, making your workflow much more efficient. Whether you’re a video editor, content creator, or just someone who works with a lot of media files, automating these tasks can save you a lot of time.