哔哩哔哩 历史记录备份
哔哩哔哩自带的历史记录有效期只有三个月左右,写来自用的插件,功能大致就是下图,播放进度大于85%会在【TA的视频】里隐藏避免重复播放,更新了个云备份(代码里搜坚果云,改为自己的号后取消注释就行)// ==UserScript==
// @name 哔哩哔哩 - 进度备份
// @namespace Violentmonkey Scripts
// @match *://*.bilibili.com/*
// @version 1.0
// @license BSD
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_listValues
// @run-at document-start
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @require https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js
// @require https://greasyfork.org/scripts/463081-webdav/code/webdav.js
// @noframes
// ==/UserScript==
(() => {
const config = {
"hide_watched_videos": true,//隐藏观看过的视频
"backup_to_cloud": true
};
const rules = {
"all": [".*://.*.bilibili.com.*", []],
"home": [".*://www.bilibili.com(?:$|/$|/\\?.*)", ],//首页
"video": [".*://www.bilibili.com/video/(*).*", ],//视频
"sapce": [".*://space.bilibili.com/.*", ]//主页
};
(function () {
for (type in rules) {
var focus = rules
var regexp = RegExp(focus, "i").exec(window.location.href)
if (regexp != null) {
console.log("\u9875\u9762\u7c7b\u578b", type, "|", "\u4f7f\u7528\u51fd\u6570", focus);
for (let i = 0; i < focus.length; i++) {
focus.call(null, { regexp: regexp.slice(1,) })
}
}
}
}());
//(new webdav("dav账号", "dav密码")).AutoBack('bilibili')//只能支持坚果云
//----------------功能模块
function RecordPlayTime() {//记录播放进度
$(bind)
function bind() {
let window = unsafeWindow
$('video,bwp-video').on("timeupdate", throttle(
function () {
if ("__INITIAL_STATE__" in window) {
if ("bvid" in window.__INITIAL_STATE__) {
let bvid = window.__INITIAL_STATE__.bvid
let duration = parseInt(this.target.duration)
let currentTime = parseInt(this.target.currentTime)
let old = GM_getValue_local("history", bvid, false)
if (!old || old.p < currentTime) {
GM_setValue_local("history", bvid, { d: duration, p: currentTime })
} else {
//当前进度小于历史最大进度
}
}
}
}, 1000
))
$('video,bwp-video').on("ended",
() => {
if ("bvid" in window.__INITIAL_STATE__) {
let PlayList = GM_getValue('PlayList', null)
let Index = PlayList.indexOf(window.__INITIAL_STATE__.bvid)
if (Index != -1) {
location.replace('https://www.bilibili.com/video/' + PlayList[++Index])
}
}
}
)
}
}
function PlayProgressUI() {//进度条
ObserveNewElements(".small-item.fakeDanmu-item", insert)
window.onfocus = function (e) {
$('.small-item.fakeDanmu-item').each(
function () {
insert(this)
}
)
}
function insert(element) {
var id = $(element).attr('data-aid')
var history = GM_getValue_local("history", id, false)
if (!!history) {//判断JSON是否为空
var progress_ui = document.createElement('div');
var Percent = getPercent(history.p, history.d)
$(progress_ui).attr('class', 'progress').attr('style', 'top: 0px;position: absolute;width: 100%;height: 4px;background-color: #909090;').html(`<div id="content" style="width: ${Percent}%;height: 100%;background-color: #f00;"></div>`);
$(element).find('.cover').append(progress_ui);
if (config["hide_watched_videos"]) {//读取设置
if (Percent > 85) {
$(element).hide();
$(element).css('border', '1px solid #e9e9e9')
}
}
}
}
}
function RemoveAdsHome() {
$(
function () {
let observer = new MutationObserver((mutationsList, observer) => {
// 遍历每一个发生变化的 mutation
for (let mutation of mutationsList) {
// 检查新增元素
if (mutation.type === 'childList') {
// 遍历新增的节点和子节点
mutation.addedNodes.forEach(node => {
if ($(node).is('.bili-video-card.is-rcmd') || $(node).is('.feed-card')) {
handleNode(node);
}
});
}
}
});
// 要监视的目标节点
let targetNode = document.body;
// 配置并启动 MutationObserver
observer.observe(targetNode, { childList: true, subtree: true });
// 处理新增的节点的函数
function handleNode(node) {
if (node.marking) {
return null
}
let element = $(node).find("div>a")
if (!element.getAttribute('href').includes("www.bilibili.com")) {
node.marking = true
if ($(node.parentElement).is('.feed-card')) {
node.parentElement.parentElement.appendChild(node.parentElement);
} else {
node.parentElement.appendChild(node);
}
console.log("移除广告", node);
}
}
$('.bili-video-card.is-rcmd').each(function () {
handleNode(this)
});
}
)
}
//----------------常用函数
function throttle(fn, intvl, ...prm) {//节流
let timer;
let interval;
return function (...args) {
if (!timer) {
timer = setTimeout(function () {
interval = intvl
fn.call(...args, ...prm)
timer = null;
}, interval)
}
}
}
function formatTime(seconds) {//转换时间格式
let minutes = Math.floor(seconds / 60);
seconds = seconds % 60;
return (minutes < 10 ? "0" : "") + minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
}
function getPercent(num, total) {//取百分比
num = parseFloat(num);
total = parseFloat(total);
if (isNaN(num) || isNaN(total)) {
return 0;
}
return total <= 0 ? "0%" : (Math.round(num / total * 10000) / 100.00);
}
function ObserveNewElements(selector, response, filter) {//selector,call(node,mutation),filterRepetition=true)
'use strict';
if (!!selector) {
let config = {
childList: true,
subtree: true
};
const mutationCallback = (mutationsList) => {
for (let mutation of mutationsList) {
let type = mutation.type;
if (type == "childList") {
if (mutation.addedNodes.length != 0) {
var New_node = []
for (let index = 0; index < mutation.addedNodes.length; index++) {
var Nodes = $(mutation.addedNodes)
for (let Tindex = 0; Tindex < Nodes.length; Tindex++) {
if ($(Nodes).is(selector)) {
New_node.push(Nodes)
}
}
Nodes.find(selector).each(
function () {
New_node.push(this)
}
)
}
if (New_node.length > 0) {
setTimeout((function (list) {
for (let i = 0; i < list.length; i++) {
if (filter) {
if (list['OpenFilter']) {
continue;
} else {
list['OpenFilter'] = true
}
}
response.call(mutation, list, mutation)
}
}(New_node)), 300)
}
}
}
}
};
var observe = new MutationObserver(mutationCallback);
observe.observe(document, config)
return observe
}
}
function GM_getValue_local(id, key, defaultValue) {
var data = GM_getValue(id, {});
return data || defaultValue;
}
function GM_setValue_local(id, key, value) {
var data = GM_getValue(id, {});
data = value;
return GM_setValue(id, data);
}
})(); 这代码怎么用啊,小白可以用吗{:17_1067:} 谢谢,这个功能很实用 正需要就有了 谢谢 很实用的功能,谢谢分享 {:1_893:}学习了,打开了思路 学习到了,格局打开了{:1_918:} 本帖最后由 leo580 于 2023-7-12 14:25 编辑
加载到,暴力猴后,保存提示。提示脚本不合适。 前来学习 怎么用啊 这个脚本
页:
[1]
2