这是一个命令行 js 程序,需要安装 node
Windows 平台:剪映 1.2.1 测试通过
macOS:剪映 1.3.1 测试通过
用法
0. 首先,当然是要下载本库的 json2srt.js 这个程序。
1. 第一步,在「剪映 Pro」软件中,自动生成字幕
2. 第二步,进入命令行。
此工具需要带一个参数,即 json 文件所处的目录名称。
Windows 上,剪映字幕的工作目录是:USER_HOME + '\AppData\Local\JianyingPro\User Data\Projects\com.lveditor.draft';
macOS 上,剪映字幕的工作目录是:USER_HOME + '/Movies/JianyingPro/User Data/Projects/com.lveditor.draft/'
在命令行上,执行:
node json2srt.js <json 文件所在的目录名>
如果不知道「json 文件所在的目录名」,可以不带参数执行:
node json2srt.js
命令会提示你到哪个目录下去找。
生成的 srt 文件在那里?
生成的 srt 文件,和 json 文件在同一个目录。
命令执行成功时,会把生成的 srt 文件路径打印在屏幕上。
- Windows 平台生产的文件是 draft.srt
- macOS 平台生产的文件是 template.srt
json2srt.js 源码:
// 这个命令行工具,是根据 https://pansong291.gitee.io/web/html/tool/JianyingPro.html 修改而来
// 感谢原作者!
// 修改者:知合
// 2021-05-26
// 南无阿弥陀佛🙏🏻
const os = require('os');
const fs = require('fs')
// 获取 home 目录
const USER_HOME = process.env.HOME || process.env.USERPROFILE
const RN = '\r';
// 当前字幕文件的目录(从命令行读取)
jsonFolder = process.argv.slice(2);
// 剪映的工作目录(macOS)
if (os.platform() == 'darwin') { //macOS 的路径
jianyingPath = USER_HOME + '/Movies/JianyingPro/User Data/Projects/com.lveditor.draft/';
// 剪映生成的字幕 json 文件
jsonFile = jianyingPath + jsonFolder + '/draft_info.json';
// 程序将生成的 srt 文件
srtFile = jianyingPath + jsonFolder + '/draft_info.srt';
// 换行符
let RN = '\r';
} else { // Windows 的路径
jianyingPath = USER_HOME + '\\AppData\\Local\\JianyingPro\\User Data\\Projects\\com.lveditor.draft\\';
// 剪映生成的字幕 json 文件
jsonFile = jianyingPath + jsonFolder + '/draft.json';
// 程序将生成的 srt 文件
srtFile = jianyingPath + jsonFolder + '/draft.srt';
// 换行符
let RN = '\r\n';
}
try {
if (jsonFolder.length == 0) {
console.log('请提供 json 目录。\n');
console.log('请到 ' + jianyingPath + ' 目录下找。\n\n');
console.log('如果目录名为 AFA473B4-BB11-4D6D-98AC-4A0E039A13D6,则请执行:');
console.log('node json2srt.js AFA473B4-BB11-4D6D-98AC-4A0E039A13D6\n');
return;
}
// 读取 json 文件
let inputText= fs.readFileSync(jsonFile);
let temp;
// 剪映 json 对象
temp = JSON.parse(inputText);
let srtFiles = convertJSON2SRT(temp);
console.log('生成完毕:'+ srtFile);
} catch (e) {
console.log('JSON 解析错误:'+e);
}
function convertJSON2SRT(jy) {
// 平台系统
let os = jy.platform.os;
// 提取文本材料
// Map 结构 = {id1: text1, id2: text2, ...}
let texts = {}, temp = jy.materials.texts;
for (let i in temp) {
texts[temp[i].id] = temp[i].content;
}
// 轨道列表
let tracks = jy.tracks, track;
// SRT 文件 Map
let srtFiles = {};
for (let i in tracks) {
track = tracks[i];
temp = convertTrack2Srt(track, texts, os);
if (temp) {
srtFiles[track.id] = temp;
}
}
return srtFiles;
}
/**
* 将一条轨道转换为 srt 文本
* @param track 轨道
* @param texts 文本材料
* @param milli 是否是毫秒单位
* @return {string}
*/
function convertTrack2Srt(track, texts, milli) {
let segments = track.segments, segment;
let srt = {content: null, start: null, end: null};
let srtText = '', index = 0;
for (let i in segments) {
segment = segments[i];
srt.content = texts[segment.material_id];
if (!srt.content) continue;
srt.start = segment.target_timerange.start;
srt.end = srt.start + segment.target_timerange.duration;
srt.start = getSrtTimeText(srt.start, milli);
srt.end = getSrtTimeText(srt.end, milli);
index++;
srtText += formatSrt(index, srt);
}
fs.writeFile(srtFile, srtText, function (err) {
if (err) {
return console.error(err);
}
});
}
/**
* 获取 SRT 格式的时间文本
* @param time 时间,windows版本为微秒数
* @param milli 是否是毫秒单位
* @returns {string}
*/
function getSrtTimeText(time, milli) {
// 1h1m1s111ms = 61m1s111ms = 3661s111ms = 3661111ms
if (!milli) {
time = Math.floor(time / 1000);
}
// 余出的毫秒
let millisecond = time % 1000;
time = Math.floor(time / 1000);
// 余出秒
let second = time % 60;
time = Math.floor(time / 60);
// 余出分钟
let minute = time % 60;
time = Math.floor(time / 60);
// 剩余时数
let hour = time;
hour = formatDigit(hour, 2);
minute = formatDigit(minute, 2);
second = formatDigit(second, 2);
millisecond = formatDigit(millisecond, 3);
return hour + ':' + minute + ':' + second + ',' + millisecond;
}
/**
* 格式化为 SRT
* @param index 字幕序号,从 1 开始
* @param srt 字幕内容等信息
* @returns {string}
*/
function formatSrt(index, srt) {
return index + RN + srt.start + ' --> ' + srt.end + RN + srt.content + RN + RN;
}
/**
* 格式化数字
* @param digit 数字
* @param length 长度
* @returns {string}
*/
function formatDigit(digit, length) {
let str = digit.toString();
while (str.length < length) {
str = '0' + str;
}
return str;
}
网友评论