解析 youtube 字幕2

上一篇讲了如何解析 YouTube 字幕,那个字幕对应的是 youtuber 自己设置好的字幕文件,字幕是标准的。

在 youtube 上还有另外一种字幕是平台自动生成的。这种字幕文件不是以句子为单位,而是以单词为单位的。那么上一篇中的解析方法就不适用了。为此我又写了一个把不规范的字幕文件转为规范的字幕文件,然后再用上一篇的方法进行解析,最终生成标准的字幕文件。

先来看一下自动生成的字幕是什么样的子的。

在这里插入图片描述

可以看到每一个单词都是分开的,我们要的是一个完整的句子,就像下面的图。

在这里插入图片描述

直接看代码吧,注释都写了。主要的处理就是用循环的方法把每一个单词拼接成一句话,然后添加到对应的数组中。其中还有一点是字幕显示的时间,自动生成的字幕是两行两行显示的,所以如果直接按照 json 中的时间显示的话,会同时显示两行字幕,看起来很乱,我是忍受不了这样的显示方式,所以我时间又处理了一下,变成一行显示。

function convertJson(resourcePath, outPath) {
    pReadFile(resourcePath)
        .then(function (data) {
            // console.log('data'+ data);
            var data = JSON.parse(data);
            var sub = data.events;
            console.log(sub.length);
            var length = sub.length;

            for (let i = 0; i < length; i++) {
                if (sub[i].segs) {
                    var utf8 = '';
                    // console.log(sub[i].segs.length);
                    for (let j = 0; j < sub[i].segs.length; j++) {
                        utf8 += sub[i].segs[j].utf8;
                    }
                    sub[i].segs = [{ "utf8": utf8 }];


                }


            }

            /**
             * arr.splice(index,len,item)
             * splice 方法在删除或替换数组里的元素后会改变原来数组的值
             * 如果用正常的正序循环删除的话,会由于数组元素的下标发生变化而出错
             * 所以可以用倒序的方法来实现循环删除
             * 
             * 用 while 来循环更简单
             */
            while (length--) {
                if (sub[length].segs) {
                    if (sub[length].segs[0].utf8 == '\n') {
                        sub.splice(length, 1);
                    }
                }

            }

            // 去掉第一项,第一项不是字幕
            sub.shift();

            // 自动生成的字幕是以两行的形式显示的,有点乱,所以把它改成一行显示
            // 两行显示的原因是字幕持续时间是两行的时间,改为一行的时间就可以了
            for (let i = 0; i < sub.length; i++) {
                if (i < sub.length - 1) {
                    sub[i].dDurationMs = sub[i + 1].tStartMs - sub[i].tStartMs;
                }
            }

            data.events = sub;
            if (fs.existsSync('../subtitle/subtitle.json')) {
                fs.writeFileSync('../subtitle/subtitle.json', '');
            }

            fs.writeFileSync('../subtitle/subtitle.json', JSON.stringify(data));

        }, function (err) {

        });
}

另外在代码中使用了 promise 。封装了一个读取文件的 promise 方法,这个方法是从别的项目里拿过来的。这里当然也可以不用,直接就用传统的方法读取也没有关系。

function pReadFile(filePath) {
    return new Promise(function (resolved, rejected) {
        fs.readFile(filePath, 'utf8', function (err, data) {
            if (err) {
                rejected(err)
            } else {
                resolved(data)
            }
        })
    })
}

把不规则的 json 文件处理成规则的之后,再用上一篇的方法,进行解析就可以了。

PS:关注公众号 windymiao,回复『字幕2』获取完整源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值