Enhance media API transcoding and video streaming capabilities

- Added support for limiting concurrent transcoding operations in the media API to prevent resource exhaustion.
- Implemented functions to retrieve video duration and bitrate using ffprobe for improved streaming performance.
- Enhanced the generate_transcoded_stream function to handle HTTP range requests, allowing for more efficient video playback.
- Updated VideoModal component to disable fluid and responsive modes, ensuring proper container boundaries during video playback.
- Improved logging throughout the transcoding process for better error tracking and debugging.
This commit is contained in:
salirezav
2025-11-04 11:55:27 -05:00
parent de46753f15
commit 5070d9b2ca
15 changed files with 391 additions and 99 deletions

View File

@@ -23,8 +23,8 @@ export const VideoModal: React.FC<Props> = ({ fileId, onClose }) => {
controls: true,
autoplay: true,
preload: 'auto',
fluid: true,
responsive: true,
fluid: false, // Disable fluid mode to respect container boundaries
responsive: false, // Disable responsive mode to prevent overflow
playbackRates: [0.5, 1, 1.25, 1.5, 2],
sources: [
{
@@ -65,53 +65,75 @@ export const VideoModal: React.FC<Props> = ({ fileId, onClose }) => {
if (!fileId || !src) return null
return (
<div
className="fixed inset-0 z-[1000] bg-black/60 dark:bg-black/80 backdrop-blur-sm flex items-center justify-center p-4"
onClick={onClose}
>
<>
<style>{`
.video-modal-container .video-js {
width: 100% !important;
height: 100% !important;
max-width: 100% !important;
max-height: 100% !important;
}
.video-modal-container .video-js .vjs-tech {
width: 100% !important;
height: 100% !important;
object-fit: contain;
}
.video-modal-container .video-js .vjs-control-bar {
position: absolute !important;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
width: 100% !important;
}
`}</style>
<div
className="bg-white dark:bg-gray-800 rounded-lg shadow-2xl w-full max-w-4xl overflow-hidden transform transition-all relative"
onClick={(e: React.MouseEvent) => e.stopPropagation()}
className="fixed inset-0 z-[1000] bg-black/60 dark:bg-black/80 backdrop-blur-sm flex items-center justify-center p-4"
onClick={onClose}
>
{/* Close button - positioned absolutely in top right corner */}
<button
onClick={onClose}
className="absolute top-3 right-3 z-10 inline-flex items-center justify-center w-10 h-10 rounded-lg bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 border border-gray-300 dark:border-gray-600 shadow-md hover:bg-red-50 dark:hover:bg-red-900/20 hover:text-red-600 dark:hover:text-red-400 hover:border-red-300 dark:hover:border-red-700 transition-all duration-200"
aria-label="Close modal"
<div
className="video-modal-container bg-white dark:bg-gray-800 rounded-lg shadow-2xl w-full max-w-4xl max-h-[90vh] overflow-hidden transform transition-all relative flex flex-col"
onClick={(e: React.MouseEvent) => e.stopPropagation()}
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
{/* Close button - positioned absolutely in top right corner */}
<button
onClick={onClose}
className="absolute top-3 right-3 z-10 inline-flex items-center justify-center w-10 h-10 rounded-lg bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 border border-gray-300 dark:border-gray-600 shadow-md hover:bg-red-50 dark:hover:bg-red-900/20 hover:text-red-600 dark:hover:text-red-400 hover:border-red-300 dark:hover:border-red-700 transition-all duration-200"
aria-label="Close modal"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<div className="p-4 bg-gray-50 dark:bg-gray-900 border-b border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">Video Player</h3>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">Watch your recording</p>
<div className="p-4 bg-gray-50 dark:bg-gray-900 border-b border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">Video Player</h3>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">Watch your recording</p>
</div>
<a
href={`${BASE}/videos/stream?file_id=${encodeURIComponent(fileId)}`}
download={fileId.split('/').pop() || 'video.mp4'}
className="px-3 py-1.5 text-xs bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors"
onClick={(e) => e.stopPropagation()}
>
Download Video
</a>
</div>
<a
href={`${BASE}/videos/stream?file_id=${encodeURIComponent(fileId)}`}
download={fileId.split('/').pop() || 'video.mp4'}
className="px-3 py-1.5 text-xs bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors"
onClick={(e) => e.stopPropagation()}
>
Download Video
</a>
</div>
</div>
<div className="p-4 bg-black">
<div className="relative w-full" style={{ aspectRatio: '16/9', maxHeight: '70vh' }}>
<video
ref={videoRef}
className="video-js vjs-default-skin w-full h-full"
playsInline
key={fileId}
/>
<div className="flex-1 min-h-0 bg-black p-4 flex items-center justify-center">
<div className="relative w-full max-w-full max-h-full" style={{ aspectRatio: '16/9', maxHeight: 'calc(90vh - 200px)' }}>
<video
ref={videoRef}
className="video-js vjs-default-skin w-full h-full"
playsInline
key={fileId}
/>
</div>
</div>
</div>
</div>
</div>
</>
)
}