您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
1.自动播放下一集 2.收藏功能 3.历史观看记录 4.去广告
当前为
// ==UserScript== // @name ddrk低端影视助手 // @namespace king // @version 0.4.1 // @description 1.自动播放下一集 2.收藏功能 3.历史观看记录 4.去广告 // @author hero-king // @match https://ddrk.me/* // @icon https://ddrk.me/favicon-32x32.png // @run-at document-start // @grant unsafeWindow // @grant GM_listValues // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @grant GM_registerMenuCommand // @require http://code.jquery.com/jquery-2.1.1.min.js // ==/UserScript== (async function () { "use strict"; /** 广告隐藏class */ const adClass = `<style> .cfa_popup { height: 0 !important; } #iaujwnefhw,#kasjbgih { height: 0 !important; overflow: hidden !important; } <style>`; $("head").append(adClass); /** 页面class */ const mainCss = `<style> .ddrk-tools__modal { position: absolute; left: 0; top: 0; right: 0; bottom: 0; text-align: right; } .btn_col-default { position: absolute; top:0; font-size:22px; color: #2EBF8B; padding:6px; background-color: rgba(0,0,0,0.4); box-shadow: 0px 0px 5px rgba(0,0,0,0.4); line-height: 1.2; user-select:none; } .col_list { position: fixed; top: 35px; right: 0; width: 0; height: auto; min-height: 54px; box-sizing: border-box; background: #000; box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.2); z-index: 999; transition: width .6s; } .col_list:hover { width: 300px; } .col_list:hover .col_list-ul{ overflow: auto; } .col_list .col_list_arrow{ position: absolute; left: -26px; top: 0; width: 26px; padding: 4px; background: #008080; color: #000; border-top-left-radius: 8px; border-bottom-left-radius: 8px; } .col_list > h6{ color: #aaa; margin: 10px 0 5px 0; text-align: center; white-space: nowrap; } .col_list-ul::-webkit-scrollbar { width: 5px; height: 5px } .col_list-ul::-webkit-scrollbar-thumb { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; background-color: #999; } .col_list-ul::-webkit-scrollbar-track { background-color: transparent } .col_list-ul { width: 300px; height: 300px; padding: 5px 0; overflow: hidden; color: #20B2AA; } .col_list-ul .col_item { display: flex; justify-content: space-between; align-items: center; cursor: pointer; margin: 5px 0; padding: 0 5px; line-height: 25px; border: 1px solid transparent; border-left: none; border-right: none; } .col_list-ul .col_item .his_time{ font-size: 12px; color: #fff; margin-left: 20px; white-space: nowrap; } .col_list-ul .col_item .icon_del{ border-radius: 100%; width: 16px; height: 16px; line-height: 1; display: none; text-align: center; color: #fff; } .col_list-ul .col_item:hover { box-shadow: 0 0 5px rgba(32,178,170,0.2); border-color: rgba(225,255,255,0.4); } .col_list-ul .col_item:hover .icon_del{ display: inline-block; } #ddrk-tools_pipbtn{ width: 0; height: 0; padding: 0; border: 0; } <style>`; $("head").append(mainCss); const Store = { setValue: function (key, value) { // 兼容移动端 GM_setValue ? GM_setValue(key, value) : localStorage.setItem(key, value); }, getValue: function (key) { return GM_getValue ? GM_getValue(key) || localStorage.getItem(key) : localStorage.getItem(key); }, listValues: function () { return GM_listValues(); }, }; const Common = { //参数time为休眠时间,单位为毫秒: sleep(time) { return new Promise((resolve) => { setTimeout(resolve, time); }); }, ready() { return new Promise((resolve) => { $(document).ready(function () { resolve(); }); }); }, getVue() { // 加载vuejs return new Promise((resolve) => { $.getScript("https://unpkg.com/[email protected]/dist/vue.global.js", resolve); }); }, }; /** * 获取历史记录localStorage */ const LocalHistory = { async getLocalHistory() { const jsonText = Store.getValue("ddrk-history"); let jsonList = []; if (jsonText) { jsonList = JSON.parse(jsonText); } const localData = this.getLocalStorageData(); const his = this.formatLocalData(localData); const filterList = this.filterLocalData(his); let res = this.compareLocalData(jsonList, filterList); // console.log("history-----------------", his); for (const item of res) { if (!item.name) { const name = await this.getDramaName(item.url); item.name = name.indexOf("(") > -1 ? name.split("(")[0] : name; } } // 过滤name不存在的 res = res.filter((item) => item.name); Store.setValue("ddrk-history", JSON.stringify(res)); return res; }, getLocalStorageData: function () { var len = localStorage.length; // 获取长度 var arr = new Array(); // 定义数据集 for (var i = 0; i < len; i++) { // 获取key 索引从0开始 var getKey = localStorage.key(i); // 获取key对应的值 var getVal = localStorage.getItem(getKey); // 放进数组 arr[i] = { key: getKey, val: getVal, }; } return arr; }, // 去重 filterLocalData(params) { const result = params.reduce((res, cur) => { const innerItem = res.find( (item) => item.enName === cur.enName && item.season === cur.season ); if (innerItem) { if (+cur.ep > +innerItem.ep) { res.splice( res.findIndex( (item) => item.enName === cur.enName && item.season === cur.season ), 1, cur ); } return res; } else { return res.concat(cur); } }, []); return result; }, // 格式化 formatLocalData(local) { const history = local .filter((item) => item.key.indexOf("videojs-resume:") === 0) .map((item) => { const info = item.key.split("/"); return { ...item, url: item.key.split(":")[1], enName: info[1], season: info.length > 3 && !isNaN(info[2]) ? info[2] : "", ep: info.at(-1).replace("?ep=", ""), }; }); return history; }, // 对比 compareLocalData(myList, ddrkList) { // 差集 const minus = ddrkList.filter( (ddrkItem) => !myList.some( (item) => item.enName === ddrkItem.enName && item.season === ddrkItem.season ) ); // console.log("-----差集-----", minus); const resultList = myList.map((innerItem) => { const ddrkItem = ddrkList.find( (item) => item.enName === innerItem.enName && item.season === innerItem.season ) || {}; return { ...innerItem, ...ddrkItem, }; }); return [...minus, ...resultList]; }, getDramaName(url) { return new Promise((resolve, reject) => { // $.get(`https://ddrk.me${url}`, function (result) { // console.log(result); // const name = $(result).find(".post-title").text(); // resolve(name); // }).error(function (XMLHttpRequest, textStatus, errorThrown) { // console.log(XMLHttpRequest, textStatus, errorThrown); // }); $.ajax({ url: `https://ddrk.me${url}`, type: "get", success: function (result) { //成功后回调 const name = $(result).find(".post-title").text(); resolve(name); }, error: function (e) { //失败后回调 resolve(""); }, }); }); }, handleColDel(index) { if (index !== -1) { colList.value.splice(index, 1); Store.setValue("ddrk-collection", JSON.stringify(colList.value)); } }, }; // 等待页面加载完成 await Common.ready(); await Common.getVue(); // vue容器 $("body").append($(`<div id="ddrk-tools" ></div>`)); const { createApp, toRefs, ref, h } = Vue; const svg1 = { setup(props) { return () => [ h( "svg", { class: "col_list_arrow", width: "32", height: "32", viewBox: "0 0 1024 1024", }, [ h("path", { fill: "#000", d: "M856.8 82.8H386.1c-40.4-43.2-135.5-67-188.9-67-94.9 0-175.8 70.5-188.9 164.4-5.6 16-8.3 31.3-8.3 46.7v603.7c0 98.7 80.3 179.2 179.2 179.2h695.7c82 0 148.8-66.7 148.8-148.8V249.8c0-92.2-74.8-167-166.9-167z m0 30.4c60 0 110.5 39.2 128.7 93.2H627.2l-183.5-93.2h413.1z m136.6 747.7c0 65.3-53.1 118.4-118.4 118.4H179.3c-82 0.1-148.9-66.7-148.9-148.8V226.8c0-12.3 2.3-24.7 7-38l0.8-3.2c10.5-79.4 78.7-139.5 159.1-139.5 56.2 0 142.9 26.7 170.1 61.2l4.6 5.8h2.6l242.3 120.3h374.9c0.6 5.3 1.6 10.6 1.6 16.1v611.4z m0 0", }), h("path", { fill: "#000", d: "M201.3 842.6h791v27.8h-791v-27.8z m-92.9 0h30.3v30.3h-30.3v-30.3z m258-260L346.1 693.8c-1.9 10.7 2.3 21.3 11 27.8 8.8 6.5 20.1 7.4 29.8 2.5l98.7-51.6 99.5 53.6c4.3 2.3 8.9 3.4 13.5 3.4 5.7 0 11.5-1.8 16.4-5.3 8.8-6.3 13.3-16.8 11.6-27.6L608.1 586.8l81.8-78c7.8-7.5 10.7-18.6 7.5-29-3.3-10.4-12-17.8-22.7-19.5L564.5 444l-49-101.9c-4.7-9.8-14.4-15.9-25.2-16.1-9.7-0.5-20.7 5.8-25.6 15.5L415.1 441.1l-112 15.1c-10.7 1.5-19.6 8.8-23.1 19.1s-0.8 21.4 6.9 29.1l79.5 78.2z m52.8-111.3c9.2-1.2 17.2-6.9 21.5-15.3l49.2-97.2 47.2 98.3c4.1 8.4 12 14.3 21.2 15.7L666.1 489.6l-78.8 75.2c-6.7 6.4-9.9 15.7-8.4 25l18.5 108.3-97.3-52.3c-4.2-2.3-8.8-3.4-13.4-3.4-4.4 0-8.9 1-13 3.1l-97 49.7 19.6-107.3c1.7-9.2-1.3-18.6-7.9-25.1l-77.3-77 108.1-14.5z m0 0", }), ] ), ]; }, }; const svg2 = { setup(props) { return () => [ h( "svg", { class: "col_list_arrow", width: "32", height: "32", viewBox: "0 0 1024 1024", }, [ h("path", { fill: "#000", d: "M204.8 552.96h204.8a20.48 20.48 0 0 1 0 40.96H204.8a20.48 20.48 0 0 1 0-40.96z", }), h("path", { fill: "#000", d: "M143.36 921.6a40.96 40.96 0 0 1-40.96-40.96V143.36a40.96 40.96 0 0 1 40.96-40.96h614.4a40.96 40.96 0 0 1 40.96 40.96v327.68h40.96V143.36a81.92 81.92 0 0 0-81.92-81.92H143.36a81.92 81.92 0 0 0-81.92 81.92v737.28a81.92 81.92 0 0 0 81.92 81.92h327.68v-40.96z", }), h("path", { fill: "#000", d: "M737.28 512a225.28 225.28 0 1 0 225.28 225.28 225.28 225.28 0 0 0-225.28-225.28z m0 409.6a184.32 184.32 0 1 1 184.32-184.32 184.32 184.32 0 0 1-184.32 184.32z", }), h("path", { fill: "#000", d: "M771.2768 660.6848Q634.88 584.0896 634.88 737.28t136.6016 76.5952q136.192-76.5952-0.2048-153.1904z m-13.5168 122.88Q675.84 829.44 675.84 737.28t81.92-46.08q81.92 46.08 0 92.16zM225.28 307.2h-20.48a20.48 20.48 0 0 0 0 40.96h20.48zM696.32 307.2H266.24v40.96h430.08a20.48 20.48 0 0 0 0-40.96z", }), ] ), ]; }, }; // 外壳组件 const MainBody = { props: { title: { type: String, required: true, }, style: { type: Object, required: true, }, list: { type: Array, required: true, default: () => [], }, }, setup(props, { slots }) { const { title, style, list } = toRefs(props); return () => h("div", { class: "col_list", style: style?.value }, [ h("h6", title.value), title.value === "收藏夹" ? h(svg1) : h(svg2), h( "ul", { class: "col_list-ul", }, list.value.map((item, index) => { if (title.value === "收藏夹") { return h(ColItem, { item, index, key: item.href, }); } else { return h(HistoryItem, { item, index, key: item.url + item.val, }); } }) ), ]); }, }; // 收藏item组件 const ColItem = { props: { item: { type: Object, required: true, }, index: { type: Number, required: true, }, }, setup(props, { slots }) { const { item, index } = props; return () => h( "li", { class: "col_item", onClick: () => { window.location.href = item.href; }, }, [ h("span", `${index + 1}. ${item.name}`), h( "span", { class: "icon_del", onClick: (event) => { event.stopPropagation(); LocalHistory.handleColDel(index); }, }, "x" ), ] ); }, }; // 历史item组件 const HistoryItem = { props: { item: { type: Object, required: true, }, index: { type: Number, required: true, }, }, setup(props, { slots }) { const { item, index } = props; const season = item.season ? `S${item.season}` : ""; const ep = item.ep ? `E${item.ep}` : ""; const hour = parseInt(item.val / 3600) > 0 ? parseInt(item.val / 3600) : 0; const min = parseInt((item.val - hour * 3600) / 60) > 0 ? parseInt((item.val - hour * 3600) / 60) : 0; const sec = parseInt(item.val - hour * 3600 - min * 60); const timeStr = `${hour > 9 ? hour : "0" + hour}:${min > 9 ? min : "0" + min }:${sec > 9 ? sec : "0" + sec}`; return () => h( "li", { class: "col_item", onClick: () => { window.location.href = item.url; }, }, [ h("span", `${index + 1}. ${item.name} ${season}${ep}`), h( "span", { class: "his_time", }, timeStr ), ] ); }, }; let colList = ref(JSON.parse(Store.getValue("ddrk-collection") || "[]")); let hisList = ref(await LocalHistory.getLocalHistory()); // 根组件 const App = { render() { return h("div", { class: "container" }, [ h(MainBody, { title: "收藏夹", style: { top: "35px", "z-index": 100 }, list: colList.value, }), h(MainBody, { title: "历史记录", style: { top: "85px", "z-index": 99 }, list: hisList.value, }), ]); }, }; const app = createApp(App); app.mount("#ddrk-tools"); // 监听 页面显示隐藏 document.addEventListener("visibilitychange", async function () { // console.log("-----------", document.visibilityState); if (document.visibilityState == "hidden") { //切离该页面时执行 // 标签隐藏时自动暂停播放(待开发) } else if (document.visibilityState == "visible") { //切换到该页面时执行 // 刷新历史记录-因为需要和localStorage对比 hisList.value = await LocalHistory.getLocalHistory(); } }); /** * 蒙层及收藏 */ const Collection = { init() { const modal = $("<div class='ddrk-tools__modal'></div>"); const colButton = $( '<span class="btn_col-default btn_col-remove">★</span>' ); $(".post-box").each(function () { const tempBtn = colButton.clone(true); if (!colList.value.find((item) => item.href === $(this).data("href"))) { tempBtn.addClass("btn_col-add"); tempBtn.removeClass("btn_col-remove"); tempBtn.text("☆"); } modal.html(tempBtn); $(this).append(modal.clone(true)); }); this.bindEvent(); }, bindEvent() { const self = this; // 点击打开新页签--后续添加到设置 $(".post-box").on("click", ".ddrk-tools__modal", function (e) { window.open($(this).parent().data("href")); e.stopPropagation(); }); $(".post-box").on("click", ".btn_col-default", function (e) { e.stopPropagation(); }); $(".post-box").on("click", ".btn_col-add", function (e) { const href = $(this).parent().parent().data("href"); const name = $(this).parent().parent().find(".post-box-title a").text(); if (!colList.value.find((item) => item.href === href)) { colList.value.push({ name: name.indexOf("(") > -1 ? name.split("(")[0] : name, href, }); Store.setValue("ddrk-collection", JSON.stringify(colList.value)); } self.reloadCollectHtml(1, $(this)); }); $(".post-box").on("click", ".btn_col-remove", function (e) { const href = $(this).parent().parent().data("href"); const index = colList.value.findIndex((item) => item.href === href); if (index !== -1) { colList.value.splice(index, 1); Store.setValue("ddrk-collection", JSON.stringify(colList.value)); } self.reloadCollectHtml(0, $(this)); }); }, reloadCollectHtml(tag, tempBtn) { if (tempBtn) { if (tag === 0) { tempBtn.addClass("btn_col-add"); tempBtn.removeClass("btn_col-remove"); tempBtn.text("☆"); } else { tempBtn.addClass("btn_col-remove"); tempBtn.removeClass("btn_col-add"); tempBtn.text("★"); } } else { $(".post-box").each(function () { const tempBtn = $(this).find(".btn_col-default"); if ( !colList.value.find((item) => item.href === $(this).data("href")) ) { tempBtn.addClass("btn_col-add"); tempBtn.removeClass("btn_col-remove"); tempBtn.text("☆"); } else { tempBtn.addClass("btn_col-remove"); tempBtn.removeClass("btn_col-add"); tempBtn.text("★"); } }); } }, }; Collection.init(); /** * 自动跳转并播放下一集 */ const autoPlayNext = { player: null, playerModel: {}, nextType: "hand", // 手动 | 自动 init() { this.initPlayer(); this.bindEvent(); // Videojs requestPictureInPicture()在滚动到顶部和底部时仅工作一次 // 解决方案:通过添加按钮模拟点击解决 $("body").append( $(`<button id="ddrk-tools_pipbtn" title="切换画中画"></button>`) ); }, initPlayer() { this.player = unsafeWindow.videojs.getAllPlayers()[0]; console.time("视频源数据加载完成"); // 监听 this.player?.one("canplaythrough", async (e) => { console.timeEnd("视频源数据加载完成"); await Common.sleep(200); this.nextType === "auto" && this.restoreVideoModel(); }); this.player?.on("ended", async () => { // console.log("--------------ended-------------"); this.getCurrentVideoModel(); // 在下一集之前获取当前video状态 if (this.playerModel.isInPictureInPicture) { //在画中画模式z则退出 // document.exitPictureInPicture(); $("#ddrk-tools_pipbtn")[0].click(); } this.handleToNext(); this.nextType = "auto"; await Common.sleep(200); this.initPlayer(); this.handleToPlay(); }); }, bindEvent() { // 主动点击下一集 $(unsafeWindow.document).on( "click", ".wp-playlist-tracks .wp-playlist-item, icon-angle-right", async (e) => { await Common.sleep(200); this.initPlayer(); this.nextType = "hand"; } ); // 切换画中画 $("body").on("click", "#ddrk-tools_pipbtn", function (e) { if (!document.pictureInPictureElement) { $("#vjsp_html5_api")[0].requestPictureInPicture(); } else { document.exitPictureInPicture(); } }); }, getCurrentVideoModel() { // 保存当前video模式 this.playerModel = { isFullscreen: this.player.isFullscreen_, // 全屏 isInPictureInPicture: !!document.pictureInPictureElement, // 画中画 isFullWindow: !!$(".vjs-theater-mode-control-close").length, // 网页全屏:打开时会包含vjs-theater-mode-control-close }; }, handleToNext() { (this.player.controlBar.childNameIndex_.nextButton || {}).handleClick(); // 下一集按钮 }, handleToPlay() { if (this.player.resumeModal?.opened_) { // 已打开恢复弹框则选择 是 this.player.resumeModal.childNameIndex_.modalButtons.childNameIndex_.resumeButton.el_.click(); } else { this.player.bigPlayButton?.el_.click(); //播放按钮 localStorage.setItem( window.location.href.replace("https://ddrk.me", "videojs-resume:"), 0 ); } }, async restoreVideoModel() { // 恢复上次video模式 if (this.playerModel.isFullscreen) { // ( // this.player.controlBar.childNameIndex_.fullscreenToggle || {} // ).handleClick(); this.player.controlBar.childNameIndex_.fullscreenToggle.el_.click(); } else if (this.playerModel.isInPictureInPicture) { // await Common.sleep(2000); // ( // this.player.controlBar.childNameIndex_.pictureInPictureToggle || {} // ).handleClick(); // this.player.controlBar.childNameIndex_.pictureInPictureToggle.el_.click(); // $("#vjsp_html5_api")[0].requestPictureInPicture(); $("#ddrk-tools_pipbtn")[0].click(); } else if (this.playerModel.isFullWindow) { ( this.player.controlBar.childNameIndex_.theaterModeToggle || {} ).handleClick(); // this.player.controlBar.childNameIndex_.theaterModeToggle.el_.click(); } }, }; autoPlayNext.init(); // /** // * 播放页上次观看记录提示 // */ // const watchRecord = { // init() { // // 有播放器则继续 // if (unsafeWindow.videojs.getAllPlayers()[0]) { // this.bindEvent(); // } // }, // bindEvent() { // $(window).bind("beforeunload", function () { // // debugger; // // return "dfdfdsfsfs提示:未保存的内容将会丢失。"; //好像这个提示并没什么用 // }); // }, // }; // watchRecord.init(); // 设置 1、自动播放开关,点击打开新页签开关 })();