美文网首页
json2srt:剪映字幕 json 转 srt

json2srt:剪映字幕 json 转 srt

作者: 佛分_知合 | 来源:发表于2021-05-26 10:42 被阅读0次

    这是一个命令行 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;
    }
    
    

    相关文章

      网友评论

          本文标题:json2srt:剪映字幕 json 转 srt

          本文链接:https://www.haomeiwen.com/subject/kfqksltx.html