Please bookmark this page to avoid losing your image tool!

YouTube Stats For Nerds Volume Normalization Analysis Tool

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, themeColor = "#ef4444") {
    // Determine dimensions to maintain proper aspect ratio and scaling
    const imgWidth = originalImg.width || 800;
    
    // Create the main wrapper container
    const container = document.createElement('div');
    container.style.width = imgWidth + 'px';
    container.style.maxWidth = '100%';
    container.style.boxSizing = 'border-box';
    container.style.position = 'relative';
    container.style.fontFamily = 'system-ui, -apple-system, sans-serif';
    container.style.margin = '0 auto';

    // Guard against unrenderable image objects
    if (originalImg.width === 0 || originalImg.height === 0) {
        container.innerHTML = `<p style="color:red; font-weight:bold;">Error: The provided image has zero width or height.</p>`;
        return container;
    }

    // Set up visualization Canvas
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    canvas.style.display = 'block';
    canvas.style.width = '100%';
    canvas.style.height = 'auto';
    canvas.style.borderRadius = '8px';
    canvas.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
    container.appendChild(canvas);

    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0);

    // Set up Status & Results Panel below the image
    const statusPanel = document.createElement('div');
    statusPanel.style.marginTop = '20px';
    statusPanel.style.background = '#f8f9fa';
    statusPanel.style.padding = '25px';
    statusPanel.style.borderRadius = '8px';
    statusPanel.style.border = '1px solid #e9ecef';
    statusPanel.style.transition = 'all 0.3s ease';
    
    statusPanel.innerHTML = `
        <div style="text-align:center;">
            <h3 style="margin:0 0 10px 0; font-size:18px; font-weight:600; color:#333;">Analyzing Stats for Nerds...</h3>
            <p id="tess-status" style="margin:0 0 15px 0; font-family:monospace; font-size:14px; color:#666;">Loading OCR Engine...</p>
            <div style="width:100%; max-width:300px; height:6px; background:#ddd; border-radius:3px; overflow:hidden; margin: 0 auto;">
                <div id="tess-progress" style="width:0%; height:100%; background:${themeColor}; transition:width 0.2s ease-out;"></div>
            </div>
        </div>
    `;
    container.appendChild(statusPanel);

    // Asynchronously perform OCR and analysis
    (async () => {
        try {
            // Dynamically load Tesseract.js if not available
            if (typeof Tesseract === 'undefined') {
                await new Promise((resolve, reject) => {
                    const script = document.createElement('script');
                    script.src = 'https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js';
                    script.onload = resolve;
                    script.onerror = () => reject(new Error("Failed to load OCR library. Check your network or CORS settings."));
                    document.head.appendChild(script);
                });
            }

            const statusEl = statusPanel.querySelector('#tess-status');
            const progressEl = statusPanel.querySelector('#tess-progress');

            // Start Text Recognition
            const result = await Tesseract.recognize(originalImg, 'eng', {
                logger: m => {
                    if (statusEl && progressEl) {
                        if (m.status) {
                            statusEl.innerText = m.status.charAt(0).toUpperCase() + m.status.slice(1) + '...';
                        }
                        if (m.progress) {
                            progressEl.style.width = Math.round(m.progress * 100) + '%';
                        }
                    }
                }
            });

            // Find line containing volume/loudness stats
            let targetLine = null;
            for (const line of result.data.lines) {
                const t = line.text.toLowerCase();
                // Common terms or representations found in Youtube's volume stats line
                if (t.includes('volume') || t.includes('normal') || t.includes('loudness') || t.includes('%') || t.includes('db')) {
                    // Make sure it looks like a stats line before confirming
                    if (t.includes('/') || t.includes('(')) {
                        targetLine = line;
                        break;
                    }
                }
            }

            if (!targetLine) {
                statusPanel.innerHTML = `
                    <div style="text-align:center; color:#b91c1c;">
                        <h3 style="margin:0 0 10px 0;">No Data Found</h3>
                        <p style="margin:0;">Could not locate Volume Normalization stats in this image. Please ensure it's a clear screenshot of 'Stats for nerds'.</p>
                    </div>
                `;
                return;
            }

            // --- Visualization (Highlighting the region) ---
            const padding = 6;
            const bbox = targetLine.bbox;
            
            // Dim the image
            ctx.fillStyle = 'rgba(0,0,0,0.65)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // Re-draw only the highlighted region
            const clearX = Math.max(0, bbox.x0 - padding);
            const clearY = Math.max(0, bbox.y0 - padding);
            const clearW = (bbox.x1 - bbox.x0) + padding * 2;
            const clearH = (bbox.y1 - bbox.y0) + padding * 2;

            ctx.clearRect(clearX, clearY, clearW, clearH);
            ctx.drawImage(originalImg, clearX, clearY, clearW, clearH, clearX, clearY, clearW, clearH);

            // Add highlight box
            ctx.strokeStyle = themeColor;
            ctx.lineWidth = 3;
            ctx.lineJoin = 'round';
            ctx.strokeRect(clearX, clearY, clearW, clearH);

            // --- Data Extraction & Parsing ---
            const textLine = targetLine.text.trim();
            
            let playerVol = "Unknown", normalizedVol = "Unknown", loudness = "Unknown";
            
            // Parse Volumes (e.g. 100% / 100%)
            const volMatch = textLine.match(/(\d+)\s*%.{1,5}?(\d+)\s*%/);
            if (volMatch) {
                playerVol = volMatch[1] + "%";
                normalizedVol = volMatch[2] + "%";
            }

            // Parse Loudness (Handle multiple formats like "content loudness 3.0dB" or "(-35.0dB/-14.0dB)")
            const loudMatch1 = textLine.match(/loudness\s*([+-]?[\d.]+)db/i);
            const multiMatch = [...textLine.matchAll(/\(([-0-9.]+)db\s*[\/|!1l]\s*([-0-9.]+)db\)/gi)];
            const loudMatch2 = textLine.match(/\(([-]?[0-9.]+)db/i); 
            
            if (loudMatch1) {
                loudness = loudMatch1[1] + " dB";
            } else if (multiMatch.length > 0) {
                loudness = multiMatch[0][1] + " dB"; // Takes the primary measured loudness
            } else if (loudMatch2) {
                loudness = loudMatch2[1] + " dB";
            }

            // Parse Codecs
            let codecs = [];
            if (/opus/i.test(textLine)) codecs.push("Opus");
            if (/ac3|ec-3/i.test(textLine)) codecs.push("AC3/E-AC3");
            if (/mp4a|aac/i.test(textLine)) codecs.push("AAC");
            if (/vorbis/i.test(textLine)) codecs.push("Vorbis");
            const codecStr = codecs.length > 0 ? codecs.join(", ") : "N/A";

            // Formulate intelligent explanation
            let explanation = 'If "Normalized" is 100%, YouTube isn\'t turning down the volume of the video.';
            const loudNum = parseFloat(loudness);
            if (!isNaN(loudNum)) {
                if (loudNum > 0) {
                    explanation = `This video's content loudness is <strong>${loudness}</strong> above YouTube's target (-14 LUFS). YouTube heavily reduces player volume to prevent it from being unexpectedly loud.`;
                } else if (loudNum < 0) {
                    explanation = `This video's content loudness is <strong>${Math.abs(loudNum)} dB</strong> below YouTube's normal target (-14 LUFS). YouTube does not dynamically boost quiet videos over 100%, so this video may sound quiet.`;
                } else {
                    explanation = `Perfect! This video's content loudness perfectly matches YouTube's target loudness (-14 LUFS). No volume reduction is required.`;
                }
            }

            // Update Panel UI
            statusPanel.style.background = '#ffffff';
            statusPanel.style.boxShadow = '0 6px 16px rgba(0,0,0,0.06)';
            statusPanel.style.border = 'none';
            statusPanel.style.borderLeft = `6px solid ${themeColor}`;
            
            const boxStyle = 'flex: 1; min-width: 140px; background: #f8f9fa; padding: 12px 16px; border-radius: 6px; border: 1px solid #e9ecef;';
            const labelStyle = 'font-size: 11px; color: #6c757d; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; margin-bottom: 5px;';
            const valueStyle = 'font-size: 22px; font-weight: 800; color: #212529;';

            statusPanel.innerHTML = `
                <h3 style="margin: 0 0 12px 0; font-size: 19px; font-weight: 700; color: #111;">Volume Normalization Analysis</h3>
                <div style="font-size: 14px; color: #495057; background: #f1f3f5; padding: 10px 14px; border-radius: 6px; font-family: monospace; overflow-wrap: break-word;">
                    ${textLine}
                </div>
                
                <div style="display: flex; flex-wrap: wrap; gap: 12px; margin-top: 20px;">
                    <div style="${boxStyle}">
                        <div style="${labelStyle}">Player Volume</div>
                        <div style="${valueStyle}">${playerVol}</div>
                    </div>
                    <div style="${boxStyle}">
                        <div style="${labelStyle}">Normalized</div>
                        <div style="${valueStyle}">${normalizedVol}</div>
                    </div>
                    <div style="${boxStyle}">
                        <div style="${labelStyle}">Loudness</div>
                        <div style="${valueStyle}">${loudness}</div>
                    </div>
                    <div style="${boxStyle}">
                        <div style="${labelStyle}">Codecs Detected</div>
                        <div style="${valueStyle}">${codecStr}</div>
                    </div>
                </div>
                
                <div style="margin-top: 20px; padding-top: 15px; border-top: 1px solid #dee2e6; font-size: 14.5px; line-height: 1.6; color: #343a40;">
                    <strong style="color: ${themeColor}">Insight:</strong> ${explanation}
                </div>
            `;

        } catch (err) {
            statusPanel.innerHTML = `
                <div style="text-align:center; color:#b91c1c;">
                    <h3 style="margin:0 0 10px 0;">Analysis Error</h3>
                    <p style="margin:0;">${err.message}</p>
                </div>
            `;
        }
    })();

    // The container is immediately returned to display the loading state while OCR resolves.
    return container;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

This tool analyzes screenshots of YouTube’s ‘Stats for Nerds’ overlay to extract and interpret volume normalization data. Using OCR (Optical Character Recognition) technology, it identifies key metrics such as player volume, normalized volume, loudness levels (in dB), and detected audio codecs. The tool provides a visual highlight of the detected data and offers an intelligent insight explaining how the video’s loudness compares to YouTube’s target levels. This is useful for video editors, content creators, and audio enthusiasts who want to understand how YouTube is processing their audio and whether a video is being dynamically adjusted for volume.

Leave a Reply

Your email address will not be published. Required fields are marked *

Other Image Tools:

YouTube Stats For Nerds Audio Volume Normalization Information Display

YouTube Stats For Nerds Volume Normalization Information Tool

YouTube Stats For Nerds Audio Volume and Codec Information Extractor

YouTube Audio Stats Volume Normalization Tool for Mp2 Mp3 Opus and Ac3

Audio Volume Normalizer for Mp2 Mp3 Opus and Ac3 Formats

YouTube Audio Stats Volume Normalizer For Mp2 Mp3 Opus and Ac3 Formats

United States of America Federal Social Security Card Template Maker

Ukrainian Dub Master Video Voice Actor Information Tool

Ukrainian Dubbed Video Voice Actor Information Tool

YouTube Stats For Nerds Volume Normalizer for Opus and Ac3 Audio

YouTube Audio Volume Normalization Tool for Opus and Ac3 Formats

YouTube Stats For Nerds Volume Normalization Tool

YouTube Video Image and Metadata Stats For Nerds Tool

YouTube Video Image and Stats For Nerds Viewer

Image To I Killed X Losky Effect Color Filter Converter

YouTube Video Photo and Stats Viewer

Image To G Major 16 Color Filter Converter

YouTube Video Photo and Image Stats For Nerds Tool

Image To Scalable Kaomoji Converter With Decorative Symbols

Kingdom Hearts SVTFOE Gameplay Image Viewer

Kingdom Hearts SVTFOE Gameplay Video Player

Image To Video Content Description Tool

Big Hero 6 2014 Tubi TV June 30 2027 Video Screenshot

No tool description provided

Big Hero 6 2014 Tubi Jun 30 2027 Photo

San Diego Comic-Con Image Gallery

Movie Studio Intro YTP Collab Style Image Maker

Movie Studio Music Fanfare Logo Maker

Movie Studio Music Fanfare Logo Generator

Kurdish Dubbing Audio to Image Visualizer Tool

Kurdish Dubbed Audio Video Tool

Kurdish Dub Audio to Image Converter

Kurdish Dub Audio Overlay Tool

Warner Bros Discovery Animation Studio Divisions Image Viewer

Image To Character Voice Actor Idea Generator

Image To Character Voice Actor Suggestion Tool

See All →