K2S Bitrate Display (Structure Fix)

Calculates bitrate by targeting the specific sibling structure of K2S metadata.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         K2S Bitrate Display (Structure Fix)
// @namespace    
// @version      5.0
// @description  Calculates bitrate by targeting the specific sibling structure of K2S metadata.
// @author       Gemini
// @license MIT
// @match        
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function parseDuration(timeStr) {
        if (!timeStr) return 0;
        const parts = timeStr.trim().split(':').map(Number);
        if (parts.length === 3) return (parts[0] * 3600) + (parts[1] * 60) + parts[2];
        if (parts.length === 2) return (parts[0] * 60) + parts[1];
        return 0;
    }

    function parseSize(sizeStr) {
        if (!sizeStr) return 0;
        // Matches "2.53 GB" or "855 MB"
        const match = sizeStr.match(/([\d\.]+)\s*(GB|MB|KB)/i);
        if (!match) return 0;

        let bits = parseFloat(match[1]);
        const unit = match[2].toUpperCase();

        if (unit === 'GB') bits *= 1073741824;
        else if (unit === 'MB') bits *= 1048576;
        else if (unit === 'KB') bits *= 1024;

        return bits * 8;
    }

    function run() {
        // 1. Find all elements that strictly contain the text "size" or "duration"
        // We use a broad selector but filter by exact text content to find the labels
        const allDivs = document.querySelectorAll('div[type="label"]');

        let sizeValueElement = null;
        let durationStr = null;

        // Iterate through all labels to find our targets
        allDivs.forEach(el => {
            const text = el.textContent.trim().toLowerCase();

            // A. Find the SIZE value
            if (text === 'size') {
                // The structure is: <div>Value</div> <div>Label</div>
                // So the value is the PREVIOUS sibling of the label
                const valueEl = el.previousElementSibling;
                if (valueEl) {
                    sizeValueElement = valueEl;
                }
            }

            // B. Find the DURATION value
            if (text === 'duration') {
                const valueEl = el.previousElementSibling;
                if (valueEl) {
                    durationStr = valueEl.textContent.trim();
                }
            }
        });

        // 2. If we found both and haven't processed this yet...
        if (sizeValueElement && durationStr && !sizeValueElement.dataset.bitrateAdded) {

            const seconds = parseDuration(durationStr);
            const bits = parseSize(sizeValueElement.textContent);

            if (seconds > 0 && bits > 0) {
                const mbps = ((bits / seconds) / 1000000).toFixed(2);

                // 3. Create the Badge
                const span = document.createElement('span');
                // Styling to match the dark theme, using the green accent color
                span.style.marginLeft = "8px";
                span.style.color = "#4caf50";
                span.style.fontWeight = "bold";
                span.innerText = `(${mbps} Mbps)`;

                // 4. Append inside the "2.53 GB" div
                sizeValueElement.appendChild(span);
                sizeValueElement.dataset.bitrateAdded = "true";
            }
        }
    }

    // Run repeatedly to handle dynamic loading (React/Vue)
    setInterval(run, 1000);

})();