Skip to content

Instantly share code, notes, and snippets.

@WsureDev
Last active February 9, 2025 13:42
Show Gist options
  • Save WsureDev/73a91d153be596e10ef2e84a24621c90 to your computer and use it in GitHub Desktop.
Save WsureDev/73a91d153be596e10ef2e84a24621c90 to your computer and use it in GitHub Desktop.
[油猴脚本] Bilibili 合集、收藏夹自动播放
// ==UserScript==
// @name Bilibili Auto Play Next
// @namespace http://tampermonkey.net/
// @supportURL https://gist.github.com/WsureDev/73a91d153be596e10ef2e84a24621c90#file-bilibili-auto-play-next
// @homepageURL https://greasyfork.org/zh-CN/scripts/481434-bilibili-auto-play-next
// @version 0.1.3
// @description 合集、收藏夹连播,可全局也可仅当前生效,懂得都懂
// @author wsure
// @match *://*.bilibili.com/*
// @icon https://static.hdslb.com/images/favicon.ico
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addElement
// @grant GM_xmlhttpRequest
// @require https://code.jquery.com/jquery-3.7.1.min.js
// @run-at document-end
// @license MIT
// @downloadURL https://update.greasyfork.org/scripts/481434/Bilibili%20Auto%20Play%20Next.user.js
// @updateURL https://update.greasyfork.org/scripts/481434/Bilibili%20Auto%20Play%20Next.meta.js
// ==/UserScript==
let globalAutoPlayNext = GM_getValue('globalAutoPlayNext',false);
let autoPlayList = GM_getValue('autoPlayList',{});
// 一段自动设置播放速度和画质的代码,写着玩的没啥用了
function setQualityAndSpeed(){
const video = document.querySelector("video");
if (window.location.href.includes('BV')){
let flag = false;
video.addEventListener("play", (event) => {
if(!flag){
$('div.bpx-player-ctrl-btn.bpx-player-ctrl-quality > ul > li:nth-child(3)').click();
setTimeout(() => {$('div.bpx-player-ctrl-btn.bpx-player-ctrl-playbackrate > ul > li:nth-child(2)').click();},1000)
flag = true;
console.log('set player quality')
}
});
}
}
function playNext(){
return GM_getValue('globalAutoPlayNext',false) || currentPlayNext();
}
function currentPlayNext(){
return getPlayListUrl() in autoPlayList;
}
function isChannel_1(){
// channel old
return $(".base-video-sections-v1").length >0
}
function isChannel_2(){
// channel old
return $(".video-pod__body").length >0
}
function isChannel(){
return isChannel_1() || isChannel_2()
}
function getPlayListUrl(){
let _type=getVideoListType();
if(_type == 'channel'){
if(isChannel_1()) {
return $('div.base-video-sections-v1 > div.video-sections-head > div.video-sections-head_first-line > div.first-line-left > a').attr('href');
} else if(isChannel_2()){
return $('div.video-pod.video-pod > div.video-pod__header > div.header-top > div.left > a').attr('href');
}
} else if(_type =='pList'){
return $('#multi_page > div.cur-list > ul > li.on > a').attr('href');
} else if(_type =='favlist'){
return window.location.href.replace(/\?.*/,'');
} else {
return window.location.href.replace(/\?.*/,'');
}
}
function getVideoListType(){
if(isChannel()){
return 'channel';
} else if($('#multi_page > div.head-con').length >0){
return 'pList';
} else if($('div.action-list-container').length >0){
return 'favlist';
} else {
return null;
}
}
function isVideoList(){
return isChannel()
|| $('div.action-list-container').length >0 // 收藏
|| $('#multi_page > div.head-con').length >0 // 分P
;
}
//在视频结束事件里加入“播放下一个”的操作
function setNextPlay(){
const video = document.querySelector("video");
if(getVideoListType() !== null){
video.addEventListener("ended", (event) => {
if (playNext())
setTimeout(function () {
// 点下一个按钮
if($('.bpx-player-ctrl-next').length >0){
$('.bpx-player-ctrl-next').click();
}
else if($('div.video-section-list.section-0 > div:nth-child(1)').length >0){ //合集末尾没有按钮,回到首个视频,不喜欢这个功能可以直接删掉这个else if
$('div.video-section-list.section-0 > div:nth-child(1)').click()
}
else if($('#multi_page > div.head-con').length >0){ //分P合集末尾没有按钮,回到首个视频,不喜欢这个功能可以直接删掉这个else if
$('#multi_page > div.cur-list > ul > li:nth-child(1) > a > div > div.link-content > span.part').click()
}
}, 1000);
})
}
}
function initButton(){
let buttonsDiv = $('<div>', {
id:'my-next',
css: {
display: 'flex',
flexDirection: 'row'
}
});
let buttonGlobal = $('<button>', {
id:'my-next-btn-G',
text: '总',
css: {
backgroundColor: (globalAutoPlayNext?'#fb7299':'gray'),
color: 'white',
borderRadius: '8px',
padding: '10px',
border: '2px solid white'
},
click: function () {
setGlobalPlayNext(!globalAutoPlayNext)
}
});
let buttonCurrent = $('<button>', {
id:'my-next-btn-C',
text: '当',
css: {
backgroundColor: (currentPlayNext()?'#fb7299':'gray'),
color: 'white',
borderRadius: '8px',
padding: '10px',
border: '2px solid white',
display:globalAutoPlayNext? 'none':'block'
},
click: function () {
setCurrentPlayNext()
}
});
buttonsDiv.append(buttonGlobal,buttonCurrent)
//合集
if(isChannel_1()){
$('div.second-line_left').append(buttonsDiv);
}
if(isChannel_2()){
$('div.video-pod.video-pod > div.video-pod__header > div.header-top > div.left').append(buttonsDiv);
}
//收藏夹
if($("div.action-list-container").length >0){
$('div.header-left').append(buttonsDiv);
}
if($('#multi_page > div.head-con').length >0){
$('div.head-con').append(buttonsDiv);
}
}
function setGlobalPlayNext(v){
if(v){
globalAutoPlayNext = true;
GM_setValue('globalAutoPlayNext',true)
document.querySelector('#my-next-btn-G').style.backgroundColor='#fb7299'
$('#my-next-btn-C').hide()
} else{
globalAutoPlayNext = false;
GM_setValue('globalAutoPlayNext',false)
document.querySelector('#my-next-btn-G').style.backgroundColor='gray'
$('#my-next-btn-C').show()
document.querySelector('#my-next-btn-C').style.backgroundColor=currentPlayNext()?'#fb7299':'gray'
}
}
function setCurrentPlayNext(){
let currentUrl = getPlayListUrl();
if(currentPlayNext()){
delete autoPlayList[currentUrl];
} else {
autoPlayList[currentUrl] = true;
}
GM_setValue('autoPlayList',autoPlayList);
document.querySelector('#my-next-btn-C').style.backgroundColor=currentPlayNext()?'#fb7299':'gray'
}
function afterListInit() {
setTimeout(function () {
//仅在符合`合集`或者`收藏夹`或者`分p合集`,并且没有找到我们的按钮的情况下初始化按钮
if(getVideoListType() !== null && $('#my-next-btn').length ==0){
initButton();
} else {
afterListInit();
}
},5000); // 5秒刷一次,免得列表更新按钮没了
}
(function() {
'use strict';
// Your code here...
$(document).ready(function () {
afterListInit();
setNextPlay();
});
})();
@WsureDev
Copy link
Author

WsureDev commented Dec 5, 2023

列表上会多出来一个Next按钮,灰色表示不会自动播放,粉色表示激活自动播放。好处就是不会像自带的自动连播那样影响看单个视频

@WsureDev
Copy link
Author

WsureDev commented Dec 8, 2023

由于在使用初版功能的时候发现,很多视频现在收录在合集中,与预想的实现效果还有差距,因此开发新按钮,为播放列表单独添加自动播放状态保存,实现不同列表的自动播放相互独立
1.将原有功能保留,效果为全局打开分P、合集、收藏夹的自动播放,按钮为“总”。
2.新增当前列表的单独自动播放功能,按钮为“当”,需要在关闭全局自动播放的“总”按钮时生效,默认为关,手动打开后会记录此列表的自动播放状态。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment