Greasy Fork is available in English.
V6更新:二合一版。优先检测并自动跳过直播(精准防误判),非直播视频自动强制切换到最高画质 (4K/2K/1080P)。
// ==UserScript==
// @name 抖音优化: 强制最高画质+自动跳过直播
// @namespace http://tampermonkey.net/
// @version 6.0
// @description V6更新:二合一版。优先检测并自动跳过直播(精准防误判),非直播视频自动强制切换到最高画质 (4K/2K/1080P)。
// @author You
// @match https://www.douyin.com/*
// @match https://live.douyin.com/*
// @grant none
// @run-at document-idle
// @license All Rights Reserved
// ==/UserScript==
(function() {
'use strict';
// ==========================================
// 全局配置参数
// ==========================================
const MAIN_INTERVAL = 1000; // 主循环检测频率 (毫秒)
const SKIP_COOLDOWN = 1500; // 跳过直播后的冷却时间
const QUALITIES = ["超清 4K", "超清 2K", "高清 1080P"]; // 画质优先级
// ==========================================
// 全局状态变量
// ==========================================
// [直播跳过模块] 状态
let isSkipping = false;
// [画质调节模块] 状态
let lastVideoSrc = "";
let isQualityChecked = false;
// ==========================================
// 工具函数库 (混合)
// ==========================================
// 1. 模拟键盘按键 (用于跳过)
function simulateKeyDown() {
const event = new KeyboardEvent('keydown', {
key: 'ArrowDown', code: 'ArrowDown', keyCode: 40, which: 40,
bubbles: true, cancelable: true
});
document.dispatchEvent(event);
console.log('【抖音助手】执行跳过直播动作');
}
// 2. 判断元素是否在可视区域 (用于精准检测直播)
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
const windowHeight = (window.innerHeight || document.documentElement.clientHeight);
const windowWidth = (window.innerWidth || document.documentElement.clientWidth);
// 垂直方向在屏幕内,水平方向在左侧75%区域(避开评论)
return (rect.top >= 0 && rect.bottom <= windowHeight) && (rect.left < windowWidth * 0.75);
}
// 3. 提示框 Toast
function showToast(text) {
const div = document.createElement('div');
div.innerText = text;
div.style.position = 'fixed';
div.style.top = '10%'; div.style.left = '50%';
div.style.transform = 'translate(-50%, -50%)';
div.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
div.style.color = 'white'; div.style.padding = '8px 16px';
div.style.borderRadius = '20px'; div.style.zIndex = '99999';
div.style.fontSize = '14px'; div.style.pointerEvents = 'none';
div.style.transition = 'opacity 0.5s';
document.body.appendChild(div);
setTimeout(() => {
div.style.opacity = '0';
setTimeout(() => div.remove(), 500);
}, 1000);
}
// 4. 模拟指针事件 (用于点击画质菜单)
function triggerPointerEvent(element, eventType) {
if (!element) return;
const event = new PointerEvent(eventType, {
bubbles: true, cancelable: true, view: window,
pointerId: 1, width: 1, height: 1, isPrimary: true, pointerType: 'mouse'
});
element.dispatchEvent(event);
}
// 5. 查找分辨率按钮 (用于画质调节)
function findResolutionButton() {
const keywords = ["智能", "标清", "高清", "超清", "4K", "1080P", "720P"];
const tags = ['span', 'div'];
for (let tag of tags) {
const els = document.getElementsByTagName(tag);
for (let i = els.length - 1; i >= 0; i--) {
const el = els[i];
if (!el.innerText) continue;
const txt = el.innerText.trim();
if (keywords.some(k => txt.includes(k))) {
if (el.clientHeight > 10 && el.clientHeight < 50 && el.clientWidth < 150) {
return el;
}
}
}
}
return null;
}
// ==========================================
// 核心模块 A: 直播检测
// ==========================================
function checkLiveStream() {
if (isSkipping) return true; // 如果正在跳过冷却中,视为"处理中",阻止后续画质检测
const xpath = "//*[text()='直播中']";
const result = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < result.snapshotLength; i++) {
let element = result.snapshotItem(i);
if (isElementInViewport(element)) {
if (element.offsetParent === null) continue;
showToast("检测到直播,正在跳过...");
isSkipping = true;
simulateKeyDown();
// 冷却重置
setTimeout(() => { isSkipping = false; }, SKIP_COOLDOWN);
return true; // 返回 true 表示检测到了直播,需要阻断后续逻辑
}
}
return false; // 没有直播
}
// ==========================================
// 核心模块 B: 画质调节
// ==========================================
function checkVideoQuality() {
const video = document.querySelector('video');
if (!video) return;
// 1. 视频切换检测 (如果换了视频,重置画质检查状态)
if (video.src !== lastVideoSrc) {
console.log("[画质] 发现新视频,重置状态...");
lastVideoSrc = video.src;
isQualityChecked = false;
}
if (isQualityChecked) return;
// 2. 寻找清晰度入口
const triggerBtn = findResolutionButton();
if (!triggerBtn) return;
const currentText = triggerBtn.innerText;
// 3. 检查是否达标
if (currentText.includes("4K")) {
isQualityChecked = true;
return;
}
// 4. 执行操作 (模拟悬停)
triggerPointerEvent(triggerBtn, 'pointerover');
triggerPointerEvent(triggerBtn, 'pointerenter');
// 5. 延时点击菜单
setTimeout(() => {
let foundTarget = false;
for (let q of QUALITIES) {
if (currentText.includes(q)) {
foundTarget = true;
break;
}
const allDivs = document.querySelectorAll('div, span, p');
for (let node of allDivs) {
if (node.innerText === q && node !== triggerBtn) {
console.log(`[画质] 点击切换: ${q}`);
triggerPointerEvent(node, 'pointerdown');
triggerPointerEvent(node, 'mousedown');
triggerPointerEvent(node, 'pointerup');
triggerPointerEvent(node, 'mouseup');
node.click();
foundTarget = true;
// 收起菜单
triggerPointerEvent(triggerBtn, 'pointerout');
triggerPointerEvent(triggerBtn, 'pointerleave');
const player = document.querySelector('.xgplayer-container') || document.body;
triggerPointerEvent(player, 'pointermove');
break;
}
}
if (foundTarget) break;
}
if (foundTarget || !currentText.includes("智能")) {
isQualityChecked = true;
triggerPointerEvent(triggerBtn, 'pointerleave');
}
}, 300);
}
// ==========================================
// 主控制循环
// ==========================================
function masterLoop() {
// 第一步:优先检测是否为直播
const isLive = checkLiveStream();
// 如果检测到是直播(并且正在执行跳过),则直接结束本次循环
// 只有当 isLive 为 false (不是直播) 时,才去检查画质
if (!isLive) {
checkVideoQuality();
}
}
console.log('【抖音助手】二合一脚本已启动 (直播跳过 + 强力画质)');
setInterval(masterLoop, MAIN_INTERVAL);
})();