Revamp Video Player (Plans to drop Zorn)
This commit is contained in:
parent
9d44f96477
commit
05b5fd8ef9
12 changed files with 575 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "minpluto",
|
||||
"version": "2024.07.13",
|
||||
"version": "2024.07.26",
|
||||
"description": "An open source frontend alternative to YouTube.",
|
||||
"repository": "https://sudovanilla.org/MinPluto/MinPluto",
|
||||
"author": "Korbs <korbs@sudovanilla.org>",
|
||||
|
|
|
@ -91,9 +91,5 @@ if (Astro.url.href.match('watch')) {
|
|||
:
|
||||
null
|
||||
}
|
||||
<script src="https://cdn.jsdelivr.net/npm/pace-js@latest/pace.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pace-js@latest/pace-theme-default.min.css">
|
||||
</head>
|
||||
<Analytics/>
|
||||
|
||||
<script is:inline src="./assets/vendor/preline/preline.js"></script>
|
||||
<Analytics/>
|
37
src/components/video-player/Controls.astro
Normal file
37
src/components/video-player/Controls.astro
Normal file
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
import {
|
||||
Backward15Seconds,
|
||||
Enlarge,
|
||||
Forward15Seconds,
|
||||
PlaySolid,
|
||||
Settings,
|
||||
} from "@iconoir/vue";
|
||||
---
|
||||
<div class="video-controls">
|
||||
<div class="vc-top">
|
||||
<p>DJI: Landscape Footage of Cities</p>
|
||||
</div>
|
||||
<div class="vc-bottom">
|
||||
<div class="vc-start">
|
||||
<button id="vc-playpause"><PlaySolid /></button>
|
||||
<button id="vc-backwards"><Backward15Seconds /></button>
|
||||
<button id="vc-forwards"><Forward15Seconds /></button>
|
||||
</div>
|
||||
<div class="vc-center">
|
||||
<div class="vc-seek">
|
||||
<span class="vc-progress-bar"></span>
|
||||
<input class="seek" id="seek" value="0" min="0" type="range" step="1">
|
||||
</div>
|
||||
<p class="timestamp">
|
||||
<span class="seek-tooltip" id="seek-tooltip">00:00</span>
|
||||
<span id="current">00:00</span>
|
||||
<span id="duration">00:00</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="vc-end">
|
||||
<!-- <button id="vc-settings"><Settings /></button> -->
|
||||
<!-- <button><SoundHighSolid /></button> Should affect <audio>, not <video> -->
|
||||
<button id="vc-fullscreen"><Enlarge /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
21
src/components/video-player/Player.astro
Normal file
21
src/components/video-player/Player.astro
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
// Properties
|
||||
const { Poster, Source } = Astro.props
|
||||
|
||||
// Components
|
||||
import Controls from '@components/video-player/Controls.astro'
|
||||
|
||||
// Styles
|
||||
import '@styles/player.scss'
|
||||
---
|
||||
|
||||
<div class="video-container">
|
||||
<video class="main-video" muted autoplay loop src={Source} poster={Poster}></video>
|
||||
<audio class="main-audio" autoplay><source src={Source} type="audio/mp3"/></audio>
|
||||
<Controls/>
|
||||
</div>
|
||||
|
||||
<!-- Player Functions -->
|
||||
<script is:inline src="/player/controller.js"></script>
|
||||
<script is:inline src="/player/seek.js"></script>
|
||||
<script is:inline src="/player/sync.js"></script>
|
8
src/pages/vp.astro
Normal file
8
src/pages/vp.astro
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
import Base from "@layouts/Default.astro";
|
||||
import Player from "@components/video-player/Player.astro"
|
||||
---
|
||||
|
||||
<Base>
|
||||
<Player Source="/demo-purposes.mp4"/>
|
||||
</Base>
|
|
@ -9,6 +9,7 @@ import { Donate, Download, ShareIos, ThumbsUp, MediaVideo } from "@iconoir/vue";
|
|||
// Components
|
||||
import Dialog from '@components/Dialog.astro'
|
||||
import Video from '@components/VideoItem.astro'
|
||||
import Player from "@components/video-player/Player.astro";
|
||||
|
||||
// Fetch
|
||||
const SWV = Astro.url.href.split("watch?v=").pop();
|
||||
|
@ -71,17 +72,10 @@ if (EightK === true) { // 571
|
|||
|
||||
<Base Title={video.title}>
|
||||
<div class="video-container">
|
||||
<video
|
||||
class="zorn-player main-video"
|
||||
autoplay
|
||||
poster={DEFAULT_IMAGE_PROXY + '/https://i.ytimg.com/vi/' + video.videoId + '/maxresdefault.jpg'}
|
||||
video-title={video.title}
|
||||
src={DEFAULT_MEDIA_DATA_PROXY + '/latest_version?id=' + video.videoId + '&itag=' + Quality + '&local=true'}
|
||||
>
|
||||
</video>
|
||||
<audio class="main-audio">
|
||||
<source src={DEFAULT_MEDIA_PROXY + '/latest_version?id=' + video.videoId} type="audio/mp3">
|
||||
</audio>
|
||||
<Player
|
||||
Poster={DEFAULT_IMAGE_PROXY + '/https://i.ytimg.com/vi/' + video.videoId + '/maxresdefault.jpg'}
|
||||
Source={DEFAULT_MEDIA_DATA_PROXY + '/latest_version?id=' + video.videoId + '&itag=' + '137' + '&local=true'}
|
||||
/>
|
||||
</div>
|
||||
<div class="video-rea">
|
||||
<div class="rea-details">
|
||||
|
|
BIN
src/public/demo-purposes.mp4
Normal file
BIN
src/public/demo-purposes.mp4
Normal file
Binary file not shown.
193
src/public/player/controller.js
Normal file
193
src/public/player/controller.js
Normal file
|
@ -0,0 +1,193 @@
|
|||
var VideoContainer = document.querySelector('.video-container')
|
||||
var VideoControls = document.querySelector('.video-controls')
|
||||
var Player = document.querySelector('video')
|
||||
|
||||
// Icons
|
||||
var play_solid_default = '<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#ffffff" stroke-width="1.5"><path d="M6.90588 4.53682C6.50592 4.2998 6 4.58808 6 5.05299V18.947C6 19.4119 6.50592 19.7002 6.90588 19.4632L18.629 12.5162C19.0211 12.2838 19.0211 11.7162 18.629 11.4838L6.90588 4.53682Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>';
|
||||
var pause_solid_default = '<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#ffffff" stroke-width="1.5" data-darkreader-inline-color="" style="--darkreader-inline-color: #e8e6e3;"><path d="M6 18.4V5.6C6 5.26863 6.26863 5 6.6 5H9.4C9.73137 5 10 5.26863 10 5.6V18.4C10 18.7314 9.73137 19 9.4 19H6.6C6.26863 19 6 18.7314 6 18.4Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.5" data-darkreader-inline-fill="" data-darkreader-inline-stroke="" style="--darkreader-inline-fill: #ffffff; --darkreader-inline-stroke: #ffffff;"></path><path d="M14 18.4V5.6C14 5.26863 14.2686 5 14.6 5H17.4C17.7314 5 18 5.26863 18 5.6V18.4C18 18.7314 17.7314 19 17.4 19H14.6C14.2686 19 14 18.7314 14 18.4Z" fill="#ffffff" stroke="#ffffff" stroke-width="1.5" data-darkreader-inline-fill="" data-darkreader-inline-stroke="" style="--darkreader-inline-fill: #ffffff; --darkreader-inline-stroke: #ffffff;"></path></svg>';
|
||||
var PlayIcon = play_solid_default;
|
||||
var PauseIcon = pause_solid_default;
|
||||
|
||||
// Fullscreen
|
||||
function Fullscreen() {
|
||||
const Button_Fullscreen = document.getElementById("vc-fullscreen");
|
||||
function Toggle_Fullscreen() {
|
||||
if (document.fullscreenElement) {
|
||||
document.querySelector('.vc-top').style.opacity = '0'
|
||||
document.exitFullscreen();
|
||||
} else if (document.webkitFullscreenElement) {
|
||||
document.querySelector('.vc-top').style.opacity = '0'
|
||||
document.webkitExitFullscreen();
|
||||
} else if (VideoContainer.webkitRequestFullscreen) {
|
||||
document.querySelector('.vc-top').style.opacity = '1'
|
||||
VideoContainer.webkitRequestFullscreen();
|
||||
} else {
|
||||
document.querySelector('.vc-top').style.opacity = '1'
|
||||
VideoContainer.requestFullscreen();
|
||||
}
|
||||
}
|
||||
Button_Fullscreen.onclick = Toggle_Fullscreen;
|
||||
function Update_FullscreenButton() {
|
||||
if (document.fullscreenElement) {
|
||||
Button_Fullscreen.setAttribute("data-title", "Exit full screen (f)");
|
||||
} else {
|
||||
Button_Fullscreen.setAttribute("data-title", "Full screen (f)");
|
||||
}
|
||||
}
|
||||
Player.addEventListener("dblclick", () => {
|
||||
Toggle_Fullscreen()
|
||||
Update_FullscreenButton()
|
||||
});
|
||||
}
|
||||
|
||||
// Play/Pause
|
||||
function PlayPause() {
|
||||
const Button_PlayPause = document.querySelector(".video-controls #vc-playpause");
|
||||
Button_PlayPause.addEventListener("click", Toggle_PlayPause);
|
||||
Player.addEventListener("click", Toggle_PlayPause);
|
||||
Player.addEventListener("play", Update_PlayPauseButton);
|
||||
Player.addEventListener("pause", Update_PlayPauseButton);
|
||||
function Toggle_PlayPause() {
|
||||
if (Player.paused || Player.ended) {
|
||||
Player.play();
|
||||
} else {
|
||||
Player.pause();
|
||||
}
|
||||
}
|
||||
function Update_PlayPauseButton() {
|
||||
if (Player.paused) {
|
||||
Button_PlayPause.setAttribute("data-title", "Play (K)");
|
||||
Button_PlayPause.innerHTML = `${PlayIcon}`;
|
||||
} else {
|
||||
Button_PlayPause.setAttribute("data-title", "Pause (K)");
|
||||
Button_PlayPause.innerHTML = `${PauseIcon}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Skip Around
|
||||
function SkipAround() {
|
||||
const Button_SkipBack = document.querySelector(".video-controls #vc-backwards");
|
||||
const Button_SkipForth = document.querySelector(".video-controls #vc-forwards");
|
||||
Button_SkipBack.addEventListener("click", Toggle_SkipBack);
|
||||
Button_SkipForth.addEventListener("click", Toggle_SkipForth);
|
||||
function Toggle_SkipBack() {
|
||||
Skip(-10);
|
||||
}
|
||||
function Toggle_SkipForth() {
|
||||
Skip(10);
|
||||
}
|
||||
function Skip(value) {
|
||||
Player.currentTime += value;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide Controls
|
||||
function AutoToggleControls() {
|
||||
function Hide_Controls2() {
|
||||
if (Player.paused) {
|
||||
return;
|
||||
} else {
|
||||
document.querySelector(".video-controls").classList.add("hide");
|
||||
}
|
||||
}
|
||||
function Show_Controls2() {
|
||||
document.querySelector(".video-controls").classList.remove("hide");
|
||||
}
|
||||
VideoControls.addEventListener("mouseenter", Show_Controls2);
|
||||
VideoControls.addEventListener("mouseleave", Hide_Controls2);
|
||||
var mouseTimer = null, cursorVisible = true;
|
||||
function Hide_Cursor() {
|
||||
mouseTimer = null;
|
||||
VideoContainer.style.cursor = "none";
|
||||
cursorVisible = false;
|
||||
Hide_Controls2();
|
||||
}
|
||||
document.onmousemove = function () {
|
||||
if (mouseTimer) {
|
||||
window.clearTimeout(mouseTimer);
|
||||
Show_Controls2();
|
||||
}
|
||||
if (!cursorVisible) {
|
||||
VideoContainer.style.cursor = "default";
|
||||
cursorVisible = true;
|
||||
}
|
||||
mouseTimer = window.setTimeout(Hide_Cursor, 3200);
|
||||
};
|
||||
}
|
||||
|
||||
// Keyboard Shortcuts
|
||||
function KeyboardShortcuts(events) {
|
||||
if (Player.hasAttribute("keyboard-shortcut-fullscreen")) {
|
||||
var Fullscreen_KeyboardShortcut = Player.getAttribute("keyboard-shortcut-fullscreen");
|
||||
} else {
|
||||
var Fullscreen_KeyboardShortcut = "f";
|
||||
}
|
||||
if (Player.hasAttribute("keyboard-shortcut-mute")) {
|
||||
var Mute_KeyboardShortcut = Player.getAttribute("keyboard-shortcut-mute");
|
||||
} else {
|
||||
var Mute_KeyboardShortcut = "m";
|
||||
}
|
||||
if (Player.hasAttribute("keyboard-shortcut-playpause")) {
|
||||
var PlayPause_KeyboardShortcut = Player.getAttribute("keyboard-shortcut-playpause");
|
||||
} else {
|
||||
var PlayPause_KeyboardShortcut = "k";
|
||||
}
|
||||
if (Player.hasAttribute("keyboard-shortcut-skipback")) {
|
||||
var SkipBack_KeyboardShortcut = Player.getAttribute("keyboard-shortcut-skipback");
|
||||
} else {
|
||||
var SkipBack_KeyboardShortcut = "j";
|
||||
}
|
||||
if (Player.hasAttribute("keyboard-shortcut-skipforth")) {
|
||||
var SkipForth_KeyboardShortcut = Player.getAttribute("keyboard-shortcut-skipforth");
|
||||
} else {
|
||||
var SkipForth_KeyboardShortcut = "l";
|
||||
}
|
||||
function keyboardShortcuts(event) {
|
||||
const { key } = event;
|
||||
if (key === PlayPause_KeyboardShortcut) {
|
||||
if (Player.paused || Player.ended) {
|
||||
Player.play();
|
||||
} else {
|
||||
Player.pause();
|
||||
}
|
||||
if (Player.paused) {
|
||||
Show_Controls();
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
Hide_Controls();
|
||||
}, 1200);
|
||||
}
|
||||
} else if (key === Mute_KeyboardShortcut) {
|
||||
Player.muted = !Player.muted;
|
||||
if (Player.muted) {
|
||||
volume.setAttribute("data-volume", volume.value);
|
||||
volume.value = 0;
|
||||
} else {
|
||||
volume.value = volume.dataset.volume;
|
||||
}
|
||||
} else if (key === Fullscreen_KeyboardShortcut) {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.webkitFullscreenElement) {
|
||||
document.webkitExitFullscreen();
|
||||
} else if (VideoContainer.webkitRequestFullscreen) {
|
||||
VideoContainer.webkitRequestFullscreen();
|
||||
} else {
|
||||
VideoContainer.requestFullscreen();
|
||||
}
|
||||
} else if (key === SkipBack_KeyboardShortcut) {
|
||||
Player.currentTime += -10;
|
||||
} else if (key === SkipForth_KeyboardShortcut) {
|
||||
Player.currentTime += 10;
|
||||
}
|
||||
}
|
||||
document.addEventListener("keyup", keyboardShortcuts);
|
||||
}
|
||||
|
||||
// Init All Functions
|
||||
AutoToggleControls()
|
||||
Fullscreen()
|
||||
KeyboardShortcuts()
|
||||
PlayPause()
|
||||
SkipAround()
|
81
src/public/player/seek.js
Normal file
81
src/public/player/seek.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
function Seek() {
|
||||
var Player = document.querySelector('video')
|
||||
const timeElapsed = document.getElementById("current");
|
||||
const duration = document.getElementById("duration");
|
||||
function formatTime(timeInSeconds) {
|
||||
const result = new Date(timeInSeconds * 1e3)
|
||||
.toISOString()
|
||||
.substr(11, 8);
|
||||
return {
|
||||
minutes: result.substr(3, 2),
|
||||
seconds: result.substr(6, 2),
|
||||
};
|
||||
}
|
||||
function initializeVideo() {
|
||||
const videoDuration = Math.round(Player.duration);
|
||||
const time = formatTime(videoDuration);
|
||||
duration.innerText = `${time.minutes}:${time.seconds}`;
|
||||
duration.setAttribute(
|
||||
"datetime",
|
||||
`${time.minutes}m ${time.seconds}s`,
|
||||
);
|
||||
}
|
||||
Player.addEventListener("loadedmetadata", initializeVideo);
|
||||
function updateTimeElapsed() {
|
||||
const time = formatTime(Math.round(Player.currentTime));
|
||||
timeElapsed.innerText = `${time.minutes}:${time.seconds}`;
|
||||
timeElapsed.setAttribute(
|
||||
"datetime",
|
||||
`${time.minutes}m ${time.seconds}s`,
|
||||
);
|
||||
}
|
||||
Player.addEventListener("timeupdate", updateTimeElapsed);
|
||||
const progressBar = document.querySelector(".vc-progress-bar");
|
||||
const seek = document.getElementById("seek");
|
||||
function initializeVideo() {
|
||||
const videoDuration = Math.round(Player.duration);
|
||||
seek.setAttribute("max", videoDuration);
|
||||
progressBar.setAttribute("max", videoDuration);
|
||||
const time = formatTime(videoDuration);
|
||||
duration.innerText = `${time.minutes}:${time.seconds}`;
|
||||
duration.setAttribute(
|
||||
"datetime",
|
||||
`${time.minutes}m ${time.seconds}s`,
|
||||
);
|
||||
}
|
||||
function updateProgress() {
|
||||
seek.value = Math.floor(Player.currentTime);
|
||||
document.querySelector('.vc-progress-bar').style.width = Player.currentTime / Player.duration * 100 + '%'
|
||||
}
|
||||
Player.addEventListener("timeupdate", updateProgress);
|
||||
const seekTooltip = document.getElementById("seek-tooltip");
|
||||
function updateSeekTooltip(event) {
|
||||
const skipTo = Math.round(
|
||||
(event.offsetX / event.target.clientWidth) *
|
||||
parseInt(event.target.getAttribute("max"), 10),
|
||||
);
|
||||
seek.setAttribute("data-seek", skipTo);
|
||||
const t = formatTime(skipTo);
|
||||
seekTooltip.textContent = `${t.minutes}:${t.seconds}`;
|
||||
const rect = Player.getBoundingClientRect();
|
||||
seekTooltip.style.left = `${event.pageX - rect.left}px`;
|
||||
seekTooltip.style.opacity = '1'
|
||||
document.querySelector('.vc-progress-bar').style.width = Player.currentTime / Player.duration * 100 + '%'
|
||||
seek.addEventListener('mouseleave', () => {
|
||||
seekTooltip.style.opacity = '0'
|
||||
})
|
||||
}
|
||||
seek.addEventListener("mousemove", updateSeekTooltip);
|
||||
function skipAhead(event) {
|
||||
const skipTo = event.target.dataset.seek
|
||||
? event.target.dataset.seek
|
||||
: event.target.value;
|
||||
Player.currentTime = skipTo;
|
||||
progressBar.value = skipTo;
|
||||
seek.value = skipTo;
|
||||
}
|
||||
seek.addEventListener("input", skipAhead);
|
||||
|
||||
initializeVideo();
|
||||
}
|
||||
Seek();
|
64
src/public/player/sync.js
Normal file
64
src/public/player/sync.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
// https://gist.github.com/michancio/59b9f3dc54b3ff4f6a84
|
||||
// Find elements
|
||||
var SyncVideo = document.querySelector(".main-video");
|
||||
var SyncAudio = document.querySelector(".main-audio");
|
||||
|
||||
// Object for synchronization of multiple media/sources
|
||||
if (typeof window.MediaController === "function") {
|
||||
var controller = new MediaController();
|
||||
SyncVideo.controller = controller;
|
||||
SyncAudio.controller = controller;
|
||||
} else {
|
||||
controller = null;
|
||||
}
|
||||
|
||||
// Run SyncAudio and SyncVideo simultaneously
|
||||
SyncVideo.addEventListener(
|
||||
"play",
|
||||
function () {
|
||||
if (!controller && SyncAudio.paused) {
|
||||
SyncAudio.play();
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
// Pause/Play and Buffering
|
||||
SyncVideo.addEventListener("waiting", () => {
|
||||
// If SyncVideo is buffering
|
||||
SyncAudio.pause();
|
||||
});
|
||||
SyncVideo.addEventListener("playing", () => {
|
||||
// If SyncVideo is done buffering
|
||||
SyncAudio.play();
|
||||
SyncTimestamp();
|
||||
});
|
||||
|
||||
SyncVideo.addEventListener(
|
||||
"pause",
|
||||
function () {
|
||||
if (!controller && !SyncAudio.paused) {
|
||||
SyncAudio.pause();
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
// When Media Ends
|
||||
SyncVideo.addEventListener(
|
||||
"ended",
|
||||
function () {
|
||||
if (controller) {
|
||||
controller.pause();
|
||||
} else {
|
||||
SyncVideo.pause();
|
||||
SyncAudio.pause();
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
// Seekbar
|
||||
function SyncTimestamp() {
|
||||
SyncAudio.currentTime = SyncVideo.currentTime;
|
||||
}
|
163
src/styles/player.scss
Normal file
163
src/styles/player.scss
Normal file
|
@ -0,0 +1,163 @@
|
|||
.video-container {
|
||||
position: relative;
|
||||
*:focus {
|
||||
border: 2px white solid;
|
||||
transition: 1s border;
|
||||
}
|
||||
video {
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
.video-controls {
|
||||
background: linear-gradient(0deg, rgba(0,0,0,0.7523460067620799) 0%, rgba(0,0,0,0) 15%, rgba(0,0,0,0) 94%, rgba(0,0,0,0.7495448863139005) 100%);;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
width: calc(100% - 24px);
|
||||
padding: 12px;
|
||||
z-index: 5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
transition: 0.3s opacity;
|
||||
button {
|
||||
color: white;
|
||||
border-radius: 3rem;
|
||||
aspect-ratio: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
.vc-top {
|
||||
margin-top: 12px;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: 0.3s opacity;
|
||||
}
|
||||
.vc-bottom {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.vc-start,
|
||||
.vc-end {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.vc-center {
|
||||
width: calc(100% - 220px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
p {
|
||||
width: max-content;
|
||||
}
|
||||
}
|
||||
.vc-seek {
|
||||
background: rgb(255 255 255 / 10%);
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
position: relative;
|
||||
display: block;
|
||||
border-radius: 3rem;
|
||||
.vc-progress-bar {
|
||||
width: 1%;
|
||||
background: #ff274d;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
border-radius: 3rem;
|
||||
}
|
||||
input#seek {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
#seek[type="range"] {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
#seek[type="range"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
#seek[type="range"]::-webkit-slider-runnable-track {
|
||||
background-color: transparent;
|
||||
border-radius: 3rem;
|
||||
height: 1rem;
|
||||
}
|
||||
#seek[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
margin-top: -4px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 3rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
#seek[type="range"]:focus::-webkit-slider-thumb {
|
||||
outline: 3px solid #ffffff;
|
||||
outline-offset: 0.125rem;
|
||||
}
|
||||
#seek[type="range"]::-moz-range-track {
|
||||
background-color: transparent;
|
||||
border-radius: 3rem;
|
||||
height: 1rem;
|
||||
}
|
||||
#seek[type="range"]::-moz-range-thumb {
|
||||
background-color: #ffffff;
|
||||
border: none;
|
||||
border-radius: 3rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
#seek[type="range"]:focus::-moz-range-thumb{
|
||||
outline: 3px solid transparent;
|
||||
outline-offset: 0.125rem;
|
||||
}
|
||||
}
|
||||
.timestamp {
|
||||
display: flex;
|
||||
background: rgb(255 255 255 / 10%);
|
||||
border-radius: 3rem;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
#seek-tooltip {
|
||||
z-index: 10;
|
||||
background: #464646;
|
||||
padding: 6px 12px;
|
||||
border-radius: 3rem 0px 0px 3rem;
|
||||
margin-right: -64px;
|
||||
opacity: 0;
|
||||
transition: 0.3s opacity;
|
||||
}
|
||||
#current {
|
||||
background: rgb(255 255 255 / 15%);
|
||||
padding: 6px 12px;
|
||||
border-radius: 3rem 0px 0px 3rem;
|
||||
}
|
||||
#duration {
|
||||
padding: 6px 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.video-controls.hide {
|
||||
opacity: 0;
|
||||
transition: 0.3s opacity;
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
"@components/*": ["src/components/*"],
|
||||
"@layouts/*": ["src/layouts/*"],
|
||||
"@library/*": ["src/library/*"],
|
||||
"@player/*": ["src/components/video-player/*"],
|
||||
"@root/*": ["*"],
|
||||
"@styles/*": ["src/styles/*"],
|
||||
"@utils/*": ["src/utilities/*"]
|
||||
|
|
Reference in a new issue