mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-05 23:18:53 -05:00
Compare commits
7 Commits
e6b5023b97
...
ca0dc29488
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca0dc29488 | ||
|
|
a4f0c742a0 | ||
|
|
6f3ed46413 | ||
|
|
178b5ed37c | ||
|
|
2a12fec89e | ||
|
|
55c701e055 | ||
|
|
40d13e8bd0 |
@ -3,14 +3,14 @@ WEBVTT
|
||||
NOTE
|
||||
Αυτό είναι ένα δείγμα υποτίτλων στα ελληνικά για το βίντεο των ωκεανών
|
||||
|
||||
00:00:00.000 --> 00:00:01.000
|
||||
00:00:00.000 --> 00:00:05.000
|
||||
Καλώς ήρθατε στον όμορφο κόσμο των ωκεανών
|
||||
|
||||
00:00:01.000 --> 00:00:02.000
|
||||
00:00:05.000 --> 00:00:09.000
|
||||
Αυτές οι τεράστιες υδάτινες εκτάσεις καλύπτουν το μεγαλύτερο μέρος του πλανήτη μας
|
||||
|
||||
00:00:02.000 --> 00:00:04.000
|
||||
00:00:09.000 --> 00:00:15.000
|
||||
Η θαλάσσια ζωή ανθίζει σε αυτά τα βαθιά γαλάζια νερά
|
||||
|
||||
00:00:05.000 --> 00:00:07.000
|
||||
00:00:15.000 --> 00:00:20.000
|
||||
Από το μικροσκοπικό πλαγκτόν μέχρι τις τεράστιες φάλαινες
|
||||
|
||||
|
Before Width: | Height: | Size: 695 KiB After Width: | Height: | Size: 695 KiB |
@ -110,9 +110,9 @@
|
||||
"480_playlist": "/media/hls/d393b72d279d4d0da70a484eb6b8b44f/media-6/stream.m3u8"
|
||||
},
|
||||
"license": null,
|
||||
"subtitles_info": [
|
||||
"__subtitles_info": [
|
||||
{
|
||||
"src": "/media/original/subtitles/user/markos/7e5aaed284954ae497d09783bf81004f.ExitofElygiaGorgeChaniaCrete.vtt",
|
||||
"src": "https://videojs.mediacms.io/media/original/subtitles/user/markos/7e5aaed284954ae497d09783bf81004f.ExitofElygiaGorgeChaniaCrete.vtt",
|
||||
"srclang": "en",
|
||||
"label": "English"
|
||||
}
|
||||
1158
frontend-tools/video-js/src/assets/sample-media-file.mp3.json
Normal file
1158
frontend-tools/video-js/src/assets/sample-media-file.mp3.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,17 @@ button {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
/* Adjust subtitle position when controls are visible */
|
||||
/* When controls are VISIBLE (user is active), add extra bottom margin */
|
||||
.video-js:not(.vjs-user-inactive) .vjs-text-track-display {
|
||||
margin-bottom: 2em; /* Adjust this value to move subtitles higher when controls are visible */
|
||||
}
|
||||
|
||||
/* When controls are HIDDEN (user is inactive), use default positioning */
|
||||
.video-js.vjs-user-inactive .vjs-text-track-display {
|
||||
margin-bottom: 0.5em; /* Smaller margin when controls are hidden */
|
||||
}
|
||||
|
||||
/* Center the fullscreen button inside its wrapper */
|
||||
/* @media (hover: hover) and (pointer: fine) {
|
||||
.vjs-fullscreen-control svg {
|
||||
@ -39,3 +50,59 @@ button {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* Prevent control bar buttons from overflowing */
|
||||
.video-js .vjs-control-bar {
|
||||
overflow: visible !important;
|
||||
display: flex !important;
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
/* Ensure control bar stays within bounds - only allow non-essential buttons to shrink */
|
||||
.video-js .vjs-control-bar .vjs-settings-button,
|
||||
.video-js .vjs-control-bar .vjs-chapters-button,
|
||||
.video-js .vjs-control-bar .vjs-subtitles-button,
|
||||
.video-js .vjs-control-bar .vjs-captions-button,
|
||||
.video-js .vjs-control-bar .vjs-subs-caps-button,
|
||||
.video-js .vjs-control-bar .vjs-autoplay-toggle,
|
||||
.video-js .vjs-control-bar .vjs-next-video-button {
|
||||
flex-shrink: 1 !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
/* Priority controls that should never shrink - maintain their size and spacing */
|
||||
.video-js .vjs-control-bar .vjs-play-control,
|
||||
.video-js .vjs-control-bar .vjs-volume-panel,
|
||||
.video-js .vjs-control-bar .vjs-fullscreen-control,
|
||||
.video-js .vjs-control-bar .vjs-picture-in-picture-toggle,
|
||||
.video-js .vjs-control-bar .custom-remaining-time {
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
/* Hide less important buttons on smaller screens */
|
||||
@media (max-width: 768px) {
|
||||
.video-js .vjs-control-bar .vjs-picture-in-picture-toggle {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.video-js .vjs-control-bar .vjs-autoplay-toggle {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.video-js .vjs-control-bar .vjs-next-video-button {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
/* Hide subtitles/captions button on very small screens - already available in settings */
|
||||
.video-js .vjs-control-bar .vjs-subtitles-button,
|
||||
.video-js .vjs-control-bar .vjs-captions-button,
|
||||
.video-js .vjs-control-bar .vjs-subs-caps-button {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,10 +29,10 @@ import KeyboardHandler from '../../utils/KeyboardHandler';
|
||||
import PlaybackEventHandler from '../../utils/PlaybackEventHandler';
|
||||
|
||||
// Import sample media data
|
||||
import sampleMediaData from '../../../public/sample-media-file.json';
|
||||
import sampleMediaData from '../../assets/sample-media-file.json';
|
||||
|
||||
// Import fallback poster image
|
||||
import audioPosterImg from '../../../public/audio-poster.jpg';
|
||||
import audioPosterImg from '../../assets/audio-poster.jpg';
|
||||
|
||||
// Function to enable tooltips for all standard VideoJS buttons
|
||||
const enableStandardButtonTooltips = (player) => {
|
||||
@ -1849,7 +1849,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
||||
src: '/sample-subtitles.vtt',
|
||||
srclang: 'en',
|
||||
label: 'English Subtitles',
|
||||
default: false,
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
kind: 'subtitles',
|
||||
@ -1870,7 +1870,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
||||
src: track.src,
|
||||
srclang: track.srclang,
|
||||
label: track.label,
|
||||
default: false,
|
||||
default: track.default || false,
|
||||
}))
|
||||
: [];
|
||||
|
||||
@ -2150,16 +2150,17 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
||||
nativeControlsForTouch: PlayerConfig.nativeControlsForTouch,
|
||||
|
||||
// Use native audio tracks instead of emulated - disabled for consistency
|
||||
nativeAudioTracks: true,
|
||||
nativeAudioTracks: false,
|
||||
|
||||
// Use native text tracks instead of emulated - disabled for consistency
|
||||
nativeTextTracks: true,
|
||||
// Use Video.js text tracks for full positioning control on mobile
|
||||
// Native tracks don't allow CSS positioning control
|
||||
nativeTextTracks: isTouchDevice,
|
||||
|
||||
// Use native video tracks instead of emulated - disabled for consistency
|
||||
nativeVideoTracks: true,
|
||||
nativeVideoTracks: false,
|
||||
|
||||
// Preload text tracks
|
||||
preloadTextTracks: true,
|
||||
preloadTextTracks: false,
|
||||
|
||||
// Play inline
|
||||
playsinline: true,
|
||||
@ -2189,9 +2190,28 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
||||
userPreferences.current.setupAutoSave(playerRef.current);
|
||||
|
||||
// Add class for audio files to enable audio-specific styling
|
||||
console.log('mediaData.media_type', mediaData.data?.media_type);
|
||||
if (mediaData.data?.media_type === 'audio') {
|
||||
playerRef.current.addClass('vjs-audio-type');
|
||||
|
||||
// For embed players, ensure poster stays visible during playback
|
||||
if (isEmbedPlayer) {
|
||||
const ensurePosterVisible = () => {
|
||||
const posterEl = playerRef.current.el().querySelector('.vjs-poster');
|
||||
if (posterEl) {
|
||||
posterEl.style.display = 'block';
|
||||
posterEl.style.opacity = '1';
|
||||
posterEl.style.visibility = 'visible';
|
||||
}
|
||||
};
|
||||
|
||||
// Keep poster visible on all play events
|
||||
playerRef.current.on('play', ensurePosterVisible);
|
||||
playerRef.current.on('playing', ensurePosterVisible);
|
||||
playerRef.current.on('timeupdate', ensurePosterVisible);
|
||||
|
||||
// Initial call
|
||||
setTimeout(ensurePosterVisible, 200);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable tooltips for all standard VideoJS buttons
|
||||
@ -3939,7 +3959,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
||||
</p>
|
||||
|
||||
{/* Add subtitle tracks */}
|
||||
{/* {subtitleTracks &&
|
||||
{subtitleTracks &&
|
||||
subtitleTracks.map((track, index) => (
|
||||
<track
|
||||
key={index}
|
||||
@ -3950,7 +3970,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
||||
default={track.default}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/*
|
||||
<track kind="chapters" src="/sample-chapters.vtt" /> */}
|
||||
{/* Add chapters track */}
|
||||
{/* {chaptersData &&
|
||||
|
||||
@ -18,6 +18,16 @@
|
||||
background-color: #000 !important;
|
||||
}
|
||||
|
||||
/* Keep poster visible even when playing for audio files */
|
||||
#page-embed .video-js-root-embed .video-js.vjs-audio-type .vjs-poster,
|
||||
#page-embed .video-js-root-embed .video-js.vjs-audio-poster-mode .vjs-poster,
|
||||
#page-embed .video-js-root-embed .video-js.vjs-has-started.vjs-audio-type .vjs-poster,
|
||||
#page-embed .video-js-root-embed .video-js.vjs-playing.vjs-audio-type .vjs-poster {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
/* Fullscreen video element - maintain aspect ratio */
|
||||
#page-embed .video-js-root-embed .video-js video {
|
||||
position: absolute !important;
|
||||
|
||||
@ -14,7 +14,6 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
root: path.resolve(__dirname, 'src'),
|
||||
publicDir: path.resolve(__dirname, 'public'),
|
||||
define: {
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'production'),
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user