Mp4-to-Mp3 Convertor Python Code.

Mp4-to-Mp3 Convertor Python Code.

One thing about me: (the site admin).

I am a python automation enthusiast.

If I catch myself using some website to do something I can just do with python, I definitely will spend, sometimes what ends up becoming several hours, generating and fixing the code myself.

Yesterday I was creating some of the branding animations for my tiktok account.

I had an mp3 file, I needed it cut. My cracked ableton had somehow become blocked (I'm pretty new to having that shit cracked so idk what happened).

I went to google. "Free online audio editor."

I clicked the first result. It was a site called veed.io and according to gemini "The best free audio editor."

Upon closer inspection of the site, it was more of a video editor: it allowed me to trim the audio in the way that i needed it to be, but it outputed the audio in MP4. To my horror, after several minutes of searching I could not find the option to output to mp3. 

So there I was with a perfectly cut mp4 file that needed to function as audio.

I tried to find an mp4-mp3 converter on firefox developer without an adblocker on accident, and was subsequently bombarded with various ad-trocities.

I then took it upon myself to generate and edit an mp3-mp4 converter in python.

Code:


import sys  # Importing the sys module to access system-specific parameters and functions
import os  # Importing the os module to interact with the operating system
from moviepy.editor import VideoFileClip  # Importing the VideoFileClip class from moviepy to work with video files

def list_mp4_files(directory):  # Function to list all MP4 files in a given directory
    """Lists all MP4 files in the given directory."""  # Docstring explaining the function's purpose
    return [f for f in os.listdir(directory) if f.endswith('.mp4')]  # List all files ending with .mp4

def select_mp4_file(files):  # Function to prompt the user to select an MP4 file from the list
    """Prompts the user to select an MP4 file from a list."""  # Docstring explaining the function's purpose
    if not files:  # If the list is empty, print a message and return None
        print("No MP4 files found in the directory.")
        return None
    
    print("Select an MP4 file to convert:")  # Prompt the user to select a file
    for index, file in enumerate(files):  # Loop through the list of files and display each with a number
        print(f"{index + 1}. {file}")
    
    while True:  # Loop until the user makes a valid choice
        try:
            choice = int(input("Enter the number of the MP4 file: "))  # Ask for user input to select a file
            if 1 <= choice <= len(files):  # If the input is within the valid range, return the selected file
                return files[choice - 1]
            else:
                print("Invalid choice. Please try again.")  # If the choice is invalid, prompt again
        except ValueError:  # If the input is not a number, print an error message and ask again
            print("Invalid input. Please enter a number.")

def convert_mp4_to_mp3(input_file, output_file, bitrate="320k"):  # Function to convert MP4 to MP3
    """Converts an MP4 file to MP3 with high quality."""  # Docstring explaining the function's purpose
    video = VideoFileClip(input_file)  # Create a VideoFileClip object to access the video file
    audio = video.audio  # Extract the audio from the video

    if audio:  # If the audio exists
        audio.write_audiofile(output_file, bitrate=bitrate, codec='mp3', fps=44100)  # Write the audio to an MP3 file
        print(f"Converted {input_file} to {output_file} with {bitrate} bitrate")  # Inform the user about the conversion
        audio.close()  # Close the audio file to release resources
    video.close()  # Close the video file to release resources

def main():  # Main function to coordinate the process
    directory = os.getcwd()  # Get the current working directory
    mp4_files = list_mp4_files(directory)  # List MP4 files in the directory
    selected_file = select_mp4_file(mp4_files)  # Let the user select an MP4 file
    
    if selected_file:  # If a file is selected
        input_file = os.path.join(directory, selected_file)  # Construct the full path to the input file
        output_file = os.path.splitext(input_file)[0] + ".mp3"  # Create the output MP3 file path
        convert_mp4_to_mp3(input_file, output_file)  # Convert the MP4 file to MP3

if __name__ == "__main__":  # This ensures the script runs when executed directly
    main()  # Call the main function

End Code

It looks for an mp4 file in the directory, gives you a numbered output in case there are more than one file, and allows you to select the file of choice. It then converts the mp4 to mp3 at a bitrate of 320k, which is high quality. 

The code works by using the moviepy library. 

For some reason, moviepy was misbehaving and my system environment path wasnt seeing it (and chatgpt kept telling me not to just manually add it to my system path for some reason??) so I ended up installing moviepy in a Virtual Environment(venv). The python script up above only works if the venv is activated first, because it requires moviepy and thats where it is. So I made a batch file to activate the venv, and then i made a separate python script, which runs the batch file and the mp4-mp3 converter script. This is so i will be able to use it with my script manager, which will be explained in a later blog post. For now, here is the batch file:

Batch file code:


@echo off
call "myenv\Scripts\activate"
python "C:\Users\Username\OneDrive\Documents\Python Bin\mp4mp3convert.py"

End Batch File Code

And the Final python script that I use to handle the entire mess of code. This activates the venv via the batch file, then runs the other script. This is just so all of my scripts are .py files, which is for a future project. Anyways:

Final Python Script


import subprocess

# Path to the batch file
batch_file_path = r"C:\Users\saurk\OneDrive\Documents\Python Bin\activatevenv.bat"

# Run the batch file using subprocess.Popen for better handling of interactive scripts
try:
    # Using Popen to handle real-time output
    process = subprocess.Popen(batch_file_path, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

    # Read the output in real-time
    while True:
        output = process.stdout.readline()
        if output == '' and process.poll() is not None:
            break
        if output:
            print(output.strip())
    
    # Capture any remaining stderr
    stderr = process.stderr.read()
    if stderr:
        print(stderr.strip())
    
    # Ensure the process exits cleanly
    return_code = process.poll()
    if return_code != 0:
        raise subprocess.CalledProcessError(return_code, batch_file_path)
except subprocess.CalledProcessError as e:
    print(f"Error: {e}")
    print(f"Error Output: {e.stderr}")

End Code

I also use separate scripts for acquiring mp3 and mp4 files directly. I'll talk about that soon, on another post.

 

Back to blog

Leave a comment