您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为B站分P视频添加随机播放功能
// ==UserScript== // @name b站分P视频随机播放 // @namespace https://github.com/LU-JIEJIE/bilibili-random-play // @version 1.1.0 // @author lu-jiejie // @description 为B站分P视频添加随机播放功能 // @license MIT // @icon https://www.bilibili.com/favicon.ico // @homepage https://github.com/LU-JIEJIE/bilibili-random-play // @match https://www.bilibili.com/video/* // ==/UserScript== (function () { 'use strict'; function setLocalStorage(key, value) { window.localStorage.setItem(key, value); } function getLocalStorage(key) { return window.localStorage.getItem(key); } function formatLog(logStr) { console.log(`[Bilibili Random Play]: ${logStr}`); } function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } function createElementFromHTML(htmlString) { const parser = new DOMParser(); const doc = parser.parseFromString(htmlString, "text/html"); return doc.body.firstChild; } function insertBefore(newNode, referenceNode) { var _a; (_a = referenceNode.parentNode) == null ? void 0 : _a.insertBefore(newNode, referenceNode); } function insertAfter(newNode, referenceNode) { var _a; (_a = referenceNode.parentNode) == null ? void 0 : _a.insertBefore(newNode, referenceNode.nextSibling); } const NOT_LIST_TYPE_VIDEO = "当前页面不是分P视频,无法使用随机播放。"; const CONTROL_PREV_BUTTON = `<div class="bpx-player-ctrl-btn bpx-player-ctrl-prev" role="button" aria-label="上一个" tabindex="0" "=""><div class="bpx-player-ctrl-btn-icon"><span class="bpx-common-svg-icon"><svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" data-pointer="none" style="enable-background:new 0 0 22 22" viewBox="0 0 22 22"><path d="M16 5a1 1 0 0 0-1 1v4.615a1.431 1.431 0 0 0-.615-.829L7.21 5.23A1.439 1.439 0 0 0 5 6.445v9.11a1.44 1.44 0 0 0 2.21 1.215l7.175-4.555a1.436 1.436 0 0 0 .616-.828V16a1 1 0 0 0 2 0V6C17 5.448 16.552 5 16 5z"></path></svg></span></div></div>`; const CONTROL_NEXT_BUTTON = `<div class="bpx-player-ctrl-btn bpx-player-ctrl-next" role="button" aria-label="下一个" tabindex="0"><div class="bpx-player-ctrl-btn-icon"><span class="bpx-common-svg-icon"><svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" data-pointer="none" style="enable-background:new 0 0 22 22" viewBox="0 0 22 22"><path d="M16 5a1 1 0 0 0-1 1v4.615a1.431 1.431 0 0 0-.615-.829L7.21 5.23A1.439 1.439 0 0 0 5 6.445v9.11a1.44 1.44 0 0 0 2.21 1.215l7.175-4.555a1.436 1.436 0 0 0 .616-.828V16a1 1 0 0 0 2 0V6C17 5.448 16.552 5 16 5z"></path></svg></span></div></div>`; const SET_TIMEOUT_TIME = 500; let isRandom = false; let totalPage = 0; let curRandomIndex = 0; let randomList = []; let videoList = []; let prevButton; let nextButton; let lock = false; function init() { ({ totalPage } = getPageInfo()); if (totalPage === 0) { formatLog(NOT_LIST_TYPE_VIDEO); return; } createControlButton(); resetControlButton(); initVideoList(); bindVideoListEvent(); } function getPageInfo() { const pageInfoSpan = document.querySelector("span.cur-page"); if (!pageInfoSpan) return { curPage: 0, totalPage: 0 }; const [curPage, totalPage2] = pageInfoSpan.innerHTML.replace(/\(|\)/, "").split("/").map((item) => Number.parseInt(item)); return { curPage, totalPage: totalPage2 }; } function initVideoList() { setTimeout(() => { videoList = Array.from(document.querySelectorAll("ul.list-box > li > a > div.clickitem")); if (videoList.length === 0) { initVideoList(); } else { createRandomButton(); } }, SET_TIMEOUT_TIME); } function createControlButton() { prevButton = createElementFromHTML(CONTROL_PREV_BUTTON); nextButton = createElementFromHTML(CONTROL_NEXT_BUTTON); prevButton.addEventListener("click", () => { if (isRandom) playNext(-1); else videoList[videoList.length - 1].click(); }); nextButton.addEventListener("click", () => { if (isRandom) playNext(); else videoList[0].click(); }); } function prevButtonEvent(e) { if (isRandom) { playNext(-1); e.stopPropagation(); e.preventDefault(); } } function nextButtonEvent(e) { if (isRandom) { playNext(); e.stopPropagation(); e.preventDefault(); } } function resetControlButton() { changeControlButtonState("prev", "remove"); changeControlButtonState("next", "remove"); setTimeout(() => { const nextButton2 = document.querySelector("div.bpx-player-ctrl-next"); const prevButton2 = document.querySelector("div.bpx-player-ctrl-prev"); if (nextButton2 && prevButton2) { prevButton2.removeEventListener("click", prevButtonEvent); nextButton2.removeEventListener("click", nextButtonEvent); prevButton2.addEventListener("click", prevButtonEvent); nextButton2.addEventListener("click", nextButtonEvent); } else if (nextButton2) { changeControlButtonState("prev", "insert"); } else if (prevButton2) { changeControlButtonState("next", "insert"); } else { resetControlButton(); } }, SET_TIMEOUT_TIME); } function handleRandomState(state) { if (state === "on") { isRandom = true; changeRandomButtonState(true); setLocalStorage("isRandom", "true"); closeAutoPlay(); initRandomList(); bindVideoEvent(); } else if (state === "off") { isRandom = false; changeRandomButtonState(false); setLocalStorage("isRandom", ""); } } function closeAutoPlay() { lock = true; const autoPlayButton = document.querySelector("#multi_page > div.head-con > div.head-right > span:nth-child(2) > span.switch-button"); if (autoPlayButton == null ? void 0 : autoPlayButton.classList.contains("on")) autoPlayButton.click(); lock = false; } function playNext(distance = 1) { curRandomIndex = (curRandomIndex + distance + totalPage) % randomList.length; const nextPage = randomList[curRandomIndex]; videoList[nextPage - 1].click(); } function bindVideoEvent() { setTimeout(() => { const video = document.querySelector("div.bpx-player-video-wrap > video"); if (video) { video.addEventListener("ended", (event) => { event.stopImmediatePropagation(); playNext(); }); } else { bindVideoEvent(); } }, SET_TIMEOUT_TIME); } function bindVideoListEvent() { setTimeout(() => { const videoList2 = document.querySelector("ul.list-box"); videoList2 == null ? void 0 : videoList2.addEventListener("click", (e) => { if (e.target.tagName !== "UL") { resetControlButton(); const curPage = +/p=(\d+)/.exec(document.location.href)[1]; curRandomIndex = randomList.findIndex((item) => item === curPage); } }); }, SET_TIMEOUT_TIME); } function changeControlButtonState(buttonType, buttonState) { const playButton = document.querySelector("div.bpx-player-ctrl-play"); if (buttonType === "prev") { if (buttonState === "insert") insertBefore(prevButton, playButton); else prevButton.remove(); } else if (buttonType === "next") { if (buttonState === "insert") insertAfter(nextButton, playButton); else nextButton.remove(); } } function createRandomButton() { const path = document.querySelector("#multi_page > div.head-con > div.head-right"); path.insertAdjacentHTML("afterbegin", ` <span class="next-button" id="random-button"> <span class="txt">随机</span> <span class="switch-button"></span> </span> `); document.querySelector("span#random-button").addEventListener("click", () => { if (isRandom) handleRandomState("off"); else handleRandomState("on"); }); isRandom = Boolean(getLocalStorage("isRandom")) || false; if (isRandom) handleRandomState("on"); else handleRandomState("off"); const autoPlayButton = document.querySelector("#multi_page > div.head-con > div.head-right > span:nth-child(2)"); autoPlayButton.addEventListener("click", () => { if ((autoPlayButton == null ? void 0 : autoPlayButton.children[1].classList.contains("on")) && isRandom && !lock) handleRandomState("off"); }); } function changeRandomButtonState(on) { const randomButton = document.querySelector("span#random-button .switch-button"); if (on) randomButton.classList.add("on"); else randomButton.classList.remove("on"); } function initRandomList() { randomList = Array.from({ length: totalPage }).fill(0).map((_, index) => index + 1); for (let i = randomList.length - 1; i >= 0; i--) { const randomIndex = randomInt(0, i); [randomList[i], randomList[randomIndex]] = [randomList[randomIndex], randomList[i]]; } const { curPage } = getPageInfo(); randomList.splice(randomList.indexOf(curPage), 1); randomList.unshift(curPage); curRandomIndex = 0; } init(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址