// ==UserScript==
// @name 百度网盘打开中文字幕(改)
// @namespace http://tampermonkey.net/
// @version 1.25
// @description 百度网盘自动打开中文字幕
// @author woshilisisui
// @match https://pan.baidu.com/pfile/video?path=*.mp4*
// @icon https://th.bing.com/th?id=ODLS.039b3eb8-253e-4d80-8727-6e7d039c3891&w=32&h=32&qlt=90&pcl=fffffa&o=6&pid=1.2
// @grant none
// @license GPL3
// ==/UserScript==
(function () {
'use strict';
let interval
// 等待页面完全加载完毕后执行脚本
window.onload = function() {
//document.querySelector('.vjs-big-play-button').style.display = 'none';
//document.querySelector('.vp-file-video-container__tools').style.display = 'none';
var controlBar
var controlBar2
var controlBar3
var controlBar4
var controlBar5
var videoElement
var videoElement2
let timeout;
function getElement() {
console.log('getElement')
document.querySelector('.vjs-big-play-button').style.display = 'none';
controlBar = document.querySelector('.video-js .vjs-control-bar');
controlBar2 = document.querySelector('.vp-video .vp-video__control-bar');
controlBar3 = document.querySelector('.vp-video .vp-video__control-bar--play-time-current');
controlBar4 = document.querySelector('.vp-video .vp-video__control-bar--play-time-all');
controlBar5 = document.querySelector('.vp-file-video-container__tools');
videoElement = document.querySelector('.video-js .vjs-tech');
videoElement2 = document.querySelector('.vp-video__player');
}
function toggleControlBar(display) {
if (!controlBar || !controlBar2 || !controlBar3 || !controlBar4 || !controlBar5) {
getElement();
return;
}
const displayValue = display ? 'block' : 'none';
if (controlBar) controlBar.style.display = displayValue;
if (controlBar2) controlBar2.style.display = display ? 'flex' : 'none';
if (controlBar3) controlBar3.style.display = displayValue;
if (controlBar4) controlBar4.style.display = displayValue;
if (controlBar5) controlBar5.style.display = displayValue;
}
function controlB() {
timeout = setTimeout(() => {
toggleControlBar(false);
}, 1000);
}
function controlBDisplay() {
clearTimeout(timeout);
toggleControlBar(true);
}
let isMouseMoveBound = false;
let isMouseLeaveBound = false;
let isControlBarMouseOverBound = false;
let isControlBarMouseLeave = false;
function bindEvents() {
try {
// 先解绑之前的事件
if (isMouseMoveBound) {
videoElement.removeEventListener('mousemove', onMouseMove);
isMouseMoveBound = false;
}
if (isMouseLeaveBound) {
videoElement2.removeEventListener('mouseleave', onMouseLeave);
isMouseLeaveBound = false;
}
if (isControlBarMouseOverBound) {
controlBar.removeEventListener('mouseover', onControlBarMouseOver);
controlBar5.removeEventListener('mouseover', onControlBarMouseOver);
isControlBarMouseOverBound = false;
}
if (isControlBarMouseLeave) {
controlBar5.removeEventListener('mouseleave', onControlBarMouseLeave);
isControlBarMouseLeave = false;
}
// 重新绑定事件
videoElement.addEventListener('mousemove', onMouseMove);
videoElement2.addEventListener('mouseleave', onMouseLeave);
controlBar.addEventListener('mouseover', onControlBarMouseOver);
controlBar5.addEventListener('mouseover', onControlBarMouseOver);
controlBar5.addEventListener('mouseleave', onControlBarMouseLeave);
// 更新绑定状态
isMouseMoveBound = true;
isMouseLeaveBound = true;
isControlBarMouseOverBound = true;
isControlBarMouseLeave = true;
} catch (err) {
console.error('绑定事件出错:', err);
// 尝试重新绑定
setTimeout(() => {
getElement();
bindEvents();
}, 1000); // 等待1秒后重试
}
}
function onMouseMove() {
clearTimeout(timeout);
controlBDisplay();
controlB();
}
function onMouseLeave() {
clearTimeout(timeout);
controlB();
}
function onControlBarMouseOver() {
clearTimeout(timeout);
}
function onControlBarMouseLeave() {
clearTimeout(timeout);
controlB();
}
getElement();
// 添加事件绑定
bindEvents();
let lastUrl = '' // 存储上一个 URL
// 监听 DOM 变化
const observer = new MutationObserver(() => {
const currentUrl = window.location.href;
// 检查 URL 是否发生变化
if (currentUrl !== lastUrl) {
console.log('URL发生变化');
lastUrl = currentUrl; // 更新上一个 URL
controlBDisplay();
controlB();
//setTimeout(() => {
// simulateMouseHoverToButton();
//}, 0);
clearInterval(interval); // 停止当前轮询
// URL 变化后稍微延迟一段时间再检测,确保 DOM 完全更新
setTimeout(() => {
waitForSubtitleButton();
checkAddDownloadButton();
}, 0);
}
});
// 开始观察 DOM 变化,监听整个页面的变化
observer.observe(document.body, { childList: true, subtree: true });
// 修改字幕颜色
function changeSubtitle() {
try {
var subtitleText = document.querySelector('.vp-video__subtitle-text.show')
//subtitleText.style.background = '#d6d6d6';
subtitleText.style.background = 'rgba(214, 214, 214, 0.5)'
subtitleText.style.color = '#ff0000';
console.log('修改字幕成功!');
} catch(err) {
console.error('修改字幕出错:', err);
setTimeout(() => {
console.log('正在重试......');
changeSubtitle();
}, 1000);
}
}
function waitForSubtitleButton() {
const maxAttempts = 100; // 设置最大尝试次数
let attempts = 0;
interval = setInterval(function () {
attempts++;
if (attempts >= maxAttempts) {
console.log('尝试次数过多,停止轮询');
console.log('不存在中文字幕');
clearInterval(interval);
}
simulateMouseHoverToButton();
// 获取所有符合条件的元素
const subtitleElements = document.querySelectorAll('li.vp-video__control-bar--video-subtitles-select-item');
console.log(subtitleElements)
if (subtitleElements && subtitleElements.length > 0) {
// 遍历所有符合条件的元素
subtitleElements.forEach(element => {
console.log(element.textContent);
// 检查元素的文本内容是否为“中文字幕”
if (element.textContent.trim() === '中文字幕') {
clearInterval(interval); // 停止检测
console.log('检测到中文字幕,进行点击...');
element.click(); // 模拟点击操作
setTimeout(() => {
changeSubtitle();
}, 1000);
}
});
}
}, 2000);
}
function simulateMouseHoverToButton() {
// 获取需要悬停的按钮
const buttonElement = document.querySelector('.vp-video__control-bar--button.is-text');
console.log(buttonElement);
if (buttonElement) {
// 创建一个鼠标事件
const mouseOverEvent = new MouseEvent('mouseenter', {
view: window,
bubbles: true,
cancelable: true
});
// 触发鼠标悬停事件
buttonElement.dispatchEvent(mouseOverEvent);
console.log('鼠标悬停到按钮上');
setTimeout(() => {
// 创建一个鼠标移开事件
const mouseLeaveEvent = new MouseEvent('mouseleave', {
view: window,
bubbles: true,
cancelable: true
});
// 触发鼠标移开事件
buttonElement.dispatchEvent(mouseLeaveEvent);
console.log('鼠标移开按钮');
}, 500);
} else {
console.log('未找到需要悬停的按钮');
}
}
// 下载字幕
function clearResources() {
performance.clearResourceTimings();
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function retryOperation(operation, maxRetries = 3, delay = 1000) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (i === maxRetries - 1) throw error;
console.log(`尝试失败,${maxRetries - i - 1}次重试后重新尝试`);
await sleep(delay);
}
}
}
async function findSubtitleUrl() {
const resources = performance.getEntriesByType("resource");
let matchedUrls = resources.filter(resource => resource.name.includes('netdisk-subtitle'));
if (matchedUrls.length > 0) {
let url = matchedUrls[matchedUrls.length - 1].name;
console.log('找到匹配的URL:', url);
return url;
} else {
throw new Error('未找到匹配的URL');
}
}
async function downloadSubtitle() {
let button = document.querySelector('li.vp-video__control-bar--video-subtitles-select-item.is-checked');
clearResources(); // 清理资源
if (button.classList.contains('is-normal')) {
button = document.querySelector('ul.vp-video__control-bar--video-subtitles-select-group.is-large li:nth-child(2)');
}
button.click();
await sleep(500);
try {
const url = await retryOperation(findSubtitleUrl);
const regex = /fn=(.*)\.mp4/;
let fileName = decodeURIComponent(url.match(regex)[1]) + '.srt';
console.log(fileName);
// 使用 Fetch 获取字幕文件内容
const response = await fetch(url);
if (!response.ok) throw new Error('获取字幕文件失败');
const subtitleText = await response.text();
// 创建一个 Blob 对象用于下载
const blob = new Blob([subtitleText], { type: 'text/plain' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = fileName;
// 自动点击下载链接
link.click();
} catch (error) {
console.error('下载失败:', error);
}
}
function addDownloadButton() {
//const controlBar = document.querySelector("#vjs_video_594 > section > div.vp-video__control-bar--setup > div:nth-child(1) > div > div.vp-inner-vontainer > div > div.vp-video__control-bar--video-subtitles > div > ul");
const controlBar = document.querySelector('.vp-video-player .vp-video__control-bar .vp-video__control-bar--video-subtitles .vp-video__control-bar--video-subtitles-select .vp-video__control-bar--video-subtitles-select-group')
console.log(controlBar)
if (controlBar) {
let downloadButton = controlBar.querySelector('button.download-subtitle');
if (!downloadButton) {
console.log('创建字幕下载按钮!');
// 如果按钮不存在,则创建一个新的按钮
downloadButton = document.createElement('button');
downloadButton.className = 'download-subtitle'; // 添加类名方便识别
downloadButton.textContent = '下载字幕';
downloadButton.style.cssText = `
background-color: #4CAF50;
border: none;
color: white;
padding: 5px 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
`;
controlBar.appendChild(downloadButton);
console.log('创建成功!');
} else {
// 如果按钮已经存在,更新其文本和事件监听器
downloadButton.textContent = '下载字幕';
}
// 更新按钮的点击事件
downloadButton.removeEventListener('click', downloadSubtitle); // 移除旧的事件处理器
downloadButton.addEventListener('click', downloadSubtitle); // 添加新的事件处理器
return true;
}
return false;
}
function checkAddDownloadButton() {
const checkFunction = setInterval(() => {
if (addDownloadButton()) {
console.log("检测到下载按钮,停止轮询");
clearInterval(checkFunction); // 停止轮询
}
}, 500); // 每 500ms 检查一次
}
//(function observeDOM() {
// const observer = new MutationObserver((mutations, obs) => {
// if (addDownloadButton()) {
// console.log("检测到下载按钮,停止监听");
// obs.disconnect(); // 停止观察 DOM
// }
// });
//
// observer.observe(document.body, { childList: true, subtree: true });
//})();
}
})();