UNPKG

ipfs-hls-player

Version:

Video.js-based HLS player optimized for IPFS content-addressed storage

293 lines (250 loc) 6.48 kB
/** * IPFS HLS Player Styles * Video.js customizations and fixes for IPFS HLS content * * @author Mark Giles * @license MIT */ /* Fix black bar issue - remove margins from video element */ .ipfs-hls-player .vjs-tech { margin: 0 !important; top: 0 !important; left: 0 !important; position: absolute !important; width: 100% !important; height: 100% !important; } /* Ensure video expands properly in fullscreen regardless of inline styles */ .vjs-fullscreen .vjs-tech, .ipfs-hls-player.vjs-fullscreen .vjs-tech { max-width: none !important; max-height: none !important; width: 100% !important; height: 100% !important; } /* Ensure video container fills space properly and contains absolutely positioned elements */ .ipfs-hls-player { position: relative; width: 100%; aspect-ratio: 16/9; /* Provide proper aspect ratio for height reference */ height: auto; } .ipfs-hls-player .video-js { background-color: #000; width: 100% !important; height: 100% !important; position: absolute; top: 0; left: 0; } /* Fix poster and text track positioning */ .ipfs-hls-player .vjs-poster, .ipfs-hls-player .vjs-text-track-display { top: 0 !important; bottom: 0 !important; margin: 0 !important; } /* Dark Theme Customizations */ .ipfs-hls-player .vjs-control-bar { background: linear-gradient(to top, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.7)); height: 3em; } .ipfs-hls-player .vjs-button > .vjs-icon-placeholder:before { font-size: 1.8em; line-height: 1.67; } /* Quality Selector Menu Styles */ .vjs-menu-button-popup .vjs-menu ul { padding: 0 !important; margin: 0 !important; list-style: none !important; } .vjs-menu-button-popup .vjs-menu ul li { margin: 0 !important; } .vjs-quality-selector .vjs-menu-item { color: #adb5bd; padding: 0.5em 1em; } .vjs-quality-selector .vjs-menu-item:hover { background-color: rgba(255, 255, 255, 0.1); color: #fff; } .vjs-quality-selector .vjs-menu-item.vjs-selected { background-color: #007bff; color: #fff; } /* Big Play Button */ .vjs-big-play-button { background-color: rgba(17, 18, 34, 0.8) !important; border: 2px solid #007bff !important; border-radius: 50% !important; width: 80px !important; height: 80px !important; line-height: 80px !important; margin: -40px 0 0 -40px !important; } .vjs-big-play-button:hover { background-color: #007bff !important; border-color: #007bff !important; } /* Loading Spinner */ .vjs-loading-spinner { border-color: #007bff !important; } /* Progress Bar */ .vjs-play-progress { background-color: #007bff !important; } .vjs-load-progress { background-color: rgba(255, 255, 255, 0.3) !important; } .vjs-progress-control:hover .vjs-progress-holder { font-size: 1.2em; } /* Volume Bar */ .vjs-volume-level { background-color: #007bff; } /* Time Display */ .vjs-current-time, .vjs-duration, .vjs-time-divider { display: block; padding: 0 0.5em; } /* Fullscreen Button */ .vjs-fullscreen-control { position: absolute; right: 0; } /* Mobile Responsive */ @media (max-width: 768px) { .vjs-control-bar { height: 2.5em; } .vjs-button > .vjs-icon-placeholder:before { font-size: 1.5em; } .vjs-big-play-button { width: 60px !important; height: 60px !important; line-height: 60px !important; margin: -30px 0 0 -30px !important; } /* Hide some controls on mobile */ .vjs-playback-rate, .vjs-chapters-button { display: none; } } /* Ensure proper aspect ratio */ .ipfs-hls-player.vjs-fluid, .ipfs-hls-player.vjs-16-9, .ipfs-hls-player.vjs-4-3 { padding-top: 0 !important; } /* Fix for IPFS videos - ensure proper object-fit */ .ipfs-hls-player video[src*="ipfs"], .ipfs-hls-player video[src*="gateway"] { object-fit: contain; } /* Preemptive video initialization - prevent flash of unstyled video */ /* Target all videos that aren't enhanced yet or Video.js tech elements */ video:not([data-ipfs-enhanced="true"]):not([id$="_html5_api"]) { /* Establish proper size immediately */ width: 100%; aspect-ratio: 16/9; background-color: #000; object-fit: contain; /* Hide initially to prevent flash */ opacity: 0; visibility: hidden; /* Display block ensures consistent rendering */ display: block; } /* Container wrapper styles */ .ipfs-video-container { width: 100%; aspect-ratio: 16/9; background-color: #000; position: relative; overflow: hidden; } /* Enhanced player container - base styles inherited from .ipfs-video-container */ /* Native player sizing - proper letterboxing with object-fit */ .ipfs-native-player { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; height: 100%; object-fit: contain; /* Maintains aspect ratio with letterboxing */ background-color: #000; } /* Modal video styles */ .modal .ipfs-hls-player .video-js { max-height: 80vh; } /* Modal native player styles - prevent clipping */ .modal .ipfs-video-container.ipfs-hls-player { max-height: 80vh; aspect-ratio: 16/9; } .modal .ipfs-native-player { max-height: 100%; max-width: 100%; } /* Loading State Styles */ .ipfs-video-container.ipfs-video-loading video { visibility: hidden; opacity: 0; } /* Loading spinner */ .ipfs-video-container.ipfs-video-loading::before { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 40px; height: 40px; border: 4px solid rgba(255, 255, 255, 0.2); border-top-color: #007bff; border-radius: 50%; animation: ipfs-spinner 0.8s linear infinite; z-index: 10; } /* Spinner animation */ @keyframes ipfs-spinner { to { transform: translate(-50%, -50%) rotate(360deg); } } /* Ready state - smooth reveal */ .ipfs-video-container.ipfs-video-ready video { visibility: visible; opacity: 1; transition: opacity 0.3s ease-in-out; } /* Enhanced videos are always visible (unless in loading state) */ video[data-ipfs-enhanced="true"]:not(.ipfs-video-container.ipfs-video-loading video) { visibility: visible; opacity: 1; } /* Error state - show video anyway for fallback */ .ipfs-video-container.ipfs-video-error video { visibility: visible; opacity: 1; } /* Ensure Video.js players also respect loading states */ .ipfs-video-container.ipfs-video-loading .video-js { visibility: hidden; opacity: 0; } .ipfs-video-container.ipfs-video-ready .video-js { visibility: visible; opacity: 1; transition: opacity 0.3s ease-in-out; }