Watch at Ease看见世界,读懂生活。

科技 · 实用指南

将 Shotcut 已保存播放列表导出为 CSV,保留重复子片段

保留重复片段、已存名称和原始入出点;离线报告不能当作时间线资源或删除清单。

保留已存播放列表重复条目的原创示意图
原创假想数据示意:producer A 的两次引用分别保留行、名称和裁剪文字。 Watch at Ease

唯一媒体文件名清单可能丢掉需要的播放列表信息:两个不同裁剪片段可以来自同一文件。报告应保留每个条目、位置和已存名称,不合成一个资源。

Shotcut 已能从播放列表分组导出视频,当前批量命名也能使用源名称。本指南补充受限离线 CSV:只读自己已存主列表的受支持 MLT 副本,不修改项目或打开媒体;不导出视频,也不判断可删除文件。

保存项目,区分清单

保存当前项目、关闭,另留名为 project.mlt 的 MLT 副本作报告。方法要求自己的 UTF-8 纯 XML,恰好一个顶层 main_bin 列表或旧名 main bin,条目直接引用顶层 producer 或 chain。命名空间、嵌套或复合条目、空白片段及带声明的 XML 均不支持,创建输出前停止。

已存主列表包含全部条目。不从运行中的界面读取所选分组、搜索筛选或显示顺序。当前源码以 shotcut:bins 保存分组文字,以 shotcut:caption 保存友好显示文字;缺失属性写空单元格。不重建自动文件名标签、智能分组归属或界面备用显示名称。

需要视频文件时,用原生 Current Playlist Bin 或 Each Playlist Bin Item 导出。只需唯一资源清单时,现有 MLT Analyzer 已可下载。这些输出与本报告不同:本方法保留条目顺序和重复项,不修复搬动项目或修改路径。

执行受限 CSV 转换

在 Linux Bash 终端使用 Python 3,进入 project.mlt 副本目录。命令按一行复制,保留直引号和反斜杠。换新输出名;已有 playlist.csv 会被拒绝。这条准确命令在 Linux Bash 执行过,未在 Windows 或 macOS 测试。

XML 解析器将主列表引用对应到 producer 或 chain,只读其直接指定属性。滤镜自身资源不会当作片段资源。顶层 ID 重复、引用缺失、指定属性重复和不支持的条目结构均在创建 CSV 前停止。

python3 -c 'exec('"'"'import csv, sys, xml.etree.ElementTree as E\nfrom pathlib import Path\nsrc, dst = map(Path, sys.argv[1:])\nraw = src.read_bytes()\ntext = raw.decode("utf-8-sig")\nif "<!DOCTYPE" in text.upper() or "<!ENTITY" in text.upper():\n raise ValueError("Own plain XML only; declarations unsupported")\nroot = E.fromstring(text)\nif root.tag != "mlt":\n raise ValueError("Expected unnamespaced mlt root")\nbins = [x for x in root if x.tag == "playlist" and x.get("id") in ("main_bin", "main bin")]\nif len(bins) != 1:\n raise ValueError("Need exactly one saved main playlist")\nobjects = {}\nfor x in root:\n if x.get("id"):\n if x.get("id") in objects:\n raise ValueError("Duplicate top-level ID")\n objects[x.get("id")] = x\nkeys = ["shotcut:caption", "shotcut:bins", "mlt_service", "resource", "shotcut:resource", "warp_resource", "shotcut:comment"]\nrows = []\nfor entry in bins[0]:\n if entry.tag == "property":\n continue\n if entry.tag != "entry" or len(entry):\n raise ValueError("Only direct referenced entries supported")\n pid = entry.get("producer", "")\n obj = objects.get(pid)\n if obj is None or obj.tag not in ("producer", "chain"):\n raise ValueError("Missing or composite producer reference")\n values = {}\n for prop in obj.findall("property"):\n name = prop.get("name")\n if name in keys:\n if name in values or len(prop):\n raise ValueError("Duplicate or nested selected property")\n values[name] = prop.get("value", prop.text or "")\n rows.append([str(len(rows)+1), pid, values.get(keys[0], ""), values.get(keys[1], ""), entry.get("in", ""), entry.get("out", "")] + [values.get(k, "") for k in keys[2:]])\nheader = ["ordinal", "producer_id", "caption", "bin_raw", "in_raw", "out_raw", "service", "resource_raw", "proxy_original_raw", "warp_resource_raw", "comment"]\nwith dst.open("x", encoding="utf-8-sig", newline="") as f:\n w = csv.writer(f)\n w.writerow(header)\n w.writerows(rows)\nwith dst.open(encoding="utf-8-sig", newline="") as f:\n if list(csv.reader(f)) != [header] + rows:\n raise ValueError("Readback mismatch; discard partial CSV")\nprint(str(len(rows)) + " saved playlist entries checked; not a timeline or deletion list")\n'"'"')' "project.mlt" "playlist.csv"

十一列都按文字理解

列为 ordinal、producer_id、caption、bin_raw、in_raw、out_raw、service、resource_raw、proxy_original_raw、warp_resource_raw、comment。ordinal 按保存条目顺序从 1 开始。名称、分组及备注来自已存属性,不从文件名推断。空单元格只表示本方法没有记录该值,不证明片段未使用或损坏。

in_raw 和 out_raw 保留解析后属性字符串及前导零;缺失边界留空。不计算时长,不推断隐含边界或校验播放范围。不要将字符串当秒数相减:MLT 值取决于表示方式和项目上下文。XML 转义经解析解码,表格保留解析值,不逐字节复制 XML 写法。

三个资源字段分开:resource_raw 对应 resource,proxy_original_raw 对应 shotcut:resource,warp_resource_raw 对应 warp_resource。timewarp 资源可能带速度前缀,代理属性也可能不同。不展开或转绝对路径、不检查存在性,也不选定正确原文件。不递归遍历嵌套项目、滤镜、遮罩、LUT 或图像序列依赖。

使用前核对报告

命令回读 CSV,将表头及每个字段与解析结果比较,通过才显示成功。条目数与已存主列表对照,再检查同源不同裁剪的两项和已知自定义名称。保留原 MLT 与 CSV 主副本,只在工作副本筛选或加交接备注。署名时另行核实作者及许可,文件名和名称不提供这些信息。

LibreOffice Calc 导入选 UTF-8、逗号和直双引号文字分隔符。十一列全设“文本”,关闭“合并分隔符”“修剪空格”“计算公式”。对话框被隐藏时开启“编辑筛选器设置”,避免把时间文字当日期或备注当公式。我们未运行 Calc 界面。

准确命令执行了 21 项模拟案例:六项有效案例含重复顺序、Unicode 和 XML 转义、速度/代理原字段、旧 ID、缺失边界、空分组及与时间线/滤镜资源分离;十五项无效案例在创建输出前停止。另六次覆盖有效输出被拒绝,输入及原输出字节不变。未测试真实 Shotcut 项目、播放、界面或 Windows/macOS 运行。写入或回读失败时,弃用部分 CSV,换新名重试;不得据此删除媒体。

分别保留资源、代理原文件和变速资源属性的原创示意图
原创假想字符串示意:三种属性分开保留,不能据此判定正确原文件。 Watch at Ease