Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions src/js/fix-vtt.js
Original file line number Diff line number Diff line change
@@ -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 };
24 changes: 24 additions & 0 deletions src/js/vtt-interceptor.js
Original file line number Diff line number Diff line change
@@ -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;
});
};
})();
46 changes: 46 additions & 0 deletions test/unit/test-captions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// test-fix.html
<!DOCTYPE html>
<html>
<head>
<link href="https://vjs.zencdn.net/8.0.4/video-js.css" rel="stylesheet" />
</head>
<body>
<video-js id="my-video" class="video-js" controls preload="auto" width="640" height="264">
<source src="https://course-dev.heysimon.com/asset/draft/7baab12c-3cbb-45f7-9047-f4635f6d8b0f/a9c44c80-fd57-4158-a3da-9c353b2cde7c/5d50b519-6335-4ed9-8284-3e46834aff43.m3u8" type="application/x-mpegURL">
</video-js>

<!-- Include your interceptors FIRST -->
<script src="vtt-interceptor.js"></script>
<script src="https://vjs.zencdn.net/8.0.4/video.min.js"></script>

<script>
const player = videojs('my-video');

player.ready(function() {
console.log('🎬 Player ready - testing captions...');

// Wait a bit then check if captions are available
setTimeout(() => {
const tracks = player.textTracks();
console.log('📝 Available text tracks:', tracks.length);

for (let i = 0; i < tracks.length; i++) {
const track = tracks[i];
console.log(`Track ${i}:`, track.label, track.language, track.kind);

// Try to enable English captions
if (track.language === 'en' || track.label === 'English') {
track.mode = 'showing';
console.log('✅ Enabled English captions');
}
}
}, 3000);
});

// Listen for errors
player.on('error', function() {
console.error('❌ Player error:', player.error());
});
</script>
</body>
</html>