您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
下载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; } })();