下载nickjr短片的字幕
// ==UserScript==
// @name downloadNickJrVideoSubstitle
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 下载nickjr短片的字幕
// @author You
// @match http://www.nickjr.tv/*/videos/*/
// @grant none
// ==/UserScript==
(async function() {
'use strict';
// Your code here...
// 等待视频开始播放
await new Promise(r => {setTimeout(r, 3000);}); // 点击分页时,等待清理
while( !EdgePlayer.activePlayer ) {
await new Promise(r => {console.log("等待视频开始播放"); setTimeout(r, 1000);});
}
// insert element
console.log("在cc按钮前插入下载按钮");
let ccEl = document.querySelector("div.edge-gui-cc-button");
ccEl.innerHTML= '<span style="width:3em;margin-left:-4em" title="油猴脚本,下载srt字幕">下载cc</span>'
ccEl.lastElementChild.onclick = downloadVtt;
console.log("在footer栏前插入下载按钮");
let newEl = document.createElement("li");
newEl.className="footer-item";
newEl.innerHTML='<div class="footer-text">下载cc</div>';
newEl.onclick = downloadVtt;
let footerEl = document.querySelector("ul.footer-legal-items");
footerEl.insertBefore(newEl, footerEl.firstElementChild);
// 功能
async function downloadVtt(){
let mediaGenUrl = EdgePlayer.activePlayer.configModel.runTimeConfig.usedMediaGenUrl;
let obj = await (await fetch(mediaGenUrl)).json();
// merge and down
// filename from url
// let fn = location.pathname.replace("videos","_").replace(/\//g,"").replace(/\-/g," ")+".srt";
// filename from title
let h1El=document.querySelector("h1.module-about-title")
let fn = h1El.nextElementSibling.querySelector("a").innerText + " " + h1El.innerText;
let preDuration=0;
let preLineCounter=0;
let srtTextList = [];
for( let videoItem of obj.package.video.item ){
// srclang==="en"
let enTranscript = videoItem.transcript.find(aTranscript=>aTranscript.srclang=="en");
if( !enTranscript ){
console.log("未找到“srclang=en”的字幕");
continue;
}
// format==="vtt"
let vttTypographic=enTranscript.typographic.find(a=>a.format==="vtt");
if( !vttTypographic ){
console.log("未找到“format=vtt”的字幕");
continue;
}
// fetch vtt
let vttText = await (await fetch(vttTypographic.src)).text();
// vtt2srt
let srtText = vtt2srt(vttText, '\n', preLineCounter+1, preDuration);
srtTextList.push(srtText);
// 累加时长
preDuration = preDuration + videoItem.rendition[0].duration;
preLineCounter = preLineCounter + (srtText.match(/\-\->/g) || []).length;
}
download(fn+".nickjr.srt", srtTextList.join("\n"));
}
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// base on https://cdn.jsdelivr.net/npm/[email protected]/vtt2srt.js
const vttRemoval = /(WEBVTT\s+)/mg;
const timeMatcher = /^\d*\n(\d{2}:\d{2}:\d{2})\.(\d{3})\s+-->\s+(\d{2}:\d{2}:\d{2})\.(\d{3}).*$/mg
const htmlRemoval = /<\/?\w+>/g;
function vtt2srt(vttString, separator = '\n', lineCounterStartValue=1, deltaTime=0) {
// removes VTT header
let srtString = vttString.replace(vttRemoval, '');
// removes html tag
srtString = srtString.replace(htmlRemoval, '');
let lineCounter = lineCounterStartValue-1;
srtString = srtString.replace(timeMatcher, function (match) {
lineCounter++;
if( deltaTime==0 ){
return lineCounter + separator + match.replace(timeMatcher, '$1,$2 --> $3,$4');
}else{
// todo, change time by add deltaTime
console.log("todo, 未实现字幕合并中的时间调整功能")
return lineCounter + separator + match.replace(timeMatcher, '$1,$2 --> $3,$4');
}
});
return srtString;
}
})();