downloadNickJrVideoSubstitle

下载nickjr短片的字幕

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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;
    }

})();