Python convert mp3 to mp4 with static image

I do have x file which contain a list of mp3 files where i would like to convert each mp3 file to mp4 file with a static .png photo.

Seems the only way here is to use ffmpeg but idk how to achieve it.

i made the script to take an input of mp3 folder and one .png photo`.

then it's will create new folder x-converted where i would like to convert each mp3 to mp4 with the static png with same name such as file1.mp3 to became file1.mp4

here's my code :

import os
import sys
from pathlib import Path
import shutil

if len(sys.argv) != 3 or not sys.argv[2].endswith("png"):
    print("Make sure to provide two arguments only\nSecond arugment should be .png")
    exit()


def CheckFile():
    try:
        files = []
        for path in os.listdir(sys.argv[1]):
            full_path = os.path.join(sys.argv[1], path)
            if os.path.isfile(full_path):
                files.append(full_path)
        mp3 = [x for x in files if x.endswith(".mp3")]
        if len(mp3) >= 1:
            return mp3, sys.argv[2], sys.argv[1]
        else:
            print(
                "Make Sure That You've at least 1 Mp3 file")
            exit()
    except FileNotFoundError:
        print("Sorry, This File Is Not Exist!")
        exit()


def Convert():
    mp3, jpg, name = CheckFile()
    name = f"{Path(name).name}-converted"
    shutil.rmtree(name, ignore_errors=True)
    os.mkdir(name)
    os.chdir(name)
    # from here i don't know how to use `ffmpeg`


Convert()

Upvotes: 3

Views: 5178

Answers (2)

llogan
llogan

Reputation: 133703

ffmpeg -loop 1 -framerate 1 -i image.png -i audio.mp3 -map 0:v -map 1:a -r 10 -vf "scale='iw-mod(iw,2)':'ih-mod(ih,2)',format=yuv420p" -movflags +faststart -shortest -fflags +shortest -max_interleave_delta 100M output.mp4
  • -loop 1 makes input.png loop indefinitely.
  • -framerate 1 sets input.png input frame rate to 1 fps.
  • -map 0 -map 1:a chooses the video from image.png and only the audio from audio.mp3. This is needed in case image.png is smaller than any album/cover art attached to the MP3. Otherwise it may choose the album/cover art instead. See FFmpeg Wiki: Map for more info.
  • -r 10 sets output frame rate to 10 fps. Setting input to 1 fps and output to 10 fps is for two reasons:
    • It is faster to input as 1 fps and duplicate frames to 10 fps compared to initially setting the input as 10 fps. It makes encoding faster.
    • Most players can't play anything under ~6 fps or so. 10 is a safe value.
  • scale='iw-mod(iw,2)':'ih-mod(ih,2)' uses scale filter to make sure the output width and height are both divisible by 2 which is a requirement for some encoders. This allows you to use any arbitrarily sized image as an input. Otherwise you can get error: width not divisible by 2.
  • format=yuv420p format filter makes output use YUV 4:2:0 chroma subsampling for playback compatibility.
  • -movflags +faststart makes the video start playing faster.
  • -shortest makes the output as long as audio.mp3. This is needed because -loop 1 was used.
  • -fflags +shortest -max_interleave_delta 100M related to -shortest and needed in some cases due to weird behavior by ffmpeg. See My ffmpeg output always add extra 30s of silence at the end for an explanation.

Upvotes: 7

user1116678
user1116678

Reputation: 32

certain library like ffmpy & ffmpeg-python can enable you operate ffmpeg with python, try these out. (I used ffmpeg-python long time ago and it worked well)

Upvotes: -1

Related Questions