ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Lossless Cut 3.66.1 版本深度解析:Markers 时间线书签、多音轨同放与 .llc v2 项目格式

Lossless Cut 3.66.1 版本深度解析:Markers 时间线书签、多音轨同放与 .llc v2 项目格式 Lossless Cut 3.66.1 版本深度解析Markers 时间线书签、多音轨同放与 .llc v2 项目格式【免费下载链接】lossless-cutThe swiss army knife of lossless video/audio editing项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut本文基于开源仓库 lossless-cut 的官方版本发布说明versions/3.66.1.md展开结合仓库源码逐项拆解 3.66.1 引入的核心机制变化分段Segment语义重构出的 Marker 书签体系、基于 FFmpeg 的多音轨同时播放、.llc项目文件 v2 格式与 selected 状态持久化、按字节大小分割时间线、JavaScript 表达式批量编辑分段以及文件名模板变量的语义调整。读完本文你将掌握 3.66.1 每个新特性的操作入口、配置方式和底层实现依据能够平滑迁移旧项目并充分利用新的工作流。一、版本概览一次底层依赖与语义的双重升级3.66.1 是 lossless-cut 在基础运行环境与内部数据模型上同时迈出大步的版本发布说明中的改动可归纳为四类运行环境升级Electron 升级到 38代价是放弃对 macOS 11 的支持FFmpeg 升级到 8.0数据模型重构分段语义重新定义——缺失end时间的分段不再延伸到时间线末尾而是成为独立概念Marker.llc项目文件版本号随之提升到 v2播放能力增强支持同时播放多条音轨借助 FFmpeg 辅助播放并大幅改善非原生支持编码格式的辅助播放性能效率工具扩充按字节大小切分时间线、表达式批量修改分段、按表达式切换轨道、CSV 标签导入导出、8 个新键盘动作与 4 个新快捷键、6 个新文件名模板变量。下文按主题逐一深入。二、Marker无结束时间的分段成为时间线书签2.1 语义变化从延伸到末尾到书签在 3.66.1 之前一个没有end时间的分段会被理解为从start一直延伸到时间线末尾。3.66.1 彻底改变了这一语义所有分段现在都强制拥有start时间缺失end时间的分段被定义为 Marker标记。从数据模型看src/renderer/src/types.ts 中.llc项目文件的 v1/v2 Schema 清晰体现了这一变化v1 中start为可选字段start: z.number().optional()v2 中start变为必填字段start: z.number()end仍可选——end缺失即 Marker。2.2 Marker 的渲染与导出规则Marker 在界面上以不同样式渲染时间线上仅呈现为一个点并被排除在导出之外。相关实现分散在多个文件中src/renderer/src/segments.ts 中的filterNonMarkers函数直接按end ! null过滤掉所有 Markersrc/renderer/src/hooks/useSegments.tsx 中segmentsOrInverse计算导出分段时先经filterNonMarkers剔除 Marker再剔除initial初始分段时间线上的操作也按 Marker 特判src/renderer/src/Timeline.tsx 中当当前分段的end null时拖拽动作被识别为移动 Marker而非调整起点界面提示文案位于 src/renderer/src/SegmentList.tsxMarkers are segments without an end time and will not be exported. Convert markers to segments by setting their end time.Marker 是没有结束时间的分段不会被导出通过设置结束时间可将 Marker 转为普通分段。2.3 批量导出 Marker 为截图Marker 的典型用途是在时间线上做书签且所有 Marker 可以被批量导出为截图。该逻辑在 src/renderer/src/App.tsx 有明确注释If all segments are markers, we shall export every marker as a file and therefore we dont have to ask user——当全部分段都是 Marker 时程序直接把每个 Marker 对应时间点导出为一张图片文件无需再逐一询问。配合Select all markers全选所有 Marker操作见 src/renderer/src/components/KeyboardShortcuts.tsx 与 src/renderer/src/SegmentList.tsx用户可以一键框选全部书签并批量生成关键帧截图。2.4 用表达式在分段与Marker之间互转由于 Marker 本质上就是end缺失的分段表达式编辑成为最直接的互转手段。src/renderer/src/hooks/useSegments.tsx 内置了这两个现成示例将分段转为 Marker{ end: undefined }将 Marker 转为分段{ ...(segment.end null { end: segment.start 5 }) }给每个 Marker 追加 5 秒时长三、多音轨同时播放FFmpeg 辅助的 amix 混音3.66.1 允许在播放时同时聆听多条音轨这对于多语言配音、多声轨素材的快速审看非常实用。其底层依赖 FFmpeg 辅助播放管线对浏览器原生支持的格式可直接使用 HTML5 播放对非原生支持或需要混音的素材则由 src/main/ffmpeg.ts 的createMediaSourceProcess启动 FFmpeg 子进程生成媒体源。该函数的混音逻辑值得关注当audioStreams.length 1时会对每条音轨先做aresample44100重采样再用amix滤镜按等权重合并[resampled0][resampled1]... amixinputsN:durationlongest:weights1 1 ...:normalize0:dropout_transition2[audio]其中durationlongest保证混合结果覆盖最长音轨normalize0关闭自动归一化以避免音量被压低。值得注意的是3.66.1 同时声明大幅改善了非原生支持编码/格式下 FFmpeg 辅助播放的性能——这直接提升了多音轨混音场景在非常见编码上的可用性。四、.llc项目文件升级到 v2selected 状态持久化4.1 v2 结构变化.llc是 lossless-cut 的项目文件格式JSON5 序列化。3.66.1 将其版本号从 1 提升到 2对应 src/renderer/src/types.ts 中的llcProjectV2Schema核心变化有两点每个分段新增selected: z.boolean().optional()字段分段的选中/取消选中状态随项目文件保存重新打开项目后无需重新框选start变为必填字段见上文 Marker 语义变化。分段的保存序列化在 src/renderer/src/segments.ts 的mapSaveableSegments中完成仅保留start, end, name, tags, selected五个字段。4.2 v1 → v2 自动迁移旧项目文件v1在加载时会被自动迁移迁移逻辑位于 src/renderer/src/edlStore.ts先用llcProjectV2Schema解析若因版本不匹配抛出 Zod 错误则回退用llcProjectV1Schema解析并将每个分段的start缺失值补为0同时把version提升为2。也就是说旧版.llc 项目中那些没有start的分段在 v2 下会被赋予起点 0 并变为 Marker 语义——这是升级后需要重点复核的行为变化。五、按字节大小分割时间线3.66.1 新增了以目标文件大小字节为基准切分时间线的能力实现位于 src/renderer/src/hooks/useSegments.tsx 的createFixedByteSizedSegments从主文件元数据获取文件总大小fileSizegetFileSize(mainFileMeta.format)弹出对话框结合fileDuration与fileSize让用户输入目标字节数将目标字节数按字节比例 时长比例换算为分段时长调用makeDurationSegments(segmentDuration, fileDuration)生成均匀分段。换算依据的是恒定码率的近似假设。与之配套的是getSegEstimatedSize函数同文件第 738-744 行Math.round((segDuration / fileDuration) * fileSize)用于在分段列表中实时估算每个分段的输出体积方便按大小规划切分结果。六、用 JavaScript 表达式批量修改分段3.66.1 将表达式能力从创建分段扩展到了修改已有分段对每个选中的分段求值一段 JavaScript 表达式返回的字段会覆盖到分段上。入口是mutateSegmentsByExprUI 为 src/renderer/src/components/ExpressionDialog.tsx 承载的ExpressionDialog。表达式上下文中可用的变量见 src/renderer/src/hooks/useSegments.tsxsegment.index分段在列表中的序号segment.label分段名称segment.start/segment.end起止时间秒segment.tags.*分段标签除上文提到的 Marker 互转外官方内置示例还包括分段整体扩展 5 秒{ start: segment.start - 5, end: segment.end 5 }以起点为中心重排分段{ start: segment.start - 5, end: segment.start 5 }给标签追加序号后缀{ label: ${segment.label} ${segment.index 1} }给偶数序号分段打标签{ tags: (segment.index 1) % 2 0 ? { ...segment.tags, even: true } : segment.tags }表达式求值在沙箱化 Worker 中执行src/renderer/src/worker/eval.ts、src/renderer/src/worker/evalWorker.ts。完整的表达式语法说明可参考仓库文档 docs/expressions.md。七、按表达式切换轨道Toggle tracks by expression配合多音轨播放按表达式切换轨道让用户可以用与分段表达式相同的语法按条件开启/关闭要拷贝或播放的轨道。相关状态管理集中在useStreamsMetasrc/renderer/src/hooks/useStreamsMeta.tsx它暴露了toggleStripVideo/toggleStripAudio/toggleStripSubtitle/toggleStripThumbnail单独切换某类轨道toggleStripAll全保留或全丢弃changeEnabledStreamsFilter/applyEnabledStreamsFilter/enabledStreamsFilter按表达式过滤轨道这组能力在 src/renderer/src/App.tsx 中与exportExtraStreams、copyStreamIdsByFile等一并注入可以直接驱动导出时的轨道取舍。八、CSV 导入/导出支持标签列此前 CSV 的Start,End,Name三列仅能表达时间与名称3.66.1 让额外列自动映射为分段标签。从 src/renderer/src/edlFormats.test.ts 的测试用例可见形如Start,End,Name,group,Name的表头中Start、End、Name之后的列会被解析为标签键值对parseCsv同时兼容无表头时的默认列语义。导入/导出的实际读写逻辑位于 src/renderer/src/edlStore.tssaveCsv/saveCsvHuman等。标签在分段中是可选键值对象tags在 src/renderer/src/segments.ts 中统一强转为字符串类型。九、新增键盘动作与快捷键3.66.1 一次性加入了 8 个新的键盘动作均可在快捷键设置中绑定默认定义见 src/renderer/src/components/KeyboardShortcuts.tsx动作名作用源码依据toggleDarkMode切换深色模式src/renderer/src/TopMenu.tsx 中亦有按钮入口toggleStripCurrentFilter用当前过滤器切换轨道保留/丢弃useStreamsMetatoggleStripAll保留或丢弃全部轨道同上toggleStripSubtitle保留或丢弃字幕轨同上toggleStripVideo保留或丢弃视频轨同上selectSegmentsAtCursor选中光标位置的所有分段src/renderer/src/hooks/useSegments.tsxmakeCursorTimeZero把时间线零点偏移设为当前光标时间等效于允许负时间偏移src/renderer/src/App.tsxsetStartTimeOffset(-commandedTimeRef.current)同时新增 4 个默认快捷键用于跳转并定位到分段ShiftAlt↑跳转到上一个分段ShiftAlt↓跳转到下一个分段ShiftAltPageUp跳转到第一个分段ShiftAltPageDown跳转到最后一个分段十、文件名模板新变量与SEG_NUM语义修正10.1 新增 6 个模板变量模板插值发生在 src/renderer/src/util/outputNameTemplate.ts 的interpolateOutFileName其构造的上下文对象即变量全集。3.66.1 新增CUT_DURATION分段时长时间码字符串CUT_FROM_NUM/CUT_TO_NUM起止时间的数值秒不带格式化的裸数字FILE_EXPORT_COUNT本次导出当前文件累计产出的文件序号从 1 开始EXPORT_COUNT全局导出累计序号SEG_LABEL分段标签在 cutmerge 合并导出模式下可用例如默认剪裁模板${FILENAME}-${CUT_FROM}-${CUT_TO}${SEG_SUFFIX}${EXT}现在可以改写成${FILENAME}-${CUT_FROM_NUM}-${CUT_TO_NUM}s${EXT}来生成纯秒数命名的输出。完整的模板语法说明见 docs/file-name-template.md。10.2SEG_NUM语义修正破坏性变更SEG_NUM与SEG_NUM_INT的含义在 3.66.1 被修正为分段在分段列表中的原始序号即界面上显示的数字源码中对应segment.originalIndex 1见 src/renderer/src/util/outputNameTemplate.ts而此前它们表示该分段在被选中的分段序列中的序号i 1。为保留旧行为新引入SELECTED_SEG_NUM/SELECTED_SEG_NUM_INT两个变量。这意味着若你的模板此前依赖SEG_NUM保证输出文件序号连续升级后输出序号可能跳号只导出被选中的分段时想要旧行为请改用SELECTED_SEG_NUM补零版与SELECTED_SEG_NUM_INT整数版。同理SEG_SUFFIX默认分段后缀-segNN也基于新的segNumPadded计算同样受该语义变化影响。十一、其他改进与升级注意点UI 性能优化界面渲染性能提升最大分段数上限提高到 1000此前更低。这对需要精细逐帧标记的素材意义重大。Electron 38 / FFmpeg 8.0底层升级带来安全性与编解码能力提升但Electron 38 已放弃 macOS 11Big Sur支持旧系统用户应停留在 3.66.1 之前的版本。FFmpeg 辅助播放性能对非原生支持的编码/容器辅助播放的启动与解码性能大幅改善配合多音轨混音使用体验更好。Marker 迁移复核加载旧.llc项目时缺失start的分段会被补零并改变语义Marker建议升级后逐一检查时间线首端的分段。结语3.66.1 表面上是一个功能增量版本实质上是 lossless-cut 数据模型的转折点Marker 概念的确立把时间线标注从分段体系中独立出来.llcv2 让选中状态与项目文件一同持久化而多音轨播放、按字节分割、表达式批处理与模板变量的扩充则共同把无损剪辑推向更精细、更自动化的批处理工作流。理解这些底层语义变化是在升级后正确迁移项目、避免输出命名与导出行为偏差的关键。【免费下载链接】lossless-cutThe swiss army knife of lossless video/audio editing项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进