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()
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:
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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With