解析 youtube 字幕

我们在看 YouTube 视频的时候,经常有下载字幕的需求,一般会使用一些浏览器插件来帮助下载,但是这些插件经常会失效,又要重新去找其他的插件,很浪费时间。做为一个程序员,自己实现一个解析字幕的小程序还是不算难的。

第一步:找到视频对应的字幕

在这里插入图片描述

打开控制台,如上图

  1. 选择 Network
  2. XHR
  3. 点击 timedtext 那一条
  4. 点击右边 Response

这样就可以找到字幕文件了,把字幕复制到一个文件中,例如,subtitle.json

第二步:解析 json

格式分析

json 的格式是这样的

在这里插入图片描述

我们需要的就是里面的 events 对象,events 是一个数组对象,每一条对应一条字幕,包含字幕开始时间,时长及内容。
熟悉字幕的同学都知道字幕的格式

  • 1 序号
  • 00:00:10,120 --> 00:00:13,840 时间
  • All of us, from a very early age 字幕内容
  • 空行

接下需要处理的就是把 json 中的 events 转换成字幕格式,然后输出到一个文件中,例如,subtitle.srt。

处理思路:

  • 字幕中的序号对应 events 数组的 index
  • 开始时间对应 tStartMs 的值
  • 结束时间对应 tStartMs + dDurationMs 的值
  • 内容对应 segs 中的第一个元素

具体实现

我这里用的是 node.js 来处理文件,所以需要安装 node.js,安装方法这里就不详细说了,网上有很多。

  1. 引入 fs 模块

    var fs = require('fs')
    
  2. 处理 json

    fs.readFile(sourcePath, 'utf8', function (err, data) {
         if (err) console.log(err);
         var test1 = JSON.parse(data);//读取的值
         // console.log(test1.events)
         subtitle = test1.events
     
         // 下面写入文件使用的是追加,所以在写之前如果文件已经存在的话就清空一下
         // 避免执行多次后文件内的重复内容太多,关键是在调试的时候可能会忘记,然后就可能懵了
         if (fs.existsSync(resultPath)) {
             fs.writeFileSync(resultPath,'')
           }
         for (let i = 0; i < subtitle.length; i++) {
             const s = subtitle[i];
             // console.log(s.segs[0].utf8) //字幕内容
             // i :字幕的位置
             // console.log(s.tStartMs) 起始时间
             // console.log(s.tStartMs + s.dDurationMs) 结束时间
     
             // 字幕格式
             // 1
             // 00:00:09,779 --> 00:00:15,899
             // 内容
             // 空行
     
             // 这个是生成标准的字幕文件
             if(isTime){
                 fs.appendFileSync(resultPath,i + '\n' + convertTime(s.tStartMs) + ' --> ' + convertTime(s.tStartMs + s.dDurationMs)
                 + '\n' + s.segs[0].utf8 + '\n\n',err => {
                     if(err){
                         console.log(err)
                     }
                 }) 
             }else{ // 这个是生成纯文本内容,不带时间轴和序号
                 fs.appendFileSync(resultPath,s.segs[0].utf8 + '\n\n',err => {
                     if(err){
                         console.log(err)
                     }
                 }) 
             }
                
         }
     });
    
  3. 处理时间的方法

    function convertTime(time) {
        var s, m, h
        h = Math.floor(time / 1000 / 60 / 60)
        console.log('h:' + h)
        m = Math.floor(((time / 1000 / 60 / 60) % 1) * 60)
        // console.log('m:' + m)
    
    
        s = ((((time / 1000 / 60 / 60) % 1) * 60) % 1) * 60// 通过与 1 取余获取小数部分
        s = s.toFixed(3)
        s = s.toString().replace('.', ',').substring(0, 6)
        console.log('s:' + s)
        if (h < 10) {
            h = '0' + h
        }
        if (m < 10) {
            m = '0' + m
        }
        var timeString = h + ':' + m + ':' + s
        // console.log(timeString)
        return timeString
    }
    
  4. 运行脚本
    在终端输入

    node parse_subtitle.js
    
  5. 当前目录下就会生成相应的字幕文件

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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值