diff --git a/auto_editor/edit.py b/auto_editor/edit.py index 8d91bcb40..a70cb65bc 100644 --- a/auto_editor/edit.py +++ b/auto_editor/edit.py @@ -15,6 +15,7 @@ from auto_editor.utils.chunks import Chunk, Chunks from auto_editor.utils.cmdkw import ParserError, parse_with_palet, pAttr, pAttrs from auto_editor.utils.container import Container, container_constructor +from auto_editor.utils.func import open_with_system_default from auto_editor.utils.log import Log from auto_editor.utils.types import Args @@ -45,8 +46,9 @@ def set_output( ext_map = { "premiere": ".xml", - "resolve": ".fcpxml", + "resolve-fcp7": ".xml", "final-cut-pro": ".fcpxml", + "resolve": ".fcpxml", "shotcut": ".mlt", "json": ".json", "audio": ".wav", @@ -122,8 +124,9 @@ def parse_export(export: str, log: Log) -> dict[str, Any]: parsing: dict[str, pAttrs] = { "default": pAttrs("default"), "premiere": pAttrs("premiere", name_attr), - "resolve": pAttrs("resolve", name_attr), + "resolve-fcp7": pAttrs("resolve-fcp7", name_attr), "final-cut-pro": pAttrs("final-cut-pro", name_attr), + "resolve": pAttrs("resolve", name_attr), "shotcut": pAttrs("shotcut"), "json": pAttrs("json", pAttr("api", 3, is_int)), "timeline": pAttrs("json", pAttr("api", 3, is_int)), @@ -176,10 +179,11 @@ def edit_media(paths: list[str], ffmpeg: FFmpeg, args: Args, log: Log) -> None: del paths - output, export = set_output(args.output_file, args.export, src, log) - assert "export" in export + output, export_ops = set_output(args.output_file, args.export, src, log) + assert "export" in export_ops + export = export_ops["export"] - if export["export"] == "timeline": + if export == "timeline": log.quiet = True if not args.preview: @@ -203,10 +207,10 @@ def edit_media(paths: list[str], ffmpeg: FFmpeg, args: Args, log: Log) -> None: if tl is None: tl = make_timeline(sources, args, samplerate, bar, log) - if export["export"] == "timeline": + if export == "timeline": from auto_editor.formats.json import make_json_timeline - make_json_timeline(export["api"], 0, tl, log) + make_json_timeline(export_ops["api"], 0, tl, log) return if args.preview: @@ -215,25 +219,27 @@ def edit_media(paths: list[str], ffmpeg: FFmpeg, args: Args, log: Log) -> None: preview(tl, log) return - if export["export"] == "json": + if export == "json": from auto_editor.formats.json import make_json_timeline - make_json_timeline(export["api"], output, tl, log) + make_json_timeline(export_ops["api"], output, tl, log) return - if export["export"] == "premiere": + if export in ("premiere", "resolve-fcp7"): from auto_editor.formats.fcp7 import fcp7_write_xml - fcp7_write_xml(export["name"], output, tl, log) + is_resolve = export.startswith("resolve") + fcp7_write_xml(export_ops["name"], output, is_resolve, tl, log) return - if export["export"] in ("final-cut-pro", "resolve"): + if export in ("final-cut-pro", "resolve"): from auto_editor.formats.fcp11 import fcp11_write_xml - fcp11_write_xml(export["name"], ffmpeg, output, export["export"], tl, log) + is_resolve = export.startswith("resolve") + fcp11_write_xml(export_ops["name"], ffmpeg, output, is_resolve, tl, log) return - if export["export"] == "shotcut": + if export == "shotcut": from auto_editor.formats.shotcut import shotcut_write_mlt shotcut_write_mlt(output, tl) @@ -297,7 +303,7 @@ def make_media(tl: v3, output: str) -> None: log, ) - if export["export"] == "clip-sequence": + if export == "clip-sequence": if tl.v1 is None: log.error("Timeline too complex to use clip-sequence export") @@ -338,10 +344,8 @@ def pad_chunk(chunk: Chunk, total: int) -> Chunks: log.stop_timer() - if not args.no_open and export["export"] in ("default", "audio", "clip-sequence"): + if not args.no_open and export in ("default", "audio", "clip-sequence"): if args.player is None: - from auto_editor.utils.func import open_with_system_default - open_with_system_default(output, log) else: import subprocess diff --git a/auto_editor/formats/fcp11.py b/auto_editor/formats/fcp11.py index c6c483b8f..64293fdd3 100644 --- a/auto_editor/formats/fcp11.py +++ b/auto_editor/formats/fcp11.py @@ -54,7 +54,7 @@ def make_name(src: FileInfo, tb: Fraction) -> str: def fcp11_write_xml( - group_name: str, ffmpeg: FFmpeg, output: str, flavor: str, tl: v3, log: Log + group_name: str, ffmpeg: FFmpeg, output: str, resolve: bool, tl: v3, log: Log ) -> None: def fraction(val: int) -> str: if val == 0: @@ -66,23 +66,22 @@ def fraction(val: int) -> str: proj_name = src.path.stem src_dur = int(src.duration * tl.tb) - tl_dur = src_dur if flavor == "resolve" else tl.out_len() + tl_dur = src_dur if resolve else tl.out_len() all_srcs: list[FileInfo] = [src] all_refs: list[str] = ["r2"] - if flavor == "resolve": - if len(src.audios) > 1: - fold = make_tracks_dir(src) - - for i in range(1, len(src.audios)): - newtrack = fold / f"{i}.wav" - ffmpeg.run( - ["-i", f"{src.path.resolve()}", "-map", f"0:a:{i}", f"{newtrack}"] - ) - all_srcs.append(initFileInfo(f"{newtrack}", log)) - all_refs.append(f"r{(i + 1) * 2}") - - fcpxml = Element("fcpxml", version="1.10" if flavor == "resolve" else "1.11") + if resolve and len(src.audios) > 1: + fold = make_tracks_dir(src) + + for i in range(1, len(src.audios)): + newtrack = fold / f"{i}.wav" + ffmpeg.run( + ["-i", f"{src.path.resolve()}", "-map", f"0:a:{i}", f"{newtrack}"] + ) + all_srcs.append(initFileInfo(f"{newtrack}", log)) + all_refs.append(f"r{(i + 1) * 2}") + + fcpxml = Element("fcpxml", version="1.10" if resolve else "1.11") resources = SubElement(fcpxml, "resources") for i, one_src in enumerate(all_srcs): @@ -163,9 +162,9 @@ def make_clip(ref: str, clip: TlVideo | TlAudio, speed_warn: bool) -> bool: warn = False for my_ref in all_refs: for clip in clips: - warn = make_clip(my_ref, clip, warn) + warn = make_clip(my_ref, clip, warn) or warn - if flavor == "resolve" and warn: + if resolve and warn: log.warning( "DaVinci Resolve may take a very long time when importing timelines with " "speed effects. Consider switching to Premiere Pro, " diff --git a/auto_editor/formats/fcp7.py b/auto_editor/formats/fcp7.py index 96933b946..fab4d32b2 100644 --- a/auto_editor/formats/fcp7.py +++ b/auto_editor/formats/fcp7.py @@ -372,7 +372,7 @@ def media_def( ET.SubElement(audiodef, "channelcount").text = f"{aud.channels}" -def fcp7_write_xml(name: str, output: str, tl: v3, log: Log) -> None: +def fcp7_write_xml(name: str, output: str, resolve: bool, tl: v3, log: Log) -> None: width, height = tl.res timebase, ntsc = set_tb_ntsc(tl.tb) @@ -443,8 +443,8 @@ def fcp7_write_xml(name: str, output: str, tl: v3, log: Log) -> None: link, "linkclipref" ).text = f"clipitem-{(i*(len(tl.v[0])))+j+1}" ET.SubElement(link, "mediatype").text = "video" if i == 0 else "audio" - ET.SubElement(link, "trackindex").text = str(max(i, 1)) - ET.SubElement(link, "clipindex").text = str(j + 1) + ET.SubElement(link, "trackindex").text = f"{max(i, 1)}" + ET.SubElement(link, "clipindex").text = f"{j + 1}" # Audio definitions and clips audio = ET.SubElement(media, "audio") @@ -452,7 +452,7 @@ def fcp7_write_xml(name: str, output: str, tl: v3, log: Log) -> None: aformat = ET.SubElement(audio, "format") aschar = ET.SubElement(aformat, "samplecharacteristics") ET.SubElement(aschar, "depth").text = DEPTH - ET.SubElement(aschar, "samplerate").text = str(tl.sr) + ET.SubElement(aschar, "samplerate").text = f"{tl.sr}" t = 0 for aclips in tl.a: