查看关注的正在直播的主播
// ==UserScript==
// @name 查看关注的正在直播的主播
// @namespace http://tampermonkey.net/
// @version 2.0
// @description 原介绍:“默认显示9个太少了,每次看也很麻烦”
// @author 芙蓉谷
// @match https://*.bilibili.com/*
// @grant GM_addStyle
// @connect api.live.bilibili.com
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-start
// ==/UserScript==
(function() {
const API_URL = "https://api.live.bilibili.com/xlive/web-ucenter/user/following";
const settings = {
maxLiveUsers: GM_getValue("setting.maxLiveUsers"),
cooldownTime: GM_getValue("setting.cooldownTime"),
maxPages: GM_getValue("setting.maxPages")
};
const fetchFollowingList = (page) => {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
url: `${API_URL}?page=${page}&page_size=29`,
method: "GET",
headers: { "cookie": document.cookie },
onload: (xhr) => {
const response = JSON.parse(xhr.responseText);
resolve(response.data.list);
},
onerror: reject
});
});
};
const createLiveListDiv = () => {
const div = document.createElement("div");
div.className = 'upList';
div.innerHTML = `
<div class="upListHeader">
<span class="upListTitle">正在直播</span>
<button class="toggleButton">折叠</button>
</div>
<ol class="upListOl"></ol>
`;
document.body.append(div);
const toggleButton = document.querySelector('.toggleButton');
const upListOl = document.querySelector('.upListOl');
toggleButton.addEventListener('click', () => {
if (upListOl.style.display === 'none') {
upListOl.style.display = 'block';
div.style.height = '400px';
toggleButton.textContent = '折叠';
} else {
upListOl.style.display = 'none';
div.style.height = 'auto';
toggleButton.textContent = '展开';
}
});
};
let currentIndex = 0; // 记录当前列表中的序号
const addLiveUserToList = (user) => {
const ol = document.querySelector(".upListOl");
currentIndex++; // 每次添加时递增序号
const li = document.createElement("li");
li.innerHTML = `<span class="index">${currentIndex}.</span> <a href="${user.liveUrl}" target="_blank" class="uname">${user.username}</a>`;
ol.appendChild(li);
};
const populateLiveList = async () => {
let page = 1;
let liveUsersCount = 0;
while (page <= settings.maxPages && liveUsersCount < settings.maxLiveUsers) {
const list = await fetchFollowingList(page);
if (list.length === 0) break;
list.forEach((item) => {
if (item.live_status === 1 && liveUsersCount < settings.maxLiveUsers) {
const liveUrl = `https://live.bilibili.com/${item.roomid}`;
const username = item.uname;
addLiveUserToList({ username, liveUrl });
liveUsersCount++;
}
});
page++;
// 添加冷却时间
await new Promise((resolve) => setTimeout(resolve, settings.cooldownTime));
}
};
setTimeout(() => {
createLiveListDiv();
populateLiveList();
}, 2000);
GM_addStyle(`
.upList {
position: fixed;
background: rgba(255, 255, 255, 0.95);
top: 80px;
right: 5px;
width: 220px;
height: 400px;
overflow-y: auto;
z-index: 999;
border-radius: 15px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
color: #333;
padding: 10px;
transition: height 0.3s ease-in-out;
}
.upListHeader {
display: flex;
justify-content: space-between;
align-items: center;
}
.upListTitle {
font-size: 18px;
font-weight: bold;
color: #007aff;
}
.toggleButton {
background: #007aff;
color: white;
border: none;
border-radius: 5px;
padding: 5px 10px;
cursor: pointer;
pointer-events: auto;
}
.toggleButton:hover {
background: #005bb5;
}
.upListOl {
list-style-type: none;
padding: 0;
margin: 0;
}
.upListOl li {
display: flex;
justify-content: space-between;
padding: 10px 5px;
border-bottom: 1px solid #eee;
}
.upListOl li:last-child {
border-bottom: none;
}
.index {
color: #999;
}
.uname {
flex-grow: 1;
margin-left: 5px;
text-decoration: none;
color: #007aff !important;
}
.uname:hover {
text-decoration: underline;
}
`);
})();
/* ==UserConfig==
setting:
maxLiveUsers:
title: 最大正在直播主播数量
description: 设置同时显示的正在直播主播数量
type: number
default: 10
min: 1
max: 100
cooldownTime:
title: 请求冷却时间(毫秒)
description: 设置每次请求的冷却时间,防止频繁请求
type: number
default: 5000
min: 100
max: 10000
maxPages:
title: 最大请求页数
description: 设置最大连续请求的页数,避免过多请求
type: number
default: 5
min: 1
max: 50
==/UserConfig== */