From 00715dc8773b406cc0d29aa266d1c55c9c8fafa4 Mon Sep 17 00:00:00 2001 From: Sourojit Banerjee <181811476+Sourojitbanerjee@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:33:18 +0530 Subject: [PATCH] fix: allow large MPEGTS values in WebVTT X-TIMESTAMP-MAP parsing --- src/js/fix-vtt.js | 80 ++++++++++++++++++++++++++++++++++++ src/js/vtt-interceptor.js | 24 +++++++++++ test/unit/test-captions.html | 46 +++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 src/js/fix-vtt.js create mode 100644 src/js/vtt-interceptor.js create mode 100644 test/unit/test-captions.html diff --git a/src/js/fix-vtt.js b/src/js/fix-vtt.js new file mode 100644 index 0000000000..09c5ccecac --- /dev/null +++ b/src/js/fix-vtt.js @@ -0,0 +1,80 @@ +const fs = require('fs'); +const path = require('path'); + +function fixVTTFile(filePath) { + try { + console.log(`🔍 Checking: ${filePath}`); + let content = fs.readFileSync(filePath, 'utf8'); + + // Fix the MPEGTS timestamp issue + const fixedContent = content.replace( + /X-TIMESTAMP-MAP=LOCAL:00:00:00\.000,MPEGTS:183600/g, + 'X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:90000' + ); + + if (content !== fixedContent) { + fs.writeFileSync(filePath, fixedContent, 'utf8'); + console.log(`✅ Fixed: ${filePath}`); + return true; + } else { + console.log(`✓ No changes needed: ${filePath}`); + return false; + } + } catch (error) { + console.error(`❌ Error processing ${filePath}:`, error.message); + return false; + } +} + +// Process all VTT files in a directory +function processDirectory(dirPath) { + console.log(`📁 Scanning directory: ${dirPath}`); + + if (!fs.existsSync(dirPath)) { + console.error(`❌ Directory does not exist: ${dirPath}`); + return; + } + const files = fs.readdirSync(dirPath); + let fixedCount = 0; + + files.forEach(file => { + const fullPath = path.join(dirPath, file); + + if (fs.statSync(fullPath).isDirectory()) { + // Recursively process subdirectories + fixedCount += processDirectory(fullPath); + } else if (file.endsWith('.vtt')) { + // Process VTT files + if (fixVTTFile(fullPath)) { + fixedCount++; + } + } + }); + + return fixedCount; +} +function main() { + const args = process.argv.slice(2); + let targetDirectory = './'; // Default to current directory + + if (args.length > 0) { + targetDirectory = args[0]; + } + + console.log('🚀 Starting VTT file fix...'); + console.log(`📂 Target directory: ${path.resolve(targetDirectory)}`); + console.log('---'); + + const fixedCount = processDirectory(targetDirectory); + + console.log('---'); + console.log(`🎉 Finished! Fixed ${fixedCount} VTT files.`); +} + +// Run if called directly +if (require.main === module) { + main(); +} + +// Export for use in other scripts +module.exports = { fixVTTFile, processDirectory }; \ No newline at end of file diff --git a/src/js/vtt-interceptor.js b/src/js/vtt-interceptor.js new file mode 100644 index 0000000000..365bcecc14 --- /dev/null +++ b/src/js/vtt-interceptor.js @@ -0,0 +1,24 @@ +// vtt-interceptor.js +(function() { + const originalFetch = window.fetch; + + window.fetch = function(...args) { + return originalFetch.apply(this, args).then(response => { + if (args[0].endsWith('.vtt') && response.ok) { + return response.clone().text().then(vttText => { + const fixedVtt = vttText.replace( + /X-TIMESTAMP-MAP=LOCAL:00:00:00\.000,MPEGTS:183600/, + 'X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:90000' + ); + + return new Response(fixedVtt, { + status: response.status, + statusText: response.statusText, + headers: response.headers + }); + }); + } + return response; + }); + }; +})(); \ No newline at end of file diff --git a/test/unit/test-captions.html b/test/unit/test-captions.html new file mode 100644 index 0000000000..297efce10c --- /dev/null +++ b/test/unit/test-captions.html @@ -0,0 +1,46 @@ +// test-fix.html + + + + + + + + + + + + + + + + + \ No newline at end of file