video implementation
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user