我们在看 YouTube 视频的时候,经常有下载字幕的需求,一般会使用一些浏览器插件来帮助下载,但是这些插件经常会失效,又要重新去找其他的插件,很浪费时间。做为一个程序员,自己实现一个解析字幕的小程序还是不算难的。
第一步:找到视频对应的字幕
打开控制台,如上图
- 选择 Network
- XHR
- 点击 timedtext 那一条
- 点击右边 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,安装方法这里就不详细说了,网上有很多。
-
引入 fs 模块
var fs = require('fs')
-
处理 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) } }) } } });
-
处理时间的方法
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 }
-
运行脚本
在终端输入node parse_subtitle.js
-
当前目录下就会生成相应的字幕文件
PS:关注公众号 windymiao,回复 『字幕』获取完整源码