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 →

Using FFmpeg to Get an MP3's Duration and 4 Ways to Get the File Size

blog/cards/using-ffmpeg-to-get-an-mp3s-duration-and-4-ways-to-get-the-file-size.jpg

Here's a Shell script I created to automate a task that used to take a bunch of steps to do manually.

Quick Jump: Demo Video

After 80+ episodes of my Running in Production podcast I finally automated the process of getting an MP3’s duration and file size in bytes so I can add it to the meta data of each episode (the site is built with Jekyll and is open source).

This video goes over what I used to do manually and how I automated it with a Shell script, FFmpeg and a few Unix tools. The takeaway here is you might be able to extract some of the patterns into your own scripts. For example, we’ll go over a while loop that removes leading zeros and colons from a string using a bit of Shell scripting and more.

Demo Video

Commands

Here’s 4 ways to get a file’s size in bytes (replace $file with your file):

# POSIX compliant.
wc -c < "${file}"

# Likely only works on Linux but is the fastest.
stat c %s "${file}"

# Likely only works on Linux.
du -sb "${file}"

# Hey it's possible!
python3 -c "import os; print(os.path.getsize('$file'))"

Here’s 2 ways to get the duration of an MP3 using ffmpeg.

You’ll need to install ffmpeg with sudo apt-get install ffmpeg, brew install ffmpeg or use whatever package manager your OS comes with.

# This is fast but it's only an estimate based on the bitrate of the file.
ffmpeg -i "${file}" 2>&1 | grep -oE "[0-9]{1}:[0-9]{2}:[0-9]{2}"

# More accurate but much slower. The first method hasn't failed me yet, it's
# usually only a difference of a few milliseconds.
ffmpeg -i "${file}" -f null /dev/null 2>&1 | grep -oE "[0-9]{1}:[0-9]{2}:[0-9]{2}" | tail -n 1

Recently I found you can do this with ffprobe too which comes with ffmpeg. Here’s that post.

Timestamps

  • 0:14 – Focusing on the why and then the how
  • 0:41 – Using this script to get meta data about each podcast episode
  • 2:01 – The manual process before I made this script
  • 3:45 – The script fixed a bunch of human errors I made in the past
  • 4:19 – Running the script to see how it works
  • 5:43 – Skimming the script
  • 6:27 – Set -e and preparing the file path to modify
  • 7:55 – Handling no episode or invalid episode names
  • 9:35 – Using find, sort and tail to get the latest episode
  • 12:51 – 4 different ways to get the file size in bytes on Linux and Unix
  • 17:40 – Using FFmpeg and a regular expression to get the duration of an MP3
  • 22:00 – Using a Bash while loop to strip leading 0s and leading colons
  • 25:58 – Figuring out if an episode is published or a draft
  • 30:43 – Outputting the details if we’re doing a dry run
  • 31:54 – Using Perl to do in place edits on the file in a cross platform way
  • 33:23 – A Bash 1 liner to run the script on every episode
  • 34:53 – Getting a more accurate duration with FFmpeg

What are you going to do with this script? 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 month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments