Greasy Fork is available in English.
禁止Sora探索页面的视频自动缓存和播放。仅当鼠标悬停在视频上时才加载并播放,移开则停止。已修复初始加载时的闪烁问题。
当前为
// ==UserScript==
// @name Sora2 禁止自动播放 Sora2 Hover to Play - Save Bandwidth & Stop Autoplay
// @namespace http://tampermonkey.net/
// @version 1.2.1
// @description 禁止Sora探索页面的视频自动缓存和播放。仅当鼠标悬停在视频上时才加载并播放,移开则停止。已修复初始加载时的闪烁问题。
// @author Your Name
// @match https://sora.chatgpt.com/explore
// @match https://sora.chatgpt.com/profile/*
// @match https://sora.chatgpt.com/profile
// @exclude https://sora.chatgpt.com/p/*
// @grant none
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
console.log('Sora Hover-to-Play 脚本 v1.2 已启动');
function processVideo(video) {
// 如果视频已经被处理过,就跳过
if (video.dataset.hoverPlayReady) {
return;
}
// 找到视频卡片的容器元素,通常是带有 "group" 类的 div
const container = video.closest('div.group');
if (!container) {
console.warn('未找到视频的悬停目标:', video);
return;
}
// --- 核心修复代码 ---
// 移除导致闪烁的动画类和背景色类
container.classList.remove('animate-pulse', 'bg-secondary/20');
// ------------------
// 1. 保存原始src并移除,以阻止预加载
if (video.src) {
video.dataset.originalSrc = video.src;
video.removeAttribute('src');
}
// 强制不预加载,并默认静音播放
video.preload = 'none';
video.muted = true;
// 2. 添加鼠标悬停事件监听
container.addEventListener('mouseenter', () => {
if (video.dataset.originalSrc && !video.getAttribute('src')) {
video.src = video.dataset.originalSrc;
video.play().catch(e => {
// 忽略浏览器可能报出的播放中断错误
});
}
});
// 3. 添加鼠标移开事件监听
container.addEventListener('mouseleave', () => {
video.pause();
video.removeAttribute('src'); // 移除src以停止缓冲并显示poster
video.load(); // 强制重新加载,确保poster显示出来
});
// 标记该视频已处理
video.dataset.hoverPlayReady = 'true';
}
// 初始化处理页面上已有的视频
function initAllVideos() {
document.querySelectorAll('video[poster]').forEach(processVideo);
}
// 使用MutationObserver来处理动态加载的视频
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes) {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1) { // 确保是元素节点
if (node.matches('video[poster]')) {
processVideo(node);
}
node.querySelectorAll('video[poster]').forEach(processVideo);
}
});
}
});
});
// 监听整个文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 页面加载完成后,先执行一次
initAllVideos();
})();