def mux(*tracks, tmdb: TmdbConfig | None = None, outfile: PathLike | None = None, quiet: bool = True, print_cli: bool = False) -> PathLike:
"""
Runs the mux.
:param *tracks: Any amount of track objects and a Chapters object
:param tmdb: A TMDB Config used for additional tagging if you so desire.
:param outfile: If you want to overwrite the output file path
:param quiet: Whether or not to print the mkvmerge output
:param print_cli: Print the final muxing command before running it if True
"""
check_mkvmerge_version()
tracks = list(tracks)
out_dir = ensure_path(get_setup_attr("out_dir", "premux"), "Mux")
args: list[str] = [get_executable("mkvmerge")]
filename, mkvtitle = output_names(tmdb, args, tracks)
if not outfile:
outfile = Path(out_dir, f"{filename}.mkv")
outfile = ensure_path(outfile, "Mux")
args.extend(["-o", str(outfile)])
for track in tracks:
if isinstance(track, _track):
args.extend(track.mkvmerge_args())
continue
elif isinstance(track, MuxingFile):
if not isinstance(track, FontFile):
warn("It's strongly recommended to pass tracks to ensure naming and tagging instead of MuxingFiles directly!", "Mux", 1)
track = track.to_track()
args.extend(track.mkvmerge_args())
continue
elif isinstance(track, Chapters):
if not track.chapters:
warn("Chapters are None or empty!", "Mux")
continue
args.extend(["--chapters", track.to_file()])
continue
elif isinstance(track, Path) or isinstance(track, str) or isinstance(track, GlobSearch):
# Failsave for if someone passes Chapters().to_file() or a txt/xml file
track = ensure_path_exists(track, "Mux")
if track.suffix.lower() in [".txt", ".xml"]:
args.extend(["--chapters", track.resolve()])
continue
elif track is None:
continue
raise error("Only _track, MuxingFiles or Chapters types are supported as muxing input!", "Mux")
if mkvtitle:
args.extend(["--title", mkvtitle])
if print_cli:
info(joincommand(args), "Mux")
debug("Running the mux...", "Mux")
if run_commandline(args, quiet, mkvmerge=True) > 1:
raise error("Muxing failed!", "Mux")
try:
from importlib.metadata import version
minfo = MediaInfo.parse(outfile, parse_speed=0.375)
container_info = minfo.general_tracks[0]
mkvpropedit = get_executable("mkvpropedit", False, False)
muxtools_version = version("muxtools")
version_tag = f" + muxtools v{muxtools_version}"
if mkvpropedit and (muxing_application := getattr(container_info, "writing_library", None)) and "muxtools" not in muxing_application:
args = [mkvpropedit, "--edit", "info", "--set", f"muxing-application={muxing_application + version_tag}", str(outfile.resolve())]
run_commandline(args)
except:
pass
if "#crc32#" in outfile.stem:
debug("Generating CRC32 for the muxed file...", "Mux")
outfile = outfile.rename(outfile.with_stem(re.sub(re.escape("#crc32#"), get_crc32(outfile), outfile.stem)))
if get_setup_attr("clean_work_dirs", False):
if os.path.samefile(get_workdir(), os.getcwd()):
error("Clearing workdir not supported when your workdir is cwd.", "Mux")
else:
rmtree(get_workdir())
debug("Done", "Mux")
return outfile