diff --git a/libconv.py b/libconv.py index 6635e0f..abd2252 100644 --- a/libconv.py +++ b/libconv.py @@ -27,15 +27,14 @@ DST_OVERWRITE: bool = config.get("libconv", "overwrite") == "true" DRY_RUN: bool = config.get("libconv", "dry_run") != "false" DEDUCE_METADATA: bool = config.get("libconv", "deduce_metadata") == "true" 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: - FFMPEG_OPTS += " -y" + FFMPEG_OPTS.append("-y") logging.basicConfig(level=logging.INFO) -cmd_list: List[str] = [] +cmd_list = [] # ----------------------------------------------------------------- # # file and folder operations @@ -50,10 +49,9 @@ def mkdir(path: str): if not DRY_RUN: os.makedirs(path, exist_ok=True) -def execute(command: str): +def execute(command: List[str]): logging.debug(f"execute: {command}") - if not DRY_RUN: - cmd_list.append(command) + cmd_list.append(command) # ----------------------------------------------------------------- # # cue sheet processing @@ -76,22 +74,24 @@ def cue_sheet_processor(path: str): 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.open_cuefile() - args = data.ffmpeg_arguments()["arguments"] + args = data.ffmpeg_arguments() 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) return 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 -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 # if there is none then do nothing as by default this is not used if not DEDUCE_METADATA: @@ -105,11 +105,14 @@ def metadata_from_folder(path: str) -> str: album_name = re.sub(r'[ ]*\(.*?\)', '', folders[-1]) 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="" number="" @@ -126,7 +129,10 @@ def metadata_from_file(filename: str) -> str: else: 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): dst_folder, preexisting = prepare_destination(path) @@ -141,7 +147,15 @@ def file_processor(path: str): for file in files: filename = get_filename(file, path) 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 @@ -215,16 +229,16 @@ def process_folder(path: str): scan_folder(path) 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: logging.info("Skipping execution as we are dry-running. Printing list as debug-info.") logging.debug(str(cmd_list)) 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__": logging.info(f"Using settings from {CONFIG_FILE}")