[go: nahoru, domu]

Skip to content

Commit

Permalink
Remove source indirection
Browse files Browse the repository at this point in the history
  • Loading branch information
WyattBlue committed Dec 3, 2023
2 parents 057fbb2 + 0399d51 commit 41be39d
Show file tree
Hide file tree
Showing 18 changed files with 315 additions and 289 deletions.
14 changes: 4 additions & 10 deletions auto_editor/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def obj_tag(tag: str, tb: Fraction, obj: dict[str, Any]) -> str:
return key


@dataclass
@dataclass(slots=True)
class Levels:
ensure: Ensure
src: FileInfo
Expand All @@ -164,9 +164,7 @@ def media_length(self) -> int:
if (arr := self.read_cache("audio", {"stream": 0})) is not None:
return len(arr)

sr, samples = read(
self.ensure.audio(f"{self.src.path.resolve()}", self.src.label, 0)
)
sr, samples = read(self.ensure.audio(self.src, 0))
samp_count = len(samples)
del samples

Expand Down Expand Up @@ -262,9 +260,7 @@ def audio(self, s: int) -> NDArray[np.float_]:
if (arr := self.read_cache("audio", {"stream": s})) is not None:
return arr

sr, samples = read(
self.ensure.audio(f"{self.src.path.resolve()}", self.src.label, s)
)
sr, samples = read(self.ensure.audio(self.src, s))

if len(samples) == 0:
raise LevelError(f"audio: stream '{s}' has no samples.")
Expand Down Expand Up @@ -326,9 +322,7 @@ def subtitle(
except re.error as e:
self.log.error(e)

sub_file = self.ensure.subtitle(
f"{self.src.path.resolve()}", self.src.label, stream=stream
)
sub_file = self.ensure.subtitle(self.src, stream)
parser = SubtitleParser(self.tb)

with open(sub_file, encoding="utf-8") as file:
Expand Down
49 changes: 15 additions & 34 deletions auto_editor/edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,25 +117,6 @@ def set_audio_codec(
return codec


def make_sources(
paths: list[str], ffmpeg: FFmpeg, log: Log
) -> tuple[dict[str, FileInfo], list[int]]:
used_paths: dict[str, int] = {}
sources: dict[str, FileInfo] = {}
inputs: list[int] = []

i = 0
for path in paths:
if path in used_paths:
inputs.append(used_paths[path])
else:
sources[str(i)] = initFileInfo(path, ffmpeg, log, str(i))
inputs.append(i)
used_paths[path] = i
i += 1
return sources, inputs


def parse_export(export: str, log: Log) -> dict[str, Any]:
exploded = export.split(":", maxsplit=1)
if len(exploded) == 1:
Expand Down Expand Up @@ -181,25 +162,27 @@ def edit_media(
from auto_editor.formats.fcp7 import fcp7_read_xml

tl = fcp7_read_xml(paths[0], ffmpeg, log)
src: FileInfo | None = next(iter(tl.sources.items()))[1]
sources = tl.sources
assert tl.src is not None
sources: list[FileInfo] = [tl.src]
src: FileInfo | None = tl.src

elif path_ext == ".mlt":
from auto_editor.formats.shotcut import shotcut_read_mlt

tl = shotcut_read_mlt(paths[0], ffmpeg, log)
src = next(iter(tl.sources.items()))[1]
sources = tl.sources
assert tl.src is not None
sources = [tl.src]
src = tl.src

elif path_ext == ".json":
from auto_editor.formats.json import read_json

tl = read_json(paths[0], ffmpeg, log)
sources = tl.sources
src = sources["0"]
sources = [] if tl.src is None else [tl.src]
src = tl.src
else:
sources, inputs = make_sources(paths, ffmpeg, log)
src = None if not inputs else sources[str(inputs[0])]
sources = [initFileInfo(path, ffmpeg, log) for path in paths]
src = None if not sources else sources[0]

del paths

Expand Down Expand Up @@ -240,9 +223,7 @@ def edit_media(
cmd.extend([os.path.join(temp, f"{s}s.{sub.ext}")])
ffmpeg.run(cmd)

tl = make_timeline(
sources, inputs, ffmpeg, ensure, args, samplerate, bar, temp, log
)
tl = make_timeline(sources, ffmpeg, ensure, args, samplerate, bar, temp, log)

if export["export"] == "timeline":
from auto_editor.formats.json import make_json_timeline
Expand Down Expand Up @@ -342,8 +323,6 @@ def make_media(tl: v3, output: str) -> None:
if tl.v1 is None:
log.error("Timeline too complex to use clip-sequence export")

sources = {"0": tl.v1.source}

from auto_editor.make_layers import clipify, make_av
from auto_editor.utils.func import append_filename

Expand All @@ -360,9 +339,11 @@ def pad_chunk(chunk: Chunk, total: int) -> Chunks:

padded_chunks = pad_chunk(chunk, total_frames)

vspace, aspace = make_av([clipify(padded_chunks, "0")], sources, [0])
vspace, aspace = make_av(
tl.v1.source, [clipify(padded_chunks, tl.v1.source)]
)
my_timeline = v3(
sources,
tl.v1.source,
tl.tb,
tl.sr,
tl.res,
Expand Down
8 changes: 5 additions & 3 deletions auto_editor/ffwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ class FileInfo:
videos: tuple[VideoStream, ...]
audios: tuple[AudioStream, ...]
subtitles: tuple[SubtitleStream, ...]
label: str

def get_res(self) -> tuple[int, int]:
if self.videos:
Expand All @@ -188,7 +187,7 @@ def get_sr(self) -> int:
return 48000


def initFileInfo(path: str, ffmpeg: FFmpeg, log: Log, label: str = "") -> FileInfo:
def initFileInfo(path: str, ffmpeg: FFmpeg, log: Log) -> FileInfo:
import av

av.logging.set_level(av.logging.PANIC)
Expand Down Expand Up @@ -245,6 +244,9 @@ def initFileInfo(path: str, ffmpeg: FFmpeg, log: Log, label: str = "") -> FileIn
else:
sar = v.sample_aspect_ratio

assert type(v.codec_context.pix_fmt) is str
assert type(v.time_base) is Fraction

videos += (
VideoStream(
v.width,
Expand Down Expand Up @@ -292,4 +294,4 @@ def initFileInfo(path: str, ffmpeg: FFmpeg, log: Log, label: str = "") -> FileIn

cont.close()

return FileInfo(Path(path), bitrate, dur, desc, videos, audios, subtitles, label)
return FileInfo(Path(path), bitrate, dur, desc, videos, audios, subtitles)
5 changes: 2 additions & 3 deletions auto_editor/formats/fcp11.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ def fraction(val: int) -> str:
return "0s"
return f"{val * tl.tb.denominator}/{tl.tb.numerator}s"

for _, _src in tl.sources.items():
src = _src
break
src = tl.src
assert src is not None

proj_name = src.path.stem
src_dur = int(src.duration * tl.tb)
Expand Down
74 changes: 42 additions & 32 deletions auto_editor/formats/fcp7.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .utils import Validator, make_tracks_dir, show

if TYPE_CHECKING:
from pathlib import Path
pass

from auto_editor.utils.log import Log

Expand Down Expand Up @@ -188,7 +188,7 @@ def speedup(speed: float) -> Element:
"""


SUPPORTED_EFFECTS = ["timeremap"]
SUPPORTED_EFFECTS = ("timeremap",)


def read_filters(clipitem: Element, log: Log) -> float:
Expand Down Expand Up @@ -325,7 +325,6 @@ def xml_bool(val: str) -> bool:
uri_to_path(fileobj["pathurl"]),
ffmpeg,
log,
str(len(sources)),
)
else:
show(clipitem["file"], 3)
Expand All @@ -342,7 +341,9 @@ def xml_bool(val: str) -> bool:
dur = clipitem["end"] - start
offset = int(clipitem["in"] * speed)

vobjs[t].append(TlVideo(start, dur, file_id, offset, speed, stream=0))
vobjs[t].append(
TlVideo(start, dur, sources[file_id], offset, speed, stream=0)
)

if "audio" in av:
tracks = valid.parse(av["audio"], aclip_schema)
Expand All @@ -356,7 +357,7 @@ def xml_bool(val: str) -> bool:
if file_id not in sources:
fileobj = valid.parse(clipitem["file"], {"pathurl": str})
sources[file_id] = initFileInfo(
uri_to_path(fileobj["pathurl"]), ffmpeg, log, str(len(sources))
uri_to_path(fileobj["pathurl"]), ffmpeg, log
)

if "filter" in clipitem:
Expand All @@ -369,10 +370,18 @@ def xml_bool(val: str) -> bool:
offset = int(clipitem["in"] * speed)

aobjs[t].append(
TlAudio(start, dur, file_id, offset, speed, volume=1, stream=0)
TlAudio(
start, dur, sources[file_id], offset, speed, volume=1, stream=0
)
)

return v3(sources, tb, sr, res, "#000", vobjs, aobjs, None)
primary_src = sources[next(iter(sources))]
assert type(primary_src) is FileInfo
print(sources)
print(vobjs)
print(aobjs)
print("=================")
return v3(primary_src, tb, sr, res, "#000", vobjs, aobjs, v1=None)


def media_def(
Expand Down Expand Up @@ -414,31 +423,30 @@ def fcp7_write_xml(name: str, ffmpeg: FFmpeg, output: str, tl: v3, log: Log) ->
width, height = tl.res
timebase, ntsc = set_tb_ntsc(tl.tb)

key_to_url: dict[tuple[str, int], str] = {}
key_to_id: dict[tuple[str, int], str] = {}
key_to_source: dict[tuple[str, int], FileInfo] = {}
src_to_url: dict[tuple[FileInfo, int], str] = {}
src_to_id: dict[tuple[FileInfo, int], str] = {}
src_to_src: dict[tuple[FileInfo, int], FileInfo] = {}

file_defs: set[str] = set() # Contains urls

def path_resolve(path: Path) -> str:
return f"{path.resolve()}"
for src in set(tl.sources):
path_resolve = f"{src.path.resolve()}"
the_id = f"file-{len(src_to_id)+1}"

for key, src in tl.sources.items():
key_to_source[(key, 0)] = src
key_to_id[(key, 0)] = f"file-{len(key_to_id)+1}"
key_to_url[(key, 0)] = path_resolve(src.path)
src_to_url[(src, 0)] = path_resolve
src_to_id[(src, 0)] = the_id

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}"]
)
ffmpeg.run(["-i", path_resolve, "-map", f"0:a:{i}", f"{newtrack}"])

key_to_source[(key, i)] = initFileInfo(f"{newtrack}", ffmpeg, log, key)
key_to_url[(key, i)] = path_resolve(newtrack)
key_to_id[(key, i)] = f"file-{len(key_to_id)+1}"
new_src = initFileInfo(f"{newtrack}", ffmpeg, log)
src_to_url[(src, i)] = f"{newtrack.resolve()}"
src_to_id[(src, i)] = f"file-{len(src_to_id)+1}"
src_to_src[(src, i)] = new_src

xmeml = ET.Element("xmeml", version="4")
sequence = ET.SubElement(xmeml, "sequence")
Expand Down Expand Up @@ -466,7 +474,6 @@ def path_resolve(path: Path) -> str:

for j, clip in enumerate(tl.v[0]):
assert isinstance(clip, TlVideo)
src = tl.sources[clip.src]

_start = f"{clip.start}"
_end = f"{clip.start + clip.dur}"
Expand All @@ -481,13 +488,12 @@ def path_resolve(path: Path) -> str:
ET.SubElement(clipitem, "in").text = _in
ET.SubElement(clipitem, "out").text = _out

_id = key_to_id[(clip.src, clip.stream)]
_id = src_to_id[(clip.src, 0)]
filedef = ET.SubElement(clipitem, "file", id=_id)

pathurl = key_to_url[(clip.src, clip.stream)]
my_src = key_to_source[(clip.src, clip.stream)]
pathurl = src_to_url[(clip.src, 0)]
if pathurl not in file_defs:
media_def(filedef, pathurl, my_src, tl, timebase, ntsc)
media_def(filedef, pathurl, clip.src, tl, timebase, ntsc)
file_defs.add(pathurl)

if clip.speed != 1:
Expand Down Expand Up @@ -518,7 +524,7 @@ def path_resolve(path: Path) -> str:
)

for j, aclip in enumerate(aclips):
src = tl.sources[aclip.src]
src = aclip.src

_start = f"{aclip.start}"
_end = f"{aclip.start + aclip.dur}"
Expand All @@ -545,11 +551,15 @@ def path_resolve(path: Path) -> str:
ET.SubElement(clipitem, "in").text = _in
ET.SubElement(clipitem, "out").text = _out

_id = key_to_id[(aclip.src, aclip.stream)]
filedef = ET.SubElement(clipitem, "file", id=_id)
_id = src_to_id[(aclip.src, aclip.stream)]
pathurl = src_to_url[(aclip.src, aclip.stream)]

if aclip.stream > 0:
my_src = src_to_src[(aclip.src, aclip.stream)]
else:
my_src = aclip.src

pathurl = key_to_url[(aclip.src, aclip.stream)]
my_src = key_to_source[(aclip.src, aclip.stream)]
filedef = ET.SubElement(clipitem, "file", id=_id)
if pathurl not in file_defs:
media_def(filedef, pathurl, my_src, tl, timebase, ntsc)
file_defs.add(pathurl)
Expand Down
Loading

0 comments on commit 41be39d

Please sign in to comment.