背景
在通过视频剪辑软件编辑完视频之后,我们通常会思考如何归档素材 。这其实是一件挺头疼的事情,对于普通的视频创作者来说,创作之前并不确切地知道哪些片段会被用利用上。
这种情况下,剪辑的过程,本身就是一个挑选的过程。无论是出于精选高光片段便于日后复用,还是节省存储空间的目的,这个需求都是切实存在的。
基础思路
我们只要获取到时间线上每个片段对应的原素材文件路径、起始位置、终止位置(或持续时间),便可以使用工具(FFmpeg)进行剪切导出。
草稿文件解析
On MacOS
草稿文件名称为 draft_info.json
,位于
bash
/Users/user/Movies/JianyingPro/User Data/Projects/com.lveditor.draft
On Windows
草稿文件名称为 draft_content.json
,位于
sql
C:\Users\user\AppData\Local\JianyingPro\User Data\Projects\com.lveditor.draft\
文件结构
读取文件信息,观察结构可以发现以下关键信息
JSON
{
"materials": {
"videos": [
{
"id": "ED9E7016-7A4D-4251-804F-2EBCAE19BC25",
"path": "##_draftpath_placeholder_[草稿ID]_##/materials/video/C0631.MP4"
},
{
"id": "2F408BAD-5031-4CC8-942D-DDAFD71B2A92",
"path": "/Users/xxx/Desktop/videos/C0631.MP4"
}
]
},
"tracks": [
{
"type": "video",
"segments": [
{
"material_id": "ED9E7016-7A4D-4251-804F-2EBCAE19BC25",
"source_timerange": {
"duration": 833333,
"start": 1350000
}
}
]
}
]
}
其中 materials 字段记录了所有素材的基本信息,比较关键的主要是文件存放位置;而 tracks 字段记录了轨道信息,我们可以从中找到对应的视频片段(segment),从而获取到片段的时间范围信息。
通过 ID 的映射,我们可以获取到:文件地址、开始时间,持续时间,然后就可以开始编写导出逻辑了。
需要注意的是 ##_draftpath_placeholder_xxx_##
字样代表的是草稿文件夹自身的位置,因此在处理时需要做替换。
借助 FFmpeg 导出
FFmpeg 是一个非常强大的跨平台流媒体处理程序,并且是开源的。同时作为命令行工具,它可以轻易地集成到脚本和程序中,作为底层工具支撑上层应用。
我们的项目正是一个基于 FFmpeg 的简单包装,由于运行时需要调用它,因此你需要提前安装 ffmpeg并将命令加入到环境(PATH)中。
Tips: 在 MacOS 中你可以通过 brew install ffmpeg 便捷地完成安装,其他方式详见官网。
完整项目的地址见 Github - emosheeep/capcut-export,运行起来大概是下面这样:
lua
Usage: ccexp [options] <file> [output]
Export video clips from CapCut editor tracks, helps archive materials.
Arguments:
file CapCut/Jianying draft info json file.
output The output directory, default is cwd.
Options:
-V, --version output the version number
-p,--concurrent <number> The number of tasks processed in parallel, the default is number of CPU.
--offset <number> Expand the video clips' time range to both sides for about specific seconds, default is 2s.
--verbose To be verbose. (default: false)
-h, --help display help for command
接下来我们介绍 ffmpeg
命令的基础用法:
Shell
ffmpeg -ss 2 -t 3 -c copy -y -i /path/to/input.mp4 /path/to/output.mp4
在上面的命令中:
-
-ss
代表设置起始位置为 2s 处 -
-t
代表导出片段的持续时间为 3s -
-c copy
指定使用流式复制的方式拷贝原视频。流式复制不会对原视频重新解码和编码,因此它是无损的,也正因没有这个过程,它的速度也快很多。 -
-y
自动同意命令运行过程中需要确认的流程。主要是同意在存在同名文件时执行覆盖操作。
所以这行命令翻译过来就是:导出原视频从 2s 处开始,持续 3s 的片段到指定位置。
为什么觉得导出视频的时间范围不那么精确?
在使用 FFmpeg 进行视频剪辑或者截取的时候,可能会出现时间范围不精准的情况,有两个主要原因:
视频关键帧(Keyframes)
关键帧是能够完全独立于其他帧进行解码的帧,通常每几秒视频就会有一个关键帧 。FFmpeg 使用 -ss
选项跳跃到特定的时间位置,默认情况下,它会跳跃到最近的关键帧。如果你选定的开始时间点并没有关键帧,FFmpeg 就会选择最近的前一个关键帧作为开始点,这样就可能造成精度问题。
而如果你想精确地指定开始时间,则需要将 -ss
参数放到 -i
参数之后。但这种做法同样会面临一些问题:
-
流式复制截取:虽是无损画质,但在视频开始位置可能有会短暂的黑屏问题。原因正是上面提到的关键帧选取问题,你选定的时间点没有关键帧,或对应的帧无法单独解码。
-
不使用流式复制:将会存在解码和重编码问题,耗时较长不说,还可能造成画质的损失。
相比之下,画质的保留更为重要,对于时间点不准确的问题,在上面的工具中,可以通过控制 offset
参数扩大两边的范围来尽可能保留更多的视频内容。
关于归档素材这件事...
最初意识到归档素材 这件事还是在「影视飓风」一期关于素材管理的视频里
其中提到软件「DAVINCI · 达芬奇」具备将轨道上未经编辑的视频片段原样导出 的功能。看完视频的我回想起自己曾经拍摄的一堆长视频素材,是删了觉得可惜,想整理又心有余而力不足。
自那一刻起,我便思索「剪映专业版」何时才能具备这项功能?为此我还特地保留了一些草稿不舍得删除,想等这项功能落地之后,导出存档,然后再清理电脑。直到期待许久没有回应,才无奈亲力亲为。好在倒也是凭借作为程序员的经验和直觉,完成了这件事。想来做的过程还是挺有趣的😅,甚至会联想到突"技术宅拯救世界"。
也许对于单纯记录生活,拍拍 vlog 的普通创作者来说,压根不会想到归档这件事。毕竟不是商业创作,没有必要做的如此认真。但我为什么突然执着于此呢?其实还是源自于发自内心想记录生活这件事。万一年底想剪个年度混剪,总不至于连素材都找不到嘛,对不对?