downloadNickJrVideoSubstitle

下载nickjr短片的字幕

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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;
    }

})();