Fix file structure and video compatibility issues
ci/woodpecker/push/woodpecker Pipeline failed Details

This commit is contained in:
Leopere 2025-03-07 19:29:13 -05:00
parent 406cb488ad
commit 683d0efbec
5 changed files with 162 additions and 141 deletions

View File

@ -20,7 +20,7 @@
@tsFiles {
path *.ts
}
header @m3u8Files Content-Type "application/x-mpegURL"
header @m3u8Files Content-Type "application/vnd.apple.mpegurl"
header @tsFiles Content-Type "video/MP2T"
# Security headers

View File

@ -33,6 +33,11 @@ FROM git.nixc.us/colin/container-base:production-nixiusstatic
# Copy the built site from the first stage
COPY --from=hugo-builder /public /srv
# Ensure images and static files are properly available
COPY public/images /srv/images
COPY public/favicon.* /srv/
COPY public/static /srv/static
# Copy our enhanced Caddyfile for development
COPY Caddyfile.default.template /etc/caddy/Caddyfile.override

View File

@ -1,68 +1,71 @@
// Initialize videos when the DOM is fully loaded
/**
* Enhanced video.js initialization script
*
* This script handles video initialization across different browsers,
* properly supporting HLS playback with appropriate fallbacks.
*/
document.addEventListener('DOMContentLoaded', function() {
console.log('[VIDEOJS] Initialization starting...');
// Initialize video.js on all video elements with the video-js class
const videoElements = document.querySelectorAll('video.video-js');
if (typeof videojs === 'undefined') {
console.error('[VIDEOJS ERROR] VideoJS is not loaded!');
return;
}
// Hero video
try {
var heroVideo = videojs('video-hero-1741299175', {
html5: {
vhs: {
overrideNative: true
if (videoElements && videoElements.length > 0) {
console.log('Found ' + videoElements.length + ' video elements to initialize');
videoElements.forEach(function(videoElement) {
// Only initialize if not already initialized
if (!videoElement.classList.contains('vjs-has-started')) {
try {
// Get all source elements
const sourceElements = videoElement.querySelectorAll('source');
let hasHlsSource = false;
let hasOtherSource = false;
// Check for HLS sources
sourceElements.forEach(function(source) {
const type = source.getAttribute('type');
if (type === 'application/x-mpegurl' || type === 'application/vnd.apple.mpegurl') {
hasHlsSource = true;
} else {
hasOtherSource = true;
}
});
// Initialize with appropriate settings
const player = videojs(videoElement.id, {
fluid: true,
responsive: true,
html5: {
vhs: {
overrideNative: !videojs.browser.IS_SAFARI,
enableLowInitialPlaylist: true,
limitRenditionsByPlayerDimensions: true
},
nativeAudioTracks: videojs.browser.IS_SAFARI,
nativeVideoTracks: videojs.browser.IS_SAFARI
},
playbackRates: [0.75, 1, 1.25, 1.5, 2]
});
// Add HLS.js for non-Safari browsers
if (hasHlsSource && !videojs.browser.IS_SAFARI) {
console.log('Adding HLS support for ' + videoElement.id);
player.src({
src: sourceElements[0].src,
type: 'application/x-mpegurl'
});
}
// Improve compatibility with varying window sizes
player.on('play', function() {
player.fluid(true);
});
} catch (e) {
console.error('Error initializing video ' + videoElement.id + ':', e);
}
} else {
console.log('Video ' + videoElement.id + ' already initialized');
}
});
heroVideo.on('error', function() {
console.error('[VIDEOJS ERROR] Hero video error:', heroVideo.error());
});
console.log('[VIDEOJS] Hero video initialized');
} catch (e) {
console.error('[VIDEOJS ERROR] Failed to initialize hero video:', e);
}
// Video 2
try {
var video2 = videojs('video2', {
html5: {
vhs: {
overrideNative: true
}
}
});
video2.on('error', function() {
console.error('[VIDEOJS ERROR] Video2 error:', video2.error());
});
console.log('[VIDEOJS] Video2 initialized');
} catch (e) {
console.error('[VIDEOJS ERROR] Failed to initialize video2:', e);
}
// Video 3
try {
var video3 = videojs('video3', {
html5: {
vhs: {
overrideNative: true
}
}
});
video3.on('error', function() {
console.error('[VIDEOJS ERROR] Video3 error:', video3.error());
});
console.log('[VIDEOJS] Video3 initialized');
} catch (e) {
console.error('[VIDEOJS ERROR] Failed to initialize video3:', e);
}
console.log('[VIDEOJS] Initialization completed');
});

View File

@ -1,79 +1 @@
// Initialize videos when the DOM is fully loaded
document.addEventListener('DOMContentLoaded', function() {
console.log('[VIDEOJS] Initialization starting...');
if (typeof videojs === 'undefined') {
console.error('[VIDEOJS ERROR] VideoJS is not loaded!');
return;
}
// Helper function to configure and initialize a video player
function initializeVideoPlayer(elementId, options) {
try {
var defaultOptions = {
html5: {
vhs: {
overrideNative: true,
enableLowInitialPlaylist: true,
limitRenditionsByPlayerDimensions: true,
useBandwidthFromLocalStorage: true
},
nativeAudioTracks: false,
nativeVideoTracks: false
},
controlBar: {
pictureInPictureToggle: false
},
playbackRates: [0.75, 1, 1.25, 1.5, 2],
techOrder: ["html5"]
};
// Merge options
var mergedOptions = {};
for (var key in defaultOptions) {
mergedOptions[key] = defaultOptions[key];
}
for (var key in options || {}) {
mergedOptions[key] = options[key];
}
var player = videojs(elementId, mergedOptions);
// Fix MIME type issues in Chromium
var hlsSource = player.el().querySelector('source[type="application/x-mpegurl"], source[type="application/vnd.apple.mpegurl"]');
if (hlsSource) {
// Ensure consistent MIME type
hlsSource.type = 'application/x-mpegurl';
// Force HLS reload to ensure proper initialization
var currentSrc = hlsSource.src;
setTimeout(function() {
// Only reload if player hasn't started yet
if (!player.hasStarted_) {
player.src({
src: currentSrc,
type: 'application/x-mpegurl'
});
}
}, 100);
}
player.on('error', function() {
console.error('[VIDEOJS ERROR] Player "' + elementId + '" error:', player.error());
});
console.log('[VIDEOJS] Player "' + elementId + '" initialized');
return player;
} catch (e) {
console.error('[VIDEOJS ERROR] Failed to initialize player "' + elementId + '":', e);
return null;
}
}
// Initialize all videos
var heroVideo = initializeVideoPlayer('video-hero-1741299175');
var video2 = initializeVideoPlayer('video2');
var video3 = initializeVideoPlayer('video3');
console.log('[VIDEOJS] Initialization completed');
});
document.addEventListener("DOMContentLoaded",function(){const e=document.querySelectorAll("video.video-js");e&&e.length>0&&(console.log("Found "+e.length+" video elements to initialize"),e.forEach(function(e){if(e.classList.contains("vjs-has-started"))console.log("Video "+e.id+" already initialized");else try{const t=e.querySelectorAll("source");let r=!1,o=!1;t.forEach(function(e){const t=e.getAttribute("type");"application/x-mpegurl"!==t&&"application/vnd.apple.mpegurl"!==t?o=!0:r=!0});const i=videojs(e.id,{fluid:!0,responsive:!0,html5:{vhs:{overrideNative:!videojs.browser.IS_SAFARI,enableLowInitialPlaylist:!0,limitRenditionsByPlayerDimensions:!0},nativeAudioTracks:videojs.browser.IS_SAFARI,nativeVideoTracks:videojs.browser.IS_SAFARI},playbackRates:[.75,1,1.25,1.5,2]});r&&!videojs.browser.IS_SAFARI&&(console.log("Adding HLS support for "+e.id),i.src({src:t[0].src,type:"application/x-mpegurl"})),i.on("play",function(){i.fluid(!0)})}catch(t){console.error("Error initializing video "+e.id+":",t)}}))});

91
fix-video-types.js Executable file
View File

@ -0,0 +1,91 @@
#!/usr/bin/env node
/**
* Video MIME Type Fixer
*
* This script updates the HLS video source MIME types in HTML files
* to use the more widely supported "application/vnd.apple.mpegurl" type
* instead of "application/x-mpegurl".
*/
const fs = require('fs');
const path = require('path');
// Function to find all HTML files in a directory recursively
function findHtmlFiles(dir, fileList = []) {
const files = fs.readdirSync(dir);
files.forEach(file => {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
findHtmlFiles(filePath, fileList);
} else if (path.extname(file).toLowerCase() === '.html') {
fileList.push(filePath);
}
});
return fileList;
}
// Function to update HLS mime types in an HTML file
function updateHlsMimeTypes(filePath) {
try {
let html = fs.readFileSync(filePath, 'utf8');
const originalHtml = html;
// Update mime type for HLS streams
html = html.replace(/type=["']application\/x-mpegurl["']/gi, 'type="application/vnd.apple.mpegurl"');
// Add the script include for the fixed video initialization
if (!html.includes('video-init-fixed.min.js')) {
html = html.replace('</body>', '<script src="/js/video-init-fixed.min.js"></script></body>');
}
// Only write file if changes were made
if (html !== originalHtml) {
fs.writeFileSync(filePath, html);
console.log(`Updated: ${filePath}`);
return true;
} else {
console.log(`No changes needed: ${filePath}`);
return false;
}
} catch (err) {
console.error(`Error processing file ${filePath}: ${err.message}`);
return false;
}
}
// Main function
function main() {
if (process.argv.length < 3) {
console.error('Error: Please provide a directory path.');
process.exit(1);
}
const directoryPath = process.argv[2];
try {
console.log(`\nScanning directory: ${directoryPath}`);
const htmlFiles = findHtmlFiles(directoryPath);
console.log(`Found ${htmlFiles.length} HTML files.`);
let updatedCount = 0;
htmlFiles.forEach(filePath => {
if (updateHlsMimeTypes(filePath)) {
updatedCount++;
}
});
console.log(`\nUpdated ${updatedCount} of ${htmlFiles.length} HTML files.`);
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
}
}
main();