Browse Source

store ffmeg-commands as list of string and not just string - this makes some processing more straightforward and less finicky - relies on ffmpeg.py from ffcuesplitter being modified in the same fashion

master
Constantin Fürst 2 years ago
parent
commit
b30b38aba7
  1. 60
      libconv.py

60
libconv.py

@ -27,15 +27,14 @@ DST_OVERWRITE: bool = config.get("libconv", "overwrite") == "true"
DRY_RUN: bool = config.get("libconv", "dry_run") != "false" DRY_RUN: bool = config.get("libconv", "dry_run") != "false"
DEDUCE_METADATA: bool = config.get("libconv", "deduce_metadata") == "true" DEDUCE_METADATA: bool = config.get("libconv", "deduce_metadata") == "true"
FFMPEG_LOCATION: str = config.get("ffmpeg", "location") FFMPEG_LOCATION: str = config.get("ffmpeg", "location")
FFMPEG_OPTS: str = config.get("ffmpeg", "options")
THREADS: int = int(config.get("libconv", "threads"))
FFMPEG_OPTS: List[str] = config.get("ffmpeg", "options").split(",")
if DST_OVERWRITE: if DST_OVERWRITE:
FFMPEG_OPTS += " -y"
FFMPEG_OPTS.append("-y")
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
cmd_list: List[str] = []
cmd_list = []
# ----------------------------------------------------------------- # # ----------------------------------------------------------------- #
# file and folder operations # file and folder operations
@ -50,9 +49,8 @@ def mkdir(path: str):
if not DRY_RUN: if not DRY_RUN:
os.makedirs(path, exist_ok=True) os.makedirs(path, exist_ok=True)
def execute(command: str):
def execute(command: List[str]):
logging.debug(f"execute: {command}") logging.debug(f"execute: {command}")
if not DRY_RUN:
cmd_list.append(command) cmd_list.append(command)
# ----------------------------------------------------------------- # # ----------------------------------------------------------------- #
@ -76,22 +74,24 @@ def cue_sheet_processor(path: str):
try: try:
data = FFCueSplitter(sheet[0], dry=DRY_RUN, outputdir=dst_folder, suffix=DST_FILE_EXT, overwrite=DST_OVERWRITE, ffmpeg_cmd=FFMPEG_LOCATION, ffmpeg_add_params=FFMPEG_OPTS) data = FFCueSplitter(sheet[0], dry=DRY_RUN, outputdir=dst_folder, suffix=DST_FILE_EXT, overwrite=DST_OVERWRITE, ffmpeg_cmd=FFMPEG_LOCATION, ffmpeg_add_params=FFMPEG_OPTS)
data.open_cuefile() data.open_cuefile()
args = data.ffmpeg_arguments()["arguments"]
args = data.ffmpeg_arguments()
except: except:
logging.error(f"Error during parsing of cuesheet {path} - trying file processor")
logging.error(f"Cuesheet parsing of {path} resulted in error. Trying file processor.")
file_processor(path) file_processor(path)
return return
for arg in args: for arg in args:
arg_end = arg.find("-y")
filename = arg[arg_end + 5:-1]
arg = arg[:arg_end]
execute(f"{arg} \"{dst_folder}{filename}\"")
prepared = []
prepared.append(FFMPEG_LOCATION)
prepared.extend(arg[:-1])
prepared.extend(FFMPEG_OPTS)
prepared.append(f"\"{dst_folder}/{arg[-1]}.{DST_FILE_EXT}\"")
execute(prepared)
# ----------------------------------------------------------------- # # ----------------------------------------------------------------- #
# basic "folder contains audio files" processing # basic "folder contains audio files" processing
def metadata_from_folder(path: str) -> str:
def metadata_from_folder(path: str) -> List[str]:
# this method has to be adapted to your individual folder structure # this method has to be adapted to your individual folder structure
# if there is none then do nothing as by default this is not used # if there is none then do nothing as by default this is not used
if not DEDUCE_METADATA: if not DEDUCE_METADATA:
@ -105,11 +105,14 @@ def metadata_from_folder(path: str) -> str:
album_name = re.sub(r'[ ]*\(.*?\)', '', folders[-1]) album_name = re.sub(r'[ ]*\(.*?\)', '', folders[-1])
comment = folders[-1].replace(album_name, "").replace("(", "").replace(")", "").replace(" ","") comment = folders[-1].replace(album_name, "").replace("(", "").replace(")", "").replace(" ","")
logging.debug(f"got metadata: album={album_name} comment={comment} artist={folders[-2]} genre={folders[-3]}")
return f"-metadata ALBUM=\"{album_name}\" -metadata COMMENT=\"{comment}\" -metadata ARTIST=\"{folders[-2]}\" -metadata GENRE=\"{folders[-3]}\""
return [
f"-metadata ALBUM=\"{album_name}\"",
f"-metadata COMMENT=\"{comment}\"",
f"-metadata ARTIST=\"{folders[-2]}\"",
f"-metadata GENRE=\"{folders[-3]}\""
]
def metadata_from_file(filename: str) -> str:
def metadata_from_file(filename: str) -> List[str]:
title="" title=""
number="" number=""
@ -126,7 +129,10 @@ def metadata_from_file(filename: str) -> str:
else: else:
logging.debug(f"file {filename} matched no metadata regex") logging.debug(f"file {filename} matched no metadata regex")
return f"-metadata TITLE=\"{title}\" -metadata TRACK=\"{number}\""
return [
f"-metadata TITLE=\"{title}\"",
f"-metadata TRACK=\"{number}\""
]
def file_processor(path: str): def file_processor(path: str):
dst_folder, preexisting = prepare_destination(path) dst_folder, preexisting = prepare_destination(path)
@ -141,7 +147,15 @@ def file_processor(path: str):
for file in files: for file in files:
filename = get_filename(file, path) filename = get_filename(file, path)
file_metadata = metadata_from_file(filename[1:]) file_metadata = metadata_from_file(filename[1:])
execute(f"\"{FFMPEG_LOCATION}\" -i \"{file}\" {FFMPEG_OPTS} {album_metadata} {file_metadata} \"{dst_folder + filename}.{DST_FILE_EXT}\"")
command = []
command.append(FFMPEG_LOCATION)
command.append("-i")
command.append(f"\"{file}\"")
command.extend(album_metadata)
command.extend(file_metadata)
command.extend(FFMPEG_OPTS)
command.append(f"\"{dst_folder}/{filename}.{DST_FILE_EXT}\"")
execute(command)
# ----------------------------------------------------------------- # # ----------------------------------------------------------------- #
# Iteration over library folders and preparation # Iteration over library folders and preparation
@ -215,16 +229,16 @@ def process_folder(path: str):
scan_folder(path) scan_folder(path)
def execute_command_list(): def execute_command_list():
logging.info(f"Executing all {len(cmd_list)} commands with {THREADS} parallel threads")
logging.info(f"Executing all {len(cmd_list)} commands")
if DRY_RUN: if DRY_RUN:
logging.info("Skipping execution as we are dry-running. Printing list as debug-info.") logging.info("Skipping execution as we are dry-running. Printing list as debug-info.")
logging.debug(str(cmd_list)) logging.debug(str(cmd_list))
return return
Parallel(n_jobs=THREADS)(
delayed(os.system)(cmd) for cmd in cmd_list
)
for cmd in cmd_list:
cmd = " ".join(cmd)
subprocess.run(cmd, shell=True)
if __name__ == "__main__": if __name__ == "__main__":
logging.info(f"Using settings from {CONFIG_FILE}") logging.info(f"Using settings from {CONFIG_FILE}")

Loading…
Cancel
Save