Created
June 25, 2019 19:01
-
-
Save RF5/fd77a35e6e5028c200ebeca82133207e to your computer and use it in GitHub Desktop.
Python script to rapidly convert folders of flac audio files to mp3, preserving metadata and cover art
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# pip install fastprogress | |
# pip install pydub | |
from pydub import AudioSegment | |
from pydub.utils import mediainfo | |
from fastprogress import progress_bar | |
import os | |
import glob | |
from pathlib import Path | |
from concurrent.futures.process import ProcessPoolExecutor | |
import concurrent | |
def parallel(func, arr, max_workers): | |
""" | |
Call `func` on every element of `arr` in parallel using `max_workers`. | |
Adapted from fastai. Thanks! | |
""" | |
if max_workers<2: _ = [func(o,i) for i,o in enumerate(arr)] | |
else: | |
with ProcessPoolExecutor(max_workers=max_workers) as ex: | |
futures = [ex.submit(func,o,i) for i,o in enumerate(arr)] | |
for f in progress_bar(concurrent.futures.as_completed(futures), total=len(arr)): pass | |
def proc_vid(v, i): | |
video, pth_to, pth = v | |
mp3_filename = pth_to/video.parent.relative_to(pth)/(video.stem + '.mp3') | |
os.makedirs(mp3_filename.parent, exist_ok=True) | |
cover_dir = None | |
# Try to discover a cover image in the current album's folder | |
# by looking for generic filenames. | |
if os.path.isfile(video.parent/'cover.jpg'): | |
cover_dir = video.parent/'cover.jpg' | |
elif os.path.isfile(video.parent/'cover.png'): | |
cover_dir = video.parent/'cover.jpg' | |
elif os.path.isfile(video.parent/'Cover.jpg'): | |
cover_dir = video.parent/'Cover.jpg' | |
elif os.path.isfile(video.parent/'Cover.png'): | |
cover_dir = video.parent/'Cover.png' | |
elif os.path.isfile(video.parents[1]/'cover.jpg'): | |
cover_dir = video.parents[1]/'cover.jpg' | |
elif os.path.isfile(video.parents[1]/'cover.png'): | |
cover_dir = video.parents[1]/'cover.jpg' | |
elif os.path.isfile(video.parents[1]/'Cover.jpg'): | |
cover_dir = video.parents[1]/'Cover.jpg' | |
elif os.path.isfile(video.parents[1]/'Cover.png'): | |
cover_dir = video.parents[1]/'Cover.png' | |
k = AudioSegment.from_file(video, format='flac') | |
if cover_dir is not None: | |
k.export(str(mp3_filename), format='mp3', tags=mediainfo(str(video)).get('TAG', {}), cover=str(cover_dir)) | |
else: | |
k.export(str(mp3_filename), format='mp3', tags=mediainfo(str(video)).get('TAG', {})) | |
def convert(): | |
folder_with_albums = './my_mixtape_archives/' # Path with folders of flac files | |
extension_list = ('**/*.flac',) | |
dirs = os.listdir(folder_with_albums) | |
for ost in dirs: | |
if ost.endswith('-mp3'): continue | |
print("\nConverting ", ost, '\n') | |
pth = Path(folder_with_albums)/ost | |
i = 0 | |
pth_to = Path(pth.name + '-mp3') | |
os.makedirs(pth_to, exist_ok=True) | |
for extension in extension_list: | |
videos = [(f, pth_to, pth) for f in pth.glob(extension)] | |
if len(videos) > 0: | |
parallel(proc_vid, videos, max_workers=os.cpu_count()) | |
break | |
print('\n\n') | |
if __name__ == "__main__": | |
convert() |
Oh yeah, this kept the mp3's in the same folder as the flac... i kept it this way because when i grab folders from itunes it won't grab the flac's anyway so at least it just grabs what i want it to grab being in the same folder.
Ahh glad you came right. This code I tested actually for windows, and how pydub's internals might have also changed in the last three years, so this script probably is slightly out of date. If I were to make a new one for 2022 it would probably use ffmpeg instead of pydub. Glad you came right though :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yeah for some reason nothing was being created and i thought maybe it was an admin right for creating folders and i tried it on my desktop, c: drive, etc... nothing, but i did change it to this and it worked:
def convert(mp3folder):
if name == "main":
convert('mp3folder')
maybe if someone else is having trouble they could use that...also, was this written for linux? maybe that's my problem.