您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
显示已过期的集数,尝试提供下载功能
// ==UserScript== // @name Viu More // @namespace http://tampermonkey.net/ // @version 0.4.4.1 // @description 显示已过期的集数,尝试提供下载功能 // @author cw2012 // @match https://viu.tv/encore/* // @icon https://www.viu.com/ott/hk/v1/images/web_loading_icon.gif // @require https://cdn.jsdelivr.net/npm/[email protected] // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_download // @grant GM_setClipboard // @connect viu.tv // @connect api.viu.now.com // @connect now.com // @connect nowe.com // @run-at document-end // ==/UserScript== (function() { 'use strict'; let totalCount, isAsc, seasonTitle, subtitles=[],clips = []; let seasonName; const cookie = 'b13b2e6a06a230f8b2'; // f7da2aac5e3df01adc const msgBox = document.createElement('div'); addStyle(); init(); function init(){ const btn = document.createElement('div'); btn.innerText = '解 析'; btn.className = 'floating-btn'; btn.addEventListener('click', ev=>{ getSeasonEposideList(); }); setTimeout(()=>{ msgBox.id = 'msg-box'; document.querySelector('#js-nav-header').append(msgBox); document.querySelector('.min-h-\\[52px\\].flex.gap-x-4.px-4').append(btn); }, 3000); } function getSeasonEposideList(){ seasonName = location.href.split('/')[4]; subtitles=[]; if(typeof document.querySelector('.min-h-\\[52px\\].flex.gap-x-4.px-4') == "undefined"){ showMsg('请在页面加载完成后重试',0); return; } GM_xmlhttpRequest({ method:'GET', url: `https://api.viu.tv/production/programmes/${seasonName}`, responseType: 'json', onerror:e=>{showMsg(`请求发生错误:${e}`,0)}, onload:res=>{ res = res.response.programme; totalCount = res.programmeMeta.totalEpisodeNo; seasonTitle = res.programmeMeta.seriesTitle; // 预告片 if(res.clips.length > 0 && res.episodes.length === 0){ for(let item of res.clips){ clips.push({ productId: item.productId, episodeNum:seasonTitle, episodeNameU3: '预告片', productSubtitle: '' }); } updateUiEpisodeList(clips); } else if(totalCount !== res.episodes.length){ // 只显示一集,说明是最后一集 // 这里一定是总集数和显示集数不一致才会被调用的 if(res.episodes.length > 1){ isAsc = res.episodes[0].episodeNum < res.episodes[1].episodeNum; }else{ isAsc = false; } setTimeout(()=>{ updateUiEpisodeList(res.episodes); showOutdatedEpisodeList(res.episodes);} , 1000); }else{ setTimeout(()=>updateUiEpisodeList(res.episodes), 2000); } } }); } function updateUiEpisodeList(list){ // 先操作已显示的列表 const listBox = document.querySelector('.overflow-y-scroll.h-full'); const shownEpisode = listBox.querySelectorAll('.items-center>.w-full'); shownEpisode.forEach((item, index)=>{ let div = document.createElement('div'); div.className = 'floating-div'; div.innerText = '复制MPD'; div.addEventListener('click', ev=>{ window.event? window.event.cancelBubble = true : ev.stopPropagation(); const productId = list[index].productId; if(list[index].onAirStartDate >= 1705852800000) getSubtitleWithProductId(productId, list[index].episodeNum + ' ' + list[index].episodeNameU3, null); else getSubtitleWithProductId(productId, list[index].episodeNum + ' ' + list[index].episodeNameU3, list[index].productSubtitle); }); item.append(div); }); setTimeout(()=>{ const li = document.createElement('span'); li.innerText = `共${totalCount}集`; li.className = 'react-tabs__tab-list'; document.querySelector('.min-h-\\[52px\\].flex.gap-x-4.px-4').append(li); },500); } function showOutdatedEpisodeList(list){ const listBox = document.querySelector('.overflow-y-scroll.h-full'); // 添加因过期而未能显示的列表 let len2add, firstProductId,firstEpisodeNum; // 正片 if(isAsc){ len2add = list[0].episodeNum>15?15:(list[0].episodeNum-1); firstProductId = parseInt(list[0].productId); firstEpisodeNum = list[0].episodeNum; let prevDiv; for(let i=0;i<len2add;i++){ const div = createOutdateEpisode(firstProductId-(i+1), firstEpisodeNum - (i+1), list[0].productSubtitle); if(i==0){ listBox.insertBefore(div, listBox.firstChild); prevDiv = div; }else{ listBox.insertBefore(div, prevDiv); prevDiv = div; } } }else{ if(list.length === 0) { return; } len2add = list[list.length-1].episodeNum>15?15:(list[list.length -1].episodeNum-1); firstProductId = parseInt(list[list.length-1].productId); firstEpisodeNum = list[list.length-1].episodeNum; for(let i=0;i<len2add;i++){ let div = createOutdateEpisode(firstProductId-(i+1), firstEpisodeNum - (i+1), list[0].productSubtitle); listBox.append(div); } } } function createOutdateEpisode(id, num, subtitleList){ let div = document.createElement('div'); div.className = 'VideoItem outdated_episode'; // div.innerText =`下载第${sn(num,2)}集字幕并复制MPD文件的url`; div.addEventListener('click',ev=>{ ev.stopPropagation(); getSubtitleWithProductId(id, num, subtitleList); }); return div; } function getSubtitleWithProductId(id, episodeNum, subtitleList){ GM_xmlhttpRequest({ method:'POST', url: 'https://api.viu.now.com/p8/3/getVodURL', headers: { 'accept':'*/*', 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36'}, data: JSON.stringify({"callerReferenceNo":getTimeStamp(new Date()),"productId":id,"contentId":id, "contentType":"Vod","mode":"prod","deviceType":"ANDROID_WEB"}), onerror:e=>{ showMsg('获取字幕时出错:'+e,0) }, onload:res=>{ res = JSON.parse(res.responseText); switch(res.responseCode){ case "MISSING_INPUT": showMsg('输入的参数不对',0); break; case "GEO_CHECK_FAIL": showMsg('IP不是香港的',0); break; case "INTERNAL_ERROR": showMsg("发生错误,该视频可能已经永久下架了",0); break; case "SUCCESS": var videoUrl = res.asset[0]; var m3u8Index = videoUrl.indexOf('.m3u8'); GM_setClipboard(`N_m3u8DL-RE.exe -mt --use-shaka-packager --tmp-dir "Downloads" --mux-after-done "format=mp4" --save-name "${episodeNum}" "${videoUrl}"`); showMsg(`${m3u8Index > -1?'m3u8':'MPD'}文件的url已复制成功`,1); if(subtitleList){ subtitleList = subtitleList.split(','); subtitles=[]; subtitleList.forEach(item=>{ if(item == 'Chinese'){ subtitles.push('TRD'); }else if(item == 'English'){ subtitles.push('GBR'); } }); downloadSubtitles(id,episodeNum, videoUrl, m3u8Index); } break; } }, ontimeout:e=>showMsg('呵呵,超时了',0) }); } function getTimeStamp(date){ const timeZone = date.getTimezoneOffset() / 60; date.setTime(date.getTime() - timeZone * 3600 * 1000); return date.toISOString().replaceAll(/[-T:Z.]/g,'').substr(0,14); } const langName = {TRD:"zh", GBR:"en"}; function downloadSubtitles(id,episodeNum, videoUrl, m3u8Index){ GM_xmlhttpRequest({ method:'GET', url:videoUrl, onload:()=>{ subtitles.forEach(item=>{ const url = m3u8Index > -1? videoUrl.substr(0,m3u8Index) + `-${item}.srt`:`https://static.viu.tv/subtitle/${id}/${id}-${item}.srt`; GM_download({ url: url, headers:{origin:'https://viu.tv',referer:'https://viu.tv/'}, name:`${sn(episodeNum,2)}.${langName[item]}.srt`, onerror:e=>showMsg(`${sn(episodeNum,2)}.${langName[item]}.srt 下载失败\n${url}`,0) }) }); } }); } function showMsg(msg,type){ msgBox.innerText = msg; msgBox.className=type?'showing':'err'; setTimeout(()=>{msgBox.className='';},type==0?4000: 2500); console.log(msg); } function sn(num,length){ return num.toString().padStart(length, '0'); } function addStyle(){ GM_addStyle(` .floating-btn{ position:fixed; background: #0a7deb; text-align: center; color:white; font-size:1.5em; cursor: pointer; border-radius:10px; border:solid #0a7deb 1px; padding:6px; top:50%; right:20px; box-shadow:#0a7deb 2px 2px 6px, #0a7deb 6px 6px 19px; } .floating-div{ position:relative; background: #0a7deb; text-align: center; color:white; cursor: pointer; border-radius:5px; border:solid #0a7deb 1px; padding:1px; } .VideoItem.undefined:hover .floating-div{ display:block; } #msg-box{ transition:all 0.5s ease-in-out; font-size:15px; position:fixed; right:30px; top:10px; background: #0a7deb; color:white; border-radius:7px; padding:10px; opacity:0; box-shadow:#0a7deb 2px 2px 6px, #0a7deb 6px 6px 19px; } #msg-box.showing{ opacity:1; top:130px; } #msg-box.err{ background:red; box-shadow:red 2px 2px 6px, red 6px 6px 19px; opacity:1; top:130px; } .VideoItem.outdated_episode{ text-align: center; background:#0a7deb; border-radius:10px; border:solid #0a7deb 1px ; padding:6px; margin:10px; color:white; cursor: pointer; } `); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址