Skip to content

Commit

Permalink
Improve resolve export
Browse files Browse the repository at this point in the history
  • Loading branch information
WyattBlue committed Aug 31, 2024
1 parent d8054be commit 93e2264
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 39 deletions.
40 changes: 22 additions & 18 deletions auto_editor/edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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)),
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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)
Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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
Expand Down
33 changes: 16 additions & 17 deletions auto_editor/formats/fcp11.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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):
Expand Down Expand Up @@ -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, "
Expand Down
8 changes: 4 additions & 4 deletions auto_editor/formats/fcp7.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -443,16 +443,16 @@ 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")
ET.SubElement(audio, "numOutputChannels").text = "2"
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:
Expand Down

0 comments on commit 93e2264

Please sign in to comment.