// ==UserScript==​ // @name 全页音频时长统计+跨页自动累计​ // @namespace http://tampermonkey.net/​ // @version 2.1​ // @description 当前页全部音频计时 + 翻页自动累加全局总时长,按钮布局优化无重叠​ // @author 豆包​ // @match *://labelx.alibaba-inc.com/*​ // @grant none​ // @run-at document-end​ // ==/UserScript==​ ​ (function () {​ 'use strict';​ console.log("✅ 全页音频时长统计+跨页累计 脚本已加载");​ ​ let panel;​ let isRunning = false;​ const STORAGE_KEY = "audio_total_all_time";​ ​ // 读取累计时长​ function getTotalAllTime() {​ const val = localStorage.getItem(STORAGE_KEY);​ return val ? parseFloat(val) : 0;​ }​ ​ // 保存累计时长​ function saveTotalAllTime(num) {​ localStorage.setItem(STORAGE_KEY, num.toFixed(2));​ }​ ​ // 清空全部累计​ function clearAllTotal() {​ saveTotalAllTime(0);​ alert("✅ 已清空跨页全部累计时长");​ updatePanelEmpty();​ }​ ​ // 秒转分秒​ function formatTime(s) {​ const m = Math.floor(s / 60);​ const sec = (s % 60).toFixed(2);​ return m > 0 ? ` ​ m分 {sec}秒` : `${sec}秒`;​ }​ ​ // 创建悬浮面板​ function createPanel() {​ if (panel) return;​ panel = document.createElement('div');​ panel.style.cssText = `​ position: fixed;​ top: 20px;​ left: 50%;​ transform: translateX(-50%);​ z-index: 9999999;​ background: rgba(255, 255, 255, 0.9);​ backdrop-filter: blur(8px);​ -webkit-backdrop-filter: blur(8px);​ padding: 20px 28px;​ border-radius: 16px;​ box-shadow: 0 4px 30px rgba(0,0,0,0.2);​ font-size: 16px;​ line-height: 1.7;​ min-width: 720px;​ max-height: 75vh;​ overflow-y: auto;​ color: #222;​ display: none;​ `;​ document.body.appendChild(panel);​ }​ ​ // 获取音频时长​ function getAudioDuration(audio) {​ if (!audio) return 0;​ return isNaN(audio.duration) || audio.duration === Infinity ? 0 : audio.duration;​ }​ ​ // 统一渲染顶部按钮(左关闭 / 右清空,完全不重叠)​ function renderTopBtn() {​ panel.innerHTML = "";​ ​ // 左侧:关闭按钮​ const closeBtn = document.createElement('div');​ closeBtn.innerText = '✕ 关闭';​ closeBtn.style.cssText = `​ position: absolute;​ top: 12px;​ left: 16px;​ cursor: pointer;​ color: #f53f3f;​ font-size: 16px;​ font-weight: bold;​ user-select: none;​ `;​ closeBtn.onclick = () => panel.style.display = 'none';​ ​ // 右侧:清空累计​ const clearBtn = document.createElement('div');​ clearBtn.innerText = '🗑️ 清空累计';​ clearBtn.style.cssText = `​ position: absolute;​ top: 12px;​ right: 16px;​ cursor: pointer;​ color: #666;​ font-size: 14px;​ user-select: none;​ `;​ clearBtn.onclick = clearAllTotal;​ ​ panel.appendChild(closeBtn);​ panel.appendChild(clearBtn);​ }​ ​ // 空白面板提示​ function updatePanelEmpty() {​ panel.style.display = 'block';​ renderTopBtn();​ const allTotal = getTotalAllTime();​ panel.insertAdjacentHTML('beforeend', `​
​ 点击音频条目开始统计
​ 全局跨页累计总时长:${formatTime(allTotal)}​
​ `);​ }​ ​ // 核心统计:当前页全部音频 + 跨页累加​ async function startStat() {​ if (isRunning) return;​ isRunning = true;​ panel.style.display = 'block';​ renderTopBtn();​ ​ panel.insertAdjacentHTML('beforeend', `​
⏳ 正在统计当前页全部音频...
​ `);​ ​ const items = document.querySelectorAll('.labelRender-item');​ const pageList = [];​ let pageTotal = 0;​ ​ for (const item of items) {​ const audio = item.querySelector('audio');​ if (!audio) continue;​ const dur = getAudioDuration(audio);​ if (dur <= 0) continue;​ const idEl = item.querySelector('div[data-has-bind="true"][style*="cursor: pointer"]');​ const idText = idEl?.textContent?.trim() || "无ID";​ pageList.push({ id: idText, dur });​ pageTotal += dur;​ }​ ​ // 跨页累加​ let allTotal = getTotalAllTime();​ allTotal += pageTotal;​ saveTotalAllTime(allTotal);​ ​ // 渲染明细​ let html = `
🎯 当前页全部音频明细
`;​ pageList.forEach((row, idx) => {​ html += `​
​ ​ idx+1. {row.id}​ ${formatTime(row.dur)}
​ `;​ });​ ​ html += `​
​ 📄 本页合计: ​ formatTime(pageTotal)( {pageTotal.toFixed(2)} 秒)​
​ 🌐 跨页全部累计:${formatTime(allTotal)}​
​ 累计总秒数:${allTotal.toFixed(2)} s​
​ `;​ ​ panel.innerHTML = "";​ renderTopBtn();​ panel.insertAdjacentHTML('beforeend', html);​ ​ console.log("✅ 本页时长:", pageTotal.toFixed(2), "全局累计:", allTotal.toFixed(2));​ isRunning = false;​ }​ ​ // 点击触发​ document.addEventListener('click', (e) => {​ if (e.target.closest('.labelRender-item')) {​ startStat();​ }​ });​ ​ // 初始化​ createPanel();​ updatePanelEmpty();​ })();​