How to Extract MP3 from MP4 in All Subdirectories Using a Bash Script

Use this Bash script to recursively find all MP4 videos and convert them to MP3 audio using ffmpeg. Organize the output neatly into folders.


If you have a bunch of .mp4 videos across multiple folders and want to extract their audio into .mp3 files using ffmpeg, this Bash script will do exactly that.

It:

  • Takes a root directory as an argument
  • Recursively searches for .mp4 files
  • Extracts .mp3 audio using ffmpeg
  • Saves them in a new mp3 folder inside the same directory as the .mp4

🔧 Requirements

  • Linux or macOS with Bash
  • ffmpeg installed and accessible via $PATH

Install ffmpeg if you don't have it:

sudo apt install ffmpeg  # Debian/Ubuntu
brew install ffmpeg      # macOS

🖥️ The Script

#!/bin/bash

# Check if directory argument is provided
if [ -z "$1" ]; then
    echo "Usage: $0 /path/to/directory"
    exit 1
fi

TARGET_DIR="$1"

# Verify the provided path is a directory
if [ ! -d "$TARGET_DIR" ]; then
    echo "Error: '$TARGET_DIR' is not a directory"
    exit 1
fi

# Function to process each mp4 file
process_file() {
    mp4_file="$1"
    dir_name="$(dirname "$mp4_file")"
    base_name="$(basename "$mp4_file" .mp4)"
    mp3_dir="$dir_name/mp3"
    mp3_file="$mp3_dir/$base_name.mp3"

    # Create the mp3 directory if it doesn't exist
    mkdir -p "$mp3_dir"

    # Extract mp3 using ffmpeg
    echo "Extracting: $mp4_file -> $mp3_file"
    ffmpeg -i "$mp4_file" -q:a 0 -map a "$mp3_file" -y -loglevel error
}

export -f process_file

# Find and process all .mp4 files in the specified directory
find "$TARGET_DIR" -type f -iname "*.mp4" -exec bash -c 'process_file "$0"' {} \;

🚀 Usage

  1. Save the script above as extract_mp3s.sh
  2. Make it executable:
chmod +x extract_mp3s.sh
  1. Run it with your target directory:
./extract_mp3s.sh /path/to/your/video/folder

📝 Notes

  • Each .mp3 file will be saved in a sibling mp3/ folder within the same folder as the original .mp4
  • Existing .mp3 files will be overwritten without prompt
  • To skip already converted files, add a check like:
[ -f "$mp3_file" ] && return

📦 Example Directory Before and After

Before:

videos/
├── project1/
│   ├── intro.mp4
├── project2/
│   ├── demo.mp4

After:

videos/
├── project1/
│   ├── intro.mp4
│   └── mp3/
│       └── intro.mp3
├── project2/
│   ├── demo.mp4
│   └── mp3/
│       └── demo.mp3

Happy scripting! 🎧