Compare commits
7 commits
97ee8b20f4
...
eede28cabe
Author | SHA1 | Date | |
---|---|---|---|
|
eede28cabe | ||
|
c7c91eec29 | ||
|
61a0c5717a | ||
|
164b4a4c48 | ||
|
af9028db95 | ||
|
16be696f91 | ||
|
53ac2d61c0 |
7 changed files with 88 additions and 87 deletions
6
TODO.md
6
TODO.md
|
@ -8,6 +8,12 @@
|
|||
- [ ] Mobile Gestures
|
||||
- [ ] Cast Support
|
||||
- [ ] Allow for multiple players on one page
|
||||
- [ ] 360 Video Support
|
||||
- [ ] Milieu Settings
|
||||
- [ ] Mode (Default | Fullscreen)
|
||||
- [ ] Speed (Default | Instant | Slow)
|
||||
- [ ] Blur
|
||||
- [ ] Scale
|
||||
- [ ] Modes
|
||||
- [ ] Audio-Only
|
||||
- [ ] Pop-Up
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GNU GPL) as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option)
|
||||
* any later version. The code is distributed WITHOUT ANY WARRANTY;
|
||||
* any later version. The code is distributed WITHOUT ANY WARRANTY
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
||||
*
|
||||
|
@ -26,83 +26,83 @@
|
|||
*/
|
||||
function Seek() {
|
||||
var Player = document.querySelector('video')
|
||||
const timeElapsed = document.getElementById("current");
|
||||
const duration = document.getElementById("duration");
|
||||
const timeElapsed = document.getElementById("current")
|
||||
const duration = document.getElementById("duration")
|
||||
function formatTime(timeInSeconds) {
|
||||
const result = new Date(timeInSeconds * 1e3)
|
||||
.toISOString()
|
||||
.substr(11, 8);
|
||||
.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}`;
|
||||
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);
|
||||
Player.addEventListener("loadedmetadata", initializeVideo)
|
||||
function updateTimeElapsed() {
|
||||
const time = formatTime(Math.round(Player.currentTime));
|
||||
timeElapsed.innerText = `${time.minutes}:${time.seconds}`;
|
||||
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");
|
||||
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}`;
|
||||
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);
|
||||
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");
|
||||
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`;
|
||||
)
|
||||
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);
|
||||
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;
|
||||
: event.target.value
|
||||
Player.currentTime = skipTo
|
||||
progressBar.value = skipTo
|
||||
seek.value = skipTo
|
||||
}
|
||||
seek.addEventListener("input", skipAhead);
|
||||
seek.addEventListener("input", skipAhead)
|
||||
|
||||
initializeVideo();
|
||||
initializeVideo()
|
||||
}
|
||||
Seek();
|
||||
Seek()
|
||||
</script>
|
|
@ -27,16 +27,16 @@
|
|||
*/
|
||||
// https://gist.github.com/michancio/59b9f3dc54b3ff4f6a84
|
||||
// Find elements
|
||||
var SyncVideo = document.querySelector(".main-video");
|
||||
var SyncAudio = document.querySelector(".main-audio");
|
||||
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;
|
||||
var controller = new MediaController()
|
||||
SyncVideo.controller = controller
|
||||
SyncAudio.controller = controller
|
||||
} else {
|
||||
controller = null;
|
||||
controller = null
|
||||
}
|
||||
|
||||
// Run SyncAudio and SyncVideo simultaneously
|
||||
|
@ -44,49 +44,49 @@ SyncVideo.addEventListener(
|
|||
"play",
|
||||
function () {
|
||||
if (!controller && SyncAudio.paused) {
|
||||
SyncAudio.play();
|
||||
SyncAudio.play()
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
)
|
||||
|
||||
// Pause/Play and Buffering
|
||||
SyncVideo.addEventListener("waiting", () => {
|
||||
// If SyncVideo is buffering
|
||||
SyncAudio.pause();
|
||||
});
|
||||
SyncAudio.pause()
|
||||
})
|
||||
SyncVideo.addEventListener("playing", () => {
|
||||
// If SyncVideo is done buffering
|
||||
SyncAudio.play();
|
||||
SyncTimestamp();
|
||||
});
|
||||
SyncAudio.play()
|
||||
SyncTimestamp()
|
||||
})
|
||||
|
||||
SyncVideo.addEventListener(
|
||||
"pause",
|
||||
function () {
|
||||
if (!controller && !SyncAudio.paused) {
|
||||
SyncAudio.pause();
|
||||
SyncAudio.pause()
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
)
|
||||
|
||||
// When Media Ends
|
||||
SyncVideo.addEventListener(
|
||||
"ended",
|
||||
function () {
|
||||
if (controller) {
|
||||
controller.pause();
|
||||
controller.pause()
|
||||
} else {
|
||||
SyncVideo.pause();
|
||||
SyncAudio.pause();
|
||||
SyncVideo.pause()
|
||||
SyncAudio.pause()
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
)
|
||||
|
||||
// Seekbar
|
||||
function SyncTimestamp() {
|
||||
SyncAudio.currentTime = SyncVideo.currentTime;
|
||||
SyncAudio.currentTime = SyncVideo.currentTime
|
||||
}
|
||||
</script>
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<canvas id="ambient-canvas-1"/>
|
||||
<canvas id="ambient-canvas-2"/>
|
||||
|
||||
|
@ -48,7 +47,7 @@ const drawFrame = () => {
|
|||
transitionToEvenCanvas()
|
||||
}
|
||||
oddFrame = !oddFrame
|
||||
};
|
||||
}
|
||||
|
||||
const transitionToOddCanvas = () => {
|
||||
oddCanvas.style.opacity = canvasOpacity
|
||||
|
@ -60,26 +59,16 @@ const transitionToEvenCanvas = () => {
|
|||
oddCanvas.style.opacity = "0"
|
||||
}
|
||||
|
||||
const drawStart = () => {
|
||||
intervalId = window.setInterval(drawFrame, frameIntervalMs)
|
||||
}
|
||||
const drawStart = () => {intervalId = window.setInterval(drawFrame, frameIntervalMs)}
|
||||
|
||||
const drawPause = () => {
|
||||
if (intervalId) window.clearInterval(intervalId)
|
||||
}
|
||||
const drawPause = () => {if (intervalId) window.clearInterval(intervalId)}
|
||||
|
||||
const init = () => {
|
||||
|
||||
//fixes a issue where firefox/chromium fails to load the ambinet mode and doesnt load it. - please dont remove this line lmao
|
||||
|
||||
AMvideo.pause();AMvideo.play();
|
||||
|
||||
// DO NOT REMOVE
|
||||
|
||||
const init = () => {
|
||||
AMvideo.pause()
|
||||
AMvideo.play()
|
||||
AMvideo.addEventListener("play", drawStart, false)
|
||||
AMvideo.addEventListener("pause", drawPause, false)
|
||||
AMvideo.addEventListener("ended", drawPause, false)
|
||||
|
||||
oddCanvas.style.transition = evenCanvas.style.transition = `opacity ${frameIntervalMs}ms`
|
||||
}
|
||||
|
||||
|
@ -87,7 +76,7 @@ const cleanup = () => {
|
|||
AMvideo.removeEventListener("play", drawStart)
|
||||
AMvideo.removeEventListener("pause", drawPause)
|
||||
AMvideo.removeEventListener("ended", drawPause)
|
||||
drawPause();
|
||||
drawPause()
|
||||
}
|
||||
|
||||
window.addEventListener("load", init)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
const { Title, Description } = Astro.props;
|
||||
const { Title, Description } = Astro.props
|
||||
---
|
||||
|
||||
<div class="info">
|
||||
|
|
|
@ -8,7 +8,7 @@ import Switcher from '@components/Switcher.astro'
|
|||
import {
|
||||
ArrowUpRight,
|
||||
NavArrowLeft,
|
||||
SwitchOn,
|
||||
SwitchOff,
|
||||
NavArrowRight
|
||||
} from '@iconoir/vue'
|
||||
---
|
||||
|
@ -28,7 +28,7 @@ import {
|
|||
<button>Download <ArrowUpRight/></button>
|
||||
<button>Embed <ArrowUpRight/></button>
|
||||
<hr/>
|
||||
<button id="has-switch">Milieu <SwitchOn/></button>
|
||||
<button id="has-switch">Milieu <SwitchOff/></button>
|
||||
<button>Close Captions <NavArrowRight/></button>
|
||||
<button onclick="PlayerMenu_Quality()">Quality <NavArrowRight/></button>
|
||||
</div>
|
||||
|
@ -46,6 +46,7 @@ import {
|
|||
<Info Title="Ennie and Yoyki: Non-Girly Games" Description="Created by Daniyar Yambushev">
|
||||
<p>Source: <a href="https://www.youtube.com/watch?v=MuyJtxzyU3o">https://www.youtube.com/watch?v=MuyJtxzyU3o</a></p>
|
||||
<p>This demo pulls from: <a href="https://md.sudovanilla.org/videos/webm/Ennie-and-Yoyki.webm">https://md.sudovanilla.org/videos/webm/Ennie-and-Yoyki.webm</a></p>
|
||||
<p>Subtitles shown are part of the video itself, not the player.</p>
|
||||
</Info>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -15,9 +15,9 @@ import {
|
|||
<meta charset="utf-8">
|
||||
|
||||
<Zorn
|
||||
Title="Ennie and Yoyki: Non-Girly Games"
|
||||
Poster="https://md.sudovanilla.org/images/eay-p-v.jpg"
|
||||
Video="https://md.sudovanilla.org/videos/webm/Ennie-and-Yoyki.webm"
|
||||
Title="Islandia"
|
||||
Poster="https://md.sudovanilla.org/images/Islandia%2000%3A00%3A21.png"
|
||||
Video="https://ocean.sudovanilla.org/media/videos/Islandia/Islandia.mp4"
|
||||
CustomControlsWithMenu
|
||||
SettingsMenu
|
||||
Milieu
|
||||
|
@ -45,12 +45,13 @@ import {
|
|||
<Switcher/>
|
||||
<style is:inline>a[href="/milieu"] {background: white !important;color: black !important;}</style>
|
||||
|
||||
<Info Title="Ennie and Yoyki: Non-Girly Games" Description="Created by Daniyar Yambushev">
|
||||
<p>Source: <a href="https://www.youtube.com/watch?v=MuyJtxzyU3o">https://www.youtube.com/watch?v=MuyJtxzyU3o</a></p>
|
||||
<p>This demo pulls from: <a href="https://md.sudovanilla.org/videos/webm/Ennie-and-Yoyki.webm">https://md.sudovanilla.org/videos/webm/Ennie-and-Yoyki.webm</a></p>
|
||||
<Info Title="Islandia" Description="Created by Vadim Sherbakov">
|
||||
<p>Source: <a href="https://vimeo.com/354598551">https://vimeo.com/354598551</a></p>
|
||||
<p>This demo pulls from: <a href="https://ocean.sudovanilla.org/media/videos/Islandia/Islandia.mp4">https://ocean.sudovanilla.org/media/videos/Islandia/Islandia.mp4</a></p>
|
||||
<p>Zorn Player uses the <a href="https://codeberg.org/ashley/poke/src/commit/a28f8e253663264abfcd284f8769b6e901ac1371/html/poketube.ejs#L2186-L2261">Ambient effect from Poke's source code</a>.</p>
|
||||
</Info>
|
||||
|
||||
<style>
|
||||
<style is:global>
|
||||
body {
|
||||
background: #010101;
|
||||
color: white;
|
||||
|
@ -59,6 +60,10 @@ body {
|
|||
color: white;
|
||||
}
|
||||
}
|
||||
.video-container {
|
||||
position: relative;
|
||||
margin: 80px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script is:inline>
|
||||
|
|
Loading…
Reference in a new issue