video implementation

This commit is contained in:
overcuriousity
2025-08-12 21:02:52 +02:00
parent 0e3d654a58
commit b291492e2d
8 changed files with 104 additions and 684 deletions

View File

@@ -1,139 +1,41 @@
---
// src/components/Video.astro - SIMPLIFIED using consolidated videoProcessor
import { videoProcessor, type VideoMetadata } from '../utils/videoUtils.js';
// src/components/Video.astro - SIMPLE wrapper component
export interface Props {
src: string;
title?: string;
description?: string;
controls?: boolean;
autoplay?: boolean;
muted?: boolean;
loop?: boolean;
preload?: 'none' | 'metadata' | 'auto';
aspectRatio?: '16:9' | '4:3' | '1:1';
showMetadata?: boolean;
poster?: string;
width?: string;
height?: string;
fallback?: string;
}
const {
src,
title,
description,
title = 'Video',
controls = true,
autoplay = false,
muted = false,
loop = false,
preload = 'metadata',
aspectRatio = '16:9',
showMetadata = true,
poster,
width,
height,
fallback
aspectRatio = '16:9'
} = Astro.props;
// SIMPLIFIED: Use consolidated videoProcessor
const metadata: Partial<VideoMetadata> = {
title,
description,
poster
};
const options = {
controls,
autoplay,
muted,
loop,
preload,
aspectRatio,
showMetadata,
width,
height
};
let videoHTML = '';
try {
const processedVideo = await videoProcessor.processVideoUrl(src, metadata);
videoHTML = videoProcessor.generateVideoHTML(processedVideo, options);
} catch (error) {
console.error('[VIDEO COMPONENT] Processing failed:', error);
videoHTML = `
<div class="video-container aspect-${aspectRatio}">
<div class="video-error">
<div class="error-icon">⚠️</div>
<div>${fallback || `Video could not be loaded: ${error.message}`}</div>
</div>
</div>
`;
}
---
<Fragment set:html={videoHTML} />
<script>
// CONSOLIDATED: Client-side video enhancement
document.addEventListener('DOMContentLoaded', () => {
const videos = document.querySelectorAll('.video-container video') as NodeListOf<HTMLVideoElement>;
videos.forEach((video: HTMLVideoElement) => {
const container = video.closest('.video-container') as HTMLElement;
if (!container) return;
// Loading states
video.addEventListener('loadstart', () => container.classList.add('loading'));
video.addEventListener('loadeddata', () => {
container.classList.remove('loading');
container.classList.add('loaded');
});
// Error handling
video.addEventListener('error', (e) => {
console.error('[VIDEO] Load error:', e);
container.classList.remove('loading');
container.classList.add('error');
const errorDiv = document.createElement('div');
errorDiv.className = 'video-error';
errorDiv.innerHTML = `
<div class="error-icon">⚠️</div>
<div>Video could not be loaded</div>
`;
video.style.display = 'none';
container.appendChild(errorDiv);
});
// Fullscreen on double-click
video.addEventListener('dblclick', () => {
if (video.requestFullscreen) {
video.requestFullscreen();
} else if ((video as any).webkitRequestFullscreen) {
(video as any).webkitRequestFullscreen();
}
});
// Keyboard shortcuts
video.addEventListener('keydown', (e: KeyboardEvent) => {
switch(e.key) {
case ' ':
e.preventDefault();
video.paused ? video.play() : video.pause();
break;
case 'f':
e.preventDefault();
if (video.requestFullscreen) video.requestFullscreen();
break;
case 'm':
e.preventDefault();
video.muted = !video.muted;
break;
}
});
});
});
</script>
<div class={`video-container aspect-${aspectRatio}`}>
<video
src={src}
controls={controls}
autoplay={autoplay}
muted={muted}
loop={loop}
style="width: 100%; height: 100%;"
data-video-title={title}
>
<p>Your browser does not support the video element.</p>
</video>
{title !== 'Video' && (
<div class="video-metadata">
<div class="video-title">{title}</div>
</div>
)}
</div>