Batch Extract Audio from Video

The challenge was to extract the first audio track from a video file in all video files in a given folder. To do this efficiently and utilizing multiple CPU cores in parallel, I installed Parallel in Ubuntu:

sudo apt install parallel

with the following script the passed folder as parameter will be scanned for mp4 files and every file’s first audio track will be extracted as m4a file: I made detailed comments on each line to explain exactly what it does.

#!/bin/bash

# Check if a folder is passed as an argument to this script.
if [ -z "$1" ]; then
    # If no folder is provided, display usage and exit the program.
    echo "Usage: $0 <folder>"
    exit 1
fi

# Assign the path of the specified folder to a variable named FOLDER.
FOLDER=$1

# Check if the assigned folder exists in the file system.
if [ ! -d "$FOLDER" ]; then
    # If it does not exist, display an error message and terminate the program.
    echo "Error: Folder '$FOLDER' does not exist."
    exit 1
fi

# Define a function named extract_audio that takes one argument (the path of an MP4 file).
extract_audio() {
    FILE="$1"
    
    # Extract the base name of the input file by removing its extension.
    BASENAME=$(basename "$FILE" .mp4)
    
    # Construct the output filename for the extracted audio track.
    OUTPUT_FILE="$FOLDER/${BASENAME}.m4a"
    
    # Use ffmpeg to extract the audio from the MP4 file and save it as an M4A file in parallel without waiting for user input or displaying any error messages.
    ffmpeg -i "$FILE" -q:a 0 -map a "$OUTPUT_FILE" < /dev/null > /dev/null 2>&1
    
    # Display a message indicating that the audio has been successfully extracted from the MP4 file and saved as an M4A file.
    echo "Extracted audio from $FILE to $OUTPUT_FILE"
}

# Export the extract_audio function so it can be used in parallel processing, along with the FOLDER variable containing the path of the specified folder.
export -f extract_audio
export FOLDER

# Find all MP4 files within the specified folder using find command. 
find "$FOLDER" -maxdepth 1 -name "*.mp4" | # Use parallel to process each file in parallel, displaying progress information as it runs.
parallel --progress extract_audio

Note how the use of the following FFmpeg parameters ensures that the first audio track is extracted from the video without being re-encoded. Therefore, no modifications are made to the original audio track.

ffmpeg -i inputVideo.mp4 -q:a 0 -map a output.m4a

Just save the file as extractAudioFromVideo.sh for example and make it executable with chmod +x extractAudioFromVideo.sh. Then you can call the script like this:

./ extractAudioFromVideo.sh pathToYourFolder

Here is an output example for a call on the local folder:

extractAudioFromVideo.sh .

Computers / CPU cores / Max jobs to run
1:local / 32 / 32

Computer:jobs running/jobs completed/%of started jobs/Average seconds to complete
local:6/0/100%/0.0s Extracted audio from ./file1.mp4 to ./file1.m4a
local:5/1/100%/11.0s Extracted audio from ./file2.mp4 to ./file2.m4a
local:4/2/100%/7.0s Extracted audio from ./file3.mp4 to ./file3.m4a
local:3/3/100%/5.0s Extracted audio from ./file14.mp4 to ./file4.m4a
local:2/4/100%/4.2s Extracted audio from ./file5.mp4 to ./file5.m4a
local:1/5/100%/3.8s Extracted audio from ./file6.mp4 to ./file6.m4a
local:0/6/100%/3.2s 

♥♥♥

Monero