Añadir make_desc.py
This commit is contained in:
104
make_desc.py
Normal file
104
make_desc.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# Copyright (C) 2026 by WallyHackenslacker wallyhackenslacker@noreply.git.hackenslacker.space
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without
|
||||||
|
# fee is hereby granted.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
|
||||||
|
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||||
|
# FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import sys
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
|
||||||
|
def parse_fps(value):
|
||||||
|
text = str(value).strip()
|
||||||
|
if "/" in text:
|
||||||
|
numerator, denominator = text.split("/", 1)
|
||||||
|
return float(numerator) / float(denominator)
|
||||||
|
return float(text)
|
||||||
|
|
||||||
|
|
||||||
|
def format_timestamp(position_frames, fps):
|
||||||
|
total_seconds = int(position_frames / fps)
|
||||||
|
hours, remainder = divmod(total_seconds, 3600)
|
||||||
|
minutes, seconds = divmod(remainder, 60)
|
||||||
|
|
||||||
|
if hours > 0:
|
||||||
|
return f"{hours}:{minutes:02d}:{seconds:02d}"
|
||||||
|
|
||||||
|
return f"{minutes}:{seconds:02d}"
|
||||||
|
|
||||||
|
|
||||||
|
def parse_cli_args(argv, xml_fps):
|
||||||
|
if len(argv) < 2:
|
||||||
|
raise SystemExit("Usage: make_desc.py <tracks.xml> [fps] [output.txt]")
|
||||||
|
|
||||||
|
input_file = argv[1]
|
||||||
|
fps = parse_fps(xml_fps)
|
||||||
|
output_file = "desc.txt"
|
||||||
|
|
||||||
|
if len(argv) >= 3:
|
||||||
|
try:
|
||||||
|
fps = parse_fps(argv[2])
|
||||||
|
if len(argv) >= 4:
|
||||||
|
output_file = argv[3]
|
||||||
|
except ValueError:
|
||||||
|
output_file = argv[2]
|
||||||
|
|
||||||
|
return input_file, fps, output_file
|
||||||
|
|
||||||
|
|
||||||
|
# Read the input file into an XML tree.
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
raise SystemExit("Usage: make_desc.py <tracks.xml> [fps] [output.txt]")
|
||||||
|
|
||||||
|
tree = ET.parse(sys.argv[1])
|
||||||
|
root = tree.getroot()
|
||||||
|
input_path, framerate, output_path = parse_cli_args(
|
||||||
|
sys.argv, root.attrib.get("fps", 25.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get all chains in the tree. Chains are media files and metadata.
|
||||||
|
chains = {}
|
||||||
|
|
||||||
|
for c in tree.iter("chain"):
|
||||||
|
chain = {}
|
||||||
|
chain_id = None
|
||||||
|
|
||||||
|
for p in c:
|
||||||
|
if p.attrib["name"] == "resource" and p.text:
|
||||||
|
chain["file"] = os.path.basename(p.text)
|
||||||
|
elif p.attrib["name"] == "kdenlive:id":
|
||||||
|
if p.text:
|
||||||
|
chain_id = int(p.text)
|
||||||
|
elif p.attrib["name"] == "length" and p.text:
|
||||||
|
chain["length"] = int(p.text)
|
||||||
|
|
||||||
|
if chain_id is not None and "file" in chain:
|
||||||
|
chains[chain_id] = chain
|
||||||
|
|
||||||
|
# Get all clips in the tree. Clips are media files in the timeline.
|
||||||
|
clips = []
|
||||||
|
|
||||||
|
for c in tree.iter("clip"):
|
||||||
|
clip = {
|
||||||
|
"position": int(c.attrib["position"]),
|
||||||
|
"bin": int(c.attrib["binid"]),
|
||||||
|
}
|
||||||
|
|
||||||
|
clips.append(clip)
|
||||||
|
|
||||||
|
# Sort clips by time.
|
||||||
|
clips.sort(key=lambda x: x["position"])
|
||||||
|
|
||||||
|
# Write the description file.
|
||||||
|
with open(output_path, "w") as f:
|
||||||
|
f.write("Track list:\n")
|
||||||
|
|
||||||
|
for c in clips:
|
||||||
|
timestamp = format_timestamp(c["position"], framerate)
|
||||||
|
f.write(f"({timestamp}) {chains[c['bin']]['file']}\n")
|
||||||
Reference in New Issue
Block a user