diff --git a/auto_editor/__main__.py b/auto_editor/__main__.py index 253e75a23..f08533c41 100755 --- a/auto_editor/__main__.py +++ b/auto_editor/__main__.py @@ -140,10 +140,7 @@ def main_options(parser: ArgumentParser) -> ArgumentParser: ) parser.add_text("Utility Options:") parser.add_argument( - "--export", - "-ex", - metavar="EXPORT:ATTRS?", - help="Choose the export mode", + "--export", "-ex", metavar="EXPORT:ATTRS?", help="Choose the export mode" ) parser.add_argument( "--output-file", @@ -153,15 +150,10 @@ def main_options(parser: ArgumentParser) -> ArgumentParser: help="Set the name/path of the new output file.", ) parser.add_argument( - "--player", - "-p", - metavar="CMD", - help="Set player to open output media files", + "--player", "-p", metavar="CMD", help="Set player to open output media files" ) parser.add_argument( - "--no-open", - flag=True, - help="Do not open the output file after editing is done", + "--no-open", flag=True, help="Do not open the output file after editing is done" ) parser.add_argument( "--temp-dir", @@ -255,7 +247,7 @@ def main_options(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( "--audio-normalize", metavar="NORM-TYPE", - help="Apply audio rendering to all audio tracks. Applied right before rendering the output file.", + help="Apply audio rendering to all audio tracks. Applied right before rendering the output file", ) parser.add_text("Miscellaneous:") parser.add_argument( @@ -268,6 +260,9 @@ def main_options(parser: ArgumentParser) -> ArgumentParser: metavar="CMD", help="Add extra options for ffmpeg. Must be in quotes", ) + parser.add_argument( + "--no-cache", flag=True, help="Don't look for or write a cache file" + ) parser.add_argument("--version", "-V", flag=True, help="Display version and halt") return parser diff --git a/auto_editor/analyze.py b/auto_editor/analyze.py index 11a6b89b7..50c308718 100644 --- a/auto_editor/analyze.py +++ b/auto_editor/analyze.py @@ -175,6 +175,7 @@ class Levels: src: FileInfo tb: Fraction bar: Bar + no_cache: bool temp: str log: Log @@ -210,6 +211,9 @@ def all(self) -> NDArray[np.bool_]: return np.zeros(self.media_length, dtype=np.bool_) def read_cache(self, tag: str, obj: dict[str, Any]) -> None | np.ndarray: + if self.no_cache: + return None + workfile = os.path.join( os.path.dirname(self.temp), f"ae-{__version__}", "cache.npz" ) @@ -227,7 +231,10 @@ def read_cache(self, tag: str, obj: dict[str, Any]) -> None | np.ndarray: self.log.debug("Using cache") return npzfile[key] - def cache(self, tag: str, obj: dict[str, Any], arr: np.ndarray) -> np.ndarray: + def cache(self, arr: np.ndarray, tag: str, obj: dict[str, Any]) -> np.ndarray: + if self.no_cache: + return arr + workdur = os.path.join(os.path.dirname(self.temp), f"ae-{__version__}") if not os.path.exists(workdur): os.mkdir(workdur) @@ -268,7 +275,7 @@ def audio(self, stream: int) -> NDArray[np.float32]: index += 1 bar.end() - return self.cache("audio", {"stream": stream}, result[:index]) + return self.cache(result[:index], "audio", {"stream": stream}) def motion(self, stream: int, blur: int, width: int) -> NDArray[np.float32]: if stream >= len(self.src.videos): @@ -301,7 +308,7 @@ def motion(self, stream: int, blur: int, width: int) -> NDArray[np.float32]: index += 1 bar.end() - return self.cache("motion", mobj, result[:index]) + return self.cache(result[:index], "motion", mobj) def subtitle( self, diff --git a/auto_editor/make_layers.py b/auto_editor/make_layers.py index ed0c51fb9..f13a185ad 100644 --- a/auto_editor/make_layers.py +++ b/auto_editor/make_layers.py @@ -71,44 +71,6 @@ def make_av(src: FileInfo, all_clips: list[list[Clip]]) -> tuple[VSpace, ASpace] return vtl, atl -def run_interpreter_for_edit_option( - text: str, filesetup: FileSetup -) -> NDArray[np.bool_]: - src = filesetup.src - tb = filesetup.tb - bar = filesetup.bar - temp = filesetup.temp - log = filesetup.log - - try: - parser = Parser(Lexer("`--edit`", text)) - if log.is_debug: - log.debug(f"edit: {parser}") - - env["timebase"] = tb - env["@levels"] = Levels(src, tb, bar, temp, log) - env["@filesetup"] = filesetup - - results = interpret(env, parser) - - if len(results) == 0: - raise MyError("Expression in --edit must return a bool-array, got nothing") - - result = results[-1] - if callable(result): - result = result() - - if not is_boolarr(result): - raise MyError( - f"Expression in --edit must return a bool-array, got {print_str(result)}" - ) - except MyError as e: - log.error(e) - - assert isinstance(result, np.ndarray) - return result - - def make_sane_timebase(fps: Fraction) -> Fraction: tb = round(fps, 2) @@ -159,8 +121,6 @@ def make_timeline( except CoerceError as e: log.error(e) - method = args.edit_based_on - has_loud = np.array([], dtype=np.bool_) src_index = np.array([], dtype=np.int32) concat = np.concatenate @@ -168,11 +128,36 @@ def make_timeline( for i, src in enumerate(sources): filesetup = FileSetup(src, len(sources) < 2, tb, bar, temp, log) - edit_result = run_interpreter_for_edit_option(method, filesetup) - mut_margin(edit_result, start_margin, end_margin) + try: + parser = Parser(Lexer("`--edit`", args.edit_based_on)) + if log.is_debug: + log.debug(f"edit: {parser}") + + env["timebase"] = tb + env["@levels"] = Levels(src, tb, bar, args.no_cache, temp, log) + env["@filesetup"] = filesetup + + results = interpret(env, parser) + + if len(results) == 0: + log.error("Expression in --edit must return a bool-array, got nothing") + + result = results[-1] + if callable(result): + result = result() + except MyError as e: + log.error(e) + + if not is_boolarr(result): + log.error( + f"Expression in --edit must return a bool-array, got {print_str(result)}" + ) + assert isinstance(result, np.ndarray) + + mut_margin(result, start_margin, end_margin) - has_loud = concat((has_loud, edit_result)) - src_index = concat((src_index, np.full(len(edit_result), i, dtype=np.int32))) + has_loud = concat((has_loud, result)) + src_index = concat((src_index, np.full(len(result), i, dtype=np.int32))) # Setup for handling custom speeds speed_index = has_loud.astype(np.uint) diff --git a/auto_editor/preview.py b/auto_editor/preview.py index 56613ffaf..bd2d4fe9f 100644 --- a/auto_editor/preview.py +++ b/auto_editor/preview.py @@ -65,7 +65,7 @@ def preview(tl: v3, temp: str, log: Log) -> None: in_len = 0 for src in all_sources: - in_len += Levels(src, tb, Bar("none"), temp, log).media_length + in_len += Levels(src, tb, Bar("none"), False, temp, log).media_length out_len = tl.out_len() diff --git a/auto_editor/subcommands/levels.py b/auto_editor/subcommands/levels.py index 8332d00df..2c739123c 100644 --- a/auto_editor/subcommands/levels.py +++ b/auto_editor/subcommands/levels.py @@ -129,7 +129,7 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None: except ParserError as e: log.error(e) - levels = Levels(src, tb, bar, temp, log) + levels = Levels(src, tb, bar, False, temp, log) try: if method == "audio": print_arr_gen(iter_audio(src, tb, **obj)) diff --git a/auto_editor/subcommands/repl.py b/auto_editor/subcommands/repl.py index 621cc8715..cf315a4c3 100644 --- a/auto_editor/subcommands/repl.py +++ b/auto_editor/subcommands/repl.py @@ -67,7 +67,7 @@ def main(sys_args: list[str] = sys.argv[1:]) -> None: tb = src.get_fps() if args.timebase is None else args.timebase bar = Bar("modern") env["timebase"] = tb - env["@levels"] = Levels(src, tb, bar, temp, log) + env["@levels"] = Levels(src, tb, bar, False, temp, log) env["@filesetup"] = FileSetup(src, strict, tb, bar, temp, log) print(f"Auto-Editor {auto_editor.__version__}") diff --git a/auto_editor/utils/types.py b/auto_editor/utils/types.py index 0b475ef1d..d703f85df 100644 --- a/auto_editor/utils/types.py +++ b/auto_editor/utils/types.py @@ -217,7 +217,7 @@ def resolution(val: str | None) -> tuple[int, int] | None: return natural(vals[0]), natural(vals[1]) -@dataclass +@dataclass(slots=True) class Args: yt_dlp_location: str = "yt-dlp" download_format: str | None = None @@ -255,6 +255,7 @@ class Args: show_ffmpeg_output: bool = False quiet: bool = False preview: bool = False + no_cache: bool = False margin: tuple[str, str] = ("0.2s", "0.2s") silent_speed: float = 99999.0 video_speed: float = 1.0