Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Get Video Duration in Seconds Using FFmpeg / FFprobe

get-video-duration-in-seconds-using-ffmpeg-probe.jpg

We'll get the value back in seconds as well as HH:MM:SS if you prefer.

Quick Jump:

We’ll be using ffprobe but that’s a tool that gets installed by default with ffmpeg. You can apt / brew / etc. install ffmpeg if you need to install it.

We can do it based off the container format or stream duration of the video:

# Container format:
$ ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 myvideo.mp4
453.903678

# Stream format:
$ ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 myvideo.mp4
453.866667

With quite a few videos I’ve noticed if you round each one to the nearest second they both produce the same result. You can round it up by piping the command into | xargs printf "%.0f\n". You can change the 0 to 1, 2 or whatever precision you want.

You may also want to use LC_ALL=C xargs /usr/bin/printf instead of printf to avoid edge cases between shells and language settings. There’s a nice write up about that here, but if you’re running this as a 1 off script with an English locale then printf should suffice.

I didn’t formally benchmark it but both appear to finish in about the same time if you run them with time. I tried it on a video that was over 3 hours long and both commands finished between 220-240ms on my workstation with an old i5 quad core 3.2ghz CPU.

If you want more details about the output you can remove the -v error flag which is the log level. It defaults to -v info if you omit it. You can find more details in the docs.

We can also get the HH:MM:SS.MICROSECONDS format with the -sexagesimal flag if you prefer:

# Container format:
$ ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -sexagesimal myvideo.mp4
0:07:33.903678

# Stream format:
$ ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 -sexagesimal 2022-10-26,21-09.mp4
0:07:33.866667

That could be handy depending on what you’re doing. A while back I made a video to do the above but I used a combo of ffmpeg and grep because I didn’t know about the above command.

As for a real world use case. I ended up getting the video duration in seconds for 200+ videos for one of my video courses to help seed my local database with realistic values for the course platform I’m building.

# Demo Video

Timestamps

  • 0:31 – Getting the duration in seconds in 2 different ways
  • 1:47 – Real world use case
  • 2:16 – They both run at about the same speed
  • 2:59 – The v flag lets us see more information (log level)
  • 3:42 – Getting the value in HH:MM:SS format
  • 4:13 – Rounding up the seconds with xargs and printf
  • 5:17 – Handling edge cases with your locale and printf

What use case will you be using this for? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per year (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments