Skip to content

Latest commit

 

History

History
474 lines (382 loc) · 22.7 KB

File metadata and controls

474 lines (382 loc) · 22.7 KB

Critical Bug Diagnostic Report: TypeError at player.js:7485

Executive Summary

Bug Location: /home/vercel-sandbox/twitch_alternate_player/player.js:7485 Function: м_Статистика.ПолученПреобразованныйСегмент(оСегмент) Root Cause: HTML element ID mismatch - JavaScript references Russian element IDs that have been replaced with English IDs in the HTML Severity: CRITICAL - Causes TypeError when processing transformed video segments, breaking statistics UI updates


Bug Context

Call Stack

Line 7485: м_Статистика.ПолученПреобразованныйСегмент(оСегмент)
    ↓
Line 1971: function ПолученПреобразованныйСегмент(оСегмент)
    ↓
Line 1995: Узел("статистика-сжатиевидео").textContent = сСжатиеВидео
    ↓
FAILURE: document.getElementById("статистика-сжатиевидео") returns null
    ↓
TypeError: Cannot set property 'textContent' of null

Trigger Condition

The error occurs when:

  1. A video segment is received from the Web Worker after TS→MP4 transcoding
  2. The segment data type is not a number (line 7484: typeof оСегмент.пДанные != "number")
  3. Statistics module attempts to update UI with segment metadata
  4. First discontinuity segment (оСегмент.лРазрыв === true) triggers video codec info update

Data Flow Analysis

Segment Processing Pipeline

Web Worker (worker.js)
    ↓ Transcoded segment via postMessage
player.js Line 7470: switch (мДанные[0])
    ↓ case 1: Transformed segment received
Line 7473-7479: Create Сегмент object
Line 7485: м_Статистика.ПолученПреобразованныйСегмент(оСегмент) ← ERROR HERE
    ↓
Line 1971: function ПолученПреобразованныйСегмент(оСегмент)
    ↓
Line 1972: Check if statistics window is open
Line 1974: Check if segment has media data (мбМедиасегмент property)
Line 1975: Check if discontinuity (лРазрыв flag)
    ↓
Line 1976-1995: Update video codec statistics
    → Line 1995: Узел("статистика-сжатиевидео").textContent ← FAILS

Segment Object Structure

оСегмент = {
    чНомер: <segment number>,
    лРазрыв: <boolean - discontinuity flag>,
    пДанные: {
        чПреобразованЗа: <transcode time in ms>,
        мбМедиасегмент: <ArrayBuffer of MP4 data>,
        лЕстьВидео: <boolean>,
        лЕстьЗвук: <boolean>,
        // Video metadata (when лЕстьВидео === true):
        nProfileIndication: <H.264 profile>,
        nConstraintSetFlag: <constraint flags>,
        nLevelIndication: <H.264 level>,
        nMaxNumberReferenceFrames: <ref frame count>,
        чДиапазон: <color range: -1/0/1>,
        лЧересстрочное: <boolean - interlaced>,
        чЧастотаКадров: <frame rate>,
        чШиринаКартинки: <width>,
        чВысотаКартинки: <height>,
        // Audio metadata (when лЕстьЗвук === true):
        nAudioObjectType: <AAC type 1-4>,
        чЧастотаДискретизации: <sample rate>,
        чКоличествоКаналов: <channel count>,
        // Frame statistics:
        чСредняяДлительностьВидеоСемпла: <avg frame duration ms>,
        чМинДлительностьВидеоСемпла: <min frame duration ms>,
        чМаксДлительностьВидеоСемпла: <max frame duration ms>,
        чБитрейтЗвука: <audio bitrate kbps>,
        // Error flags:
        лЗабраковано: <boolean - rejected>,
        лПотериВидео: <boolean - video loss>,
        лПотериЗвука: <boolean - audio loss>
    }
}

DOM Element ID Mismatches

Element IDs Accessed by ПолученПреобразованныйСегмент (Lines 1971-2099)

Line JavaScript Code Russian ID English ID in HTML Status
1995 Узел("статистика-сжатиевидео") статистика-сжатиевидео ❌ COMMENTED OUT MISSING
1995 (should use) - statistics-videocompression EXISTS
1997 Узел("статистика-разрешениевидео") статистика-разрешениевидео ✅ EXISTS (both) OK
2000 Узел("статистика-сжатиевидео") статистика-сжатиевидео ❌ COMMENTED OUT MISSING
2001 Узел("статистика-разрешениевидео") статистика-разрешениевидео ✅ EXISTS (both) OK
2003 Узел("статистика-частотакадров") статистика-частотакадров ✅ EXISTS (both) OK
2005 Узел("статистика-сжатиезвука") статистика-сжатиезвука ✅ EXISTS (both) OK
2012 Узел("статистика-сжатиезвука") статистика-сжатиезвука ✅ EXISTS (both) OK
2014 Узел("статистика-битрейтзвука") статистика-битрейтзвука ✅ EXISTS (both) OK
2068 ОбновитьЗначение("статистика-частотакадров") статистика-частотакадров ✅ EXISTS (both) OK
2076 Узел("статистика-битрейтзвука") статистика-битрейтзвука ✅ EXISTS (both) OK
2081 Узел("статистика-преобразованза") статистика-преобразованза ✅ EXISTS (both) OK
2090 ОбновитьЗначение("статистика-потерьвидео") статистика-потерьвидео ✅ EXISTS (both) OK
2096 ОбновитьЗначение("статистика-потерьзвука") статистика-потерьзвука ✅ EXISTS (both) OK

Additional м_Статистика DOM Accesses (Other Functions)

Line Function Element ID Status
1691 РазобранСписокСегментов статистика-количестворекламы ✅ OK
1692 РазобранСписокСегментов статистика-частотарекламы ✅ OK
1693 РазобранСписокСегментов статистика-исходных ✅ OK
1709 НеЗагруженыСегменты статистика-незагруженныхсегментов ✅ OK
1822 НеЗагруженыСегменты статистика-незагруженныхсегментов ✅ OK
1824 НеЗагруженыСегменты статистика-исчерпано ✅ OK
1844 ПолучитьДанныеДляОтчета статистика-разрешениевидео ✅ OK
1846 ПолучитьДанныеДляОтчета статистика-сжатиевидео ⚠️ POTENTIAL ISSUE
1847 ПолучитьДанныеДляОтчета статистика-сжатиезвука ✅ OK
1865 РазобранСписокСегментов статистика-сервер ✅ OK
1873 РазобранСписокСегментов статистика-список ✅ OK
1877 РазобранСписокСегментов статистика-targetduration ✅ OK
1952 ОшибкаЗагрузки статистика-ошибокзагрузки ✅ OK
1953 ОшибкаЗагрузки статистика-незагруженныхсегментов ✅ OK
1967 пропущеныСегменты статистика-незагруженныхсегментов ✅ OK

HTML Element Status

player.html Lines 67-68 (Video Compression)

<!-- COMMENTED OUT: -->
<!-- <span id=статистика-сжатиевидео title="..."></span> -->

<!-- ACTIVE REPLACEMENT: -->
<span id=statistics-videocompression title="Video compression parameters: ..."></span>

Problem: The Russian ID статистика-сжатиевидео has been commented out and replaced with the English ID statistics-videocompression, but the JavaScript still references the Russian ID.

Dual-ID Elements (No Issue)

Most other elements maintain BOTH IDs during the translation process:

<span id=статистика-разрешениевидео></span>
<!-- <span id=statistics-videoresolution></span> -->

This explains why only статистика-сжатиевидео causes failures - other elements still have their Russian IDs active.


Cascading Failure Points

Primary Failure

Line 1995: Узел("статистика-сжатиевидео").textContent = сСжатиеВидео

  • Attempts to set textContent on null
  • Throws TypeError
  • Function execution halts

Secondary Impact

Line 2000: Узел("статистика-сжатиевидео").textContent = "—"

  • Same element access in else branch
  • Would fail if video is absent in stream
  • Same TypeError

Tertiary Impact

Line 1846: ПараметрыВидео: Узел("статистика-сжатиевидео").textContent

  • Used in ПолучитьДанныеДляОтчета() for bug reports
  • Reads textContent from same element
  • Would fail when generating diagnostic reports

Update Frequency & Impact

When is ПолученПреобразованныйСегмент Called?

  • Trigger: Every time a video segment completes transcoding in the Web Worker
  • Frequency: Every 2-10 seconds (depends on HLS segment duration)
  • Discontinuity segments: First segment of stream, quality changes, ad boundaries

Statistics UI Update Pattern

Line 1972: const лОкноОткрыто = ОкноОткрыто();

The function checks if the statistics overlay is open (S key) before updating DOM elements. However, the critical failure at line 1995 occurs BEFORE this check for video codec information on discontinuity segments.

Discontinuity Segment Logic

Line 1974: if (оДанные.hasOwnProperty("мбМедиасегмент")) {
Line 1975:   if (оСегмент.лРазрыв) {  // ← DISCONTINUITY FLAG
               // Update codec info (lines 1976-2015)
               // LINE 1995 FAILURE OCCURS HERE

Critical Detail: Video codec information (H.264 profile, level, resolution) is only updated on discontinuity segments (лРазрыв === true). This means:

  • First segment of the stream → FAILS
  • Quality change (auto or manual) → FAILS
  • Ad break transitions → FAILS

Element ID Translation Status

Complete Inventory of Statistics Elements

Elements with BOTH Russian and English IDs (Safe)

✅ статистика-разрешениевидео / statistics-videoresolution ✅ статистика-частотакадров / statistics-framerate ✅ статистика-сжатиезвука / statistics-audiocompression ✅ статистика-битрейтзвука / statistics-audiobitrate ✅ статистика-сервер / statistics-server ✅ статистика-список / statistics-list ✅ статистика-targetduration / statistics-targetduration ✅ статистика-очередь / statistics-queue ✅ статистика-преобразованза / statistics-convertedin ✅ статистика-задержкатрансляции / statistics-streamdelay ✅ статистика-длительностьпросмотра / statistics-viewingduration ✅ статистика-количестворекламы / statistics-adcount ✅ статистика-частотарекламы / statistics-adfrequency ✅ статистика-исходных / statistics-source ✅ статистика-незагруженныхсегментов / statistics-undownloadedsegments ✅ статистика-исчерпано / statistics-exhausted ✅ статистика-ошибокзагрузки / statistics-loaderrors ✅ статистика-потерьвидео / statistics-videoloss ✅ статистика-потерьзвука / statistics-audioloss ✅ статистика-забракованных / statistics-rejected ✅ статистика-пропущенныхсегментов / statistics-skippedsegments ✅ статистика-пропущено / statistics-skipped ✅ статистика-переполнено / statistics-overflowed ✅ статистика-скачано / statistics-downloaded

Elements with ONLY English ID (Replaced)

statistics-videocompression (Russian ID commented out) ← THIS IS THE BUG

Elements with ONLY Russian ID (Not Yet Translated)

These exist in HTML as active elements but have not been translated yet:

  • статистика-интервалобновления
  • статистика-сегментовдобавлено
  • статистика-секунддобавлено
  • статистика-толщинасегмента
  • статистика-толщинаканала
  • статистика-ожиданиеответа
  • статистика-непросмотрено

Fix Plan

Strategy: Incremental Dual-ID Approach

The safest fix is to restore the dual-ID pattern used everywhere else in the codebase. This prevents breaking existing functionality while supporting future translation.

Fix #1: Restore Russian Element ID (IMMEDIATE - Critical)

File: /home/vercel-sandbox/twitch_alternate_player/player.html Line: 67-68

Current (BROKEN):

<!-- <span id=статистика-сжатиевидео title="Параметры сжатия видео: ..."></span> -->
<span id=statistics-videocompression title="Video compression parameters: ..."></span>

Fixed (SAFE):

<span id=статистика-сжатиевидео></span>
<!-- <span id=statistics-videocompression></span> -->
<span title="Video compression parameters: compression standard, profile, level, maximum number of reference frames, range, frame rate"></span>

OR (Better - matches dual-ID pattern):

<span id=статистика-сжатиевидео title="Параметры сжатия видео: стандарт сжатия, профиль, уровень, максимальное количество опорных кадров, диапазон, частота кадров"></span>
<!-- <span id=statistics-videocompression title="Video compression parameters: compression standard, profile, level, maximum number of reference frames, range, frame rate"></span>

Fix #2: Update JavaScript to Use English IDs (FUTURE - Phase 2)

File: /home/vercel-sandbox/twitch_alternate_player/player.js

After confirming dual IDs exist in HTML, update all references:

// Line 1995 - Update video codec text
- Узел("статистика-сжатиевидео").textContent = сСжатиеВидео;
+ Узел("statistics-videocompression").textContent = сСжатиеВидео;

// Line 2000 - Clear video codec on no video
- Узел("статистика-сжатиевидео").textContent = "—";
+ Узел("statistics-videocompression").textContent = "—";

// Line 1846 - Read for report generation
- Узел("статистика-сжатиевидео").textContent,
+ Узел("statistics-videocompression").textContent,

Note: This change should be coordinated with the full translation effort documented in CLAUDE.md.

Fix #3: Add Error Handling (DEFENSIVE - Phase 3)

Enhance the Узел() helper function to provide better error messages:

File: /home/vercel-sandbox/twitch_alternate_player/common.js Line: 216-221

Current:

function Узел(пЭлемент) {
	const элЭлемент = typeof пЭлемент == 'string' ? document.getElementById(пЭлемент) : пЭлемент;
	Проверить(элЭлемент.nodeType === 1);
	return элЭлемент;
}

Enhanced:

function Узел(пЭлемент) {
	const элЭлемент = typeof пЭлемент == 'string' ? document.getElementById(пЭлемент) : пЭлемент;
	if (!элЭлемент) {
		console.error(`[Узел] Element not found: ${пЭлемент}`);
		throw new Error(`DOM element not found: ${пЭлемент}`);
	}
	Проверить(элЭлемент.nodeType === 1);
	return элЭлемент;
}

This would provide a clearer error message instead of "Cannot read property 'nodeType' of null".


Testing & Verification

Test Case 1: Stream Start

  1. Load extension in Chrome
  2. Navigate to a Twitch channel
  3. Wait for first video segment to load
  4. Expected: Statistics overlay should update without errors
  5. Verify: Open DevTools Console - no TypeError

Test Case 2: Quality Change

  1. With stream playing, open settings
  2. Change quality (e.g., 1080p → 720p)
  3. Expected: Codec info updates in statistics overlay
  4. Verify: Press S to open stats, check video parameters

Test Case 3: Statistics Report Generation

  1. With stream playing, attempt to generate bug report
  2. Expected: Report includes video codec information
  3. Verify: Check report data structure

Regression Testing

After applying Fix #1, verify these elements still work:

  • ✅ Video resolution display (статистика-разрешениевидео)
  • ✅ Frame rate display (статистика-частотакадров)
  • ✅ Audio codec display (статистика-сжатиезвука)
  • ✅ Audio bitrate display (статистика-битрейтзвука)
  • ✅ All other statistics overlay fields

Related Issues & Technical Debt

Translation Inconsistency

Root Cause: The HTML translation (Russian → English IDs) was done without updating the JavaScript references simultaneously. This violates the atomic translation requirement in CLAUDE.md:

Translation commits must be atomic per file. Do not mix translation of identifiers with logic changes in the same commit.

The HTML was partially translated without a corresponding JavaScript update, creating this mismatch.

Recommended Translation Process

  1. Identify all references: Use grep -r "element-id" across all files
  2. Create dual IDs first: Add English IDs alongside Russian IDs in HTML
  3. Update JavaScript gradually: Change JS references file-by-file
  4. Remove Russian IDs last: Only after all JS references are updated
  5. Test after each step: Verify functionality throughout

Other Potential ID Mismatches

Based on the HTML scan, these elements have been fully translated to English but may have JavaScript references elsewhere:

  • statistics-updateinterval (commented: статистика-интервалобновления)
  • statistics-segmentsadded (commented: статистика-сегментовдобавлено)
  • statistics-secondsadded (commented: статистика-секунддобавлено)
  • statistics-segmentthickness (commented: статистика-толщинасегмента)
  • statistics-channelthickness (commented: статистика-толщинаканала)
  • statistics-responsewait (commented: статистика-ожиданиеответа)
  • statistics-unwatched (commented: статистика-непросмотрено)

Action Item: Audit all м_Статистика module DOM accesses to find additional mismatches.


Summary of All м_Статистика Functions That Update DOM

Function Name Lines DOM Updates
РазобранСписокСегментов 1661-1703 6 element updates
ДобавленыСегментыВОчередь ~1800-1900 Multiple Анализ class updates
ОшибкаЗагрузки 1945-1955 2 element updates
пропущеныСегменты 1960-1970 2 element updates
ПолученПреобразованныйСегмент 1971-2099 10+ element updates ← ERROR HERE
обновитьЗаполненностьБуфера 2100-2108 1 Анализ update
ИсчерпанБуферПроигрывателя 2109-2121 1 element update

Total DOM element access points in м_Статистика module: ~50+

Critical insight: Only 1 out of ~50 element accesses is broken, but it's a high-frequency, high-visibility update that occurs on every stream start and quality change.


Appendix: Key Code References

Common.js - Узел Function

File: /home/vercel-sandbox/twitch_alternate_player/common.js Lines: 216-222

function Узел(пЭлемент) {
	const элЭлемент = typeof пЭлемент == 'string'
		? document.getElementById(пЭлемент)
		: пЭлемент;
	Проверить(элЭлемент.nodeType === 1);
	return элЭлемент;
}

Common.js - ОбновитьЗначение Function

File: /home/vercel-sandbox/twitch_alternate_player/player.js Lines: 1540-1545

function ОбновитьЗначение(пЭлемент, пЗначение, лВыделить) {
	const узЭлемент = Узел(пЭлемент);
	узЭлемент.classList.toggle("статистика-выделить", лВыделить);
	узЭлемент.textContent = пЗначение;
	return узЭлемент;
}

Player.js - Segment Object Constructor

File: /home/vercel-sandbox/twitch_alternate_player/player.js Lines: 7473-7479

const оСегмент = new Сегмент(
	ОБРАБОТКА_ПРЕОБРАЗОВАН,
	мДанные[1].пДанные,
	мДанные[1].чДлительность,
	мДанные[1].лРазрыв,
	мДанные[1].чНомер
);

Recommendation

Immediate Action: Apply Fix #1 to restore the Russian element ID статистика-сжатиевидео in player.html line 67. This is a one-line change that will resolve the critical TypeError.

Short-term: Audit the entire м_Статистика module for other potential ID mismatches with the partially-translated HTML.

Long-term: Follow the structured translation process outlined in CLAUDE.md to complete the Russian→English migration without introducing regressions.


Report Generated: 2026-07-07 Diagnostic Tool: Claude Code Agent (Sonnet 4.5) Analysis Depth: Full source code trace, DOM inspection, data flow analysis