Compare commits
8 commits
79c9039cdd
...
23bf61f239
Author | SHA1 | Date | |
---|---|---|---|
|
23bf61f239 | ||
|
c793d5940f | ||
|
cbc06d83ed | ||
|
c930a3bbf1 | ||
|
eb376151f2 | ||
|
9bcbd72237 | ||
|
ce4007160a | ||
|
8c67818689 |
11 changed files with 127 additions and 21 deletions
44
README.md
44
README.md
|
@ -1,8 +1,24 @@
|
|||
# Zorn
|
||||
<br/>
|
||||
<h3 align="center">
|
||||
<img src="https://md.sudovanilla.org/images/Zorn%20Player.png" alt="Logo" height="64"/>
|
||||
</h3>
|
||||
<br/>
|
||||
|
||||
<div align="center">
|
||||
Tailored for MinPluto, customizable for you.
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
|
||||
![Zorn using Milieu Mode](https://md.sudovanilla.org/images/Screenshot%20from%202024-08-16%2016-16-48.png)
|
||||
|
||||
A custom video player tailored for MinPluto.
|
||||
<div align="center">
|
||||
|
||||
<a href="https://codeberg.org/MinPluto/Zorn/" target="_blank"> <img src="https://img.shields.io/badge/Codeberg-blue"> </a>
|
||||
<a href="https://npm.sudovanilla.org/-/web/detail/@minpluto/zorn" target="_blank"> <img src="https://img.shields.io/badge/SudoVanilla%20Packages-purple"> </a>
|
||||
<a href="https://www.npmjs.com/package/@minpluto/zorn" target="_blank"> <img src="https://img.shields.io/badge/NPM-red"> </a>
|
||||
</div>
|
||||
|
||||
## Installation
|
||||
To install Zorn for your Astro project, run the following:
|
||||
|
@ -79,6 +95,7 @@ Local:
|
|||
```jsx
|
||||
<Zorn Video="/media/video.webm"/>
|
||||
```
|
||||
> [!NOTE]
|
||||
> Use the `/public/` folder in your Astro project.
|
||||
|
||||
Remote:
|
||||
|
@ -94,6 +111,7 @@ Local:
|
|||
```jsx
|
||||
<Zorn Audio="/media/audio.ogg"/>
|
||||
```
|
||||
> [!NOTE]
|
||||
> Use the `/public/` folder in your Astro project.
|
||||
|
||||
Remote:
|
||||
|
@ -127,7 +145,7 @@ Then, as a slot, add your menu like so:
|
|||
</div>
|
||||
</Zorn>
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Use `OpenZornMenu()` as the open menu function. You can use the scripts provided in `/test/` of this package.
|
||||
|
||||
You can also add sub-menus with additional scripts you'll need to add:
|
||||
|
@ -203,9 +221,10 @@ Just add the `Live` option with an `.m3u8` source.
|
|||
| **Other Browsers**|
|
||||
| FOSS Browser | ✅ | ✅ | ❌ | ✅ |
|
||||
| Ladybird | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
| Pale Moon | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
| **WebKit Browsers**|
|
||||
| Safari | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
| GNOME Web | ✅ | ✅ | ✅*N| ✅ |
|
||||
| GNOME Web | ✅ | ✅ | ✅ | ✅ |
|
||||
| DuckDuckGo | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
| **Electron Browsers**|
|
||||
| Min | 🔘 | ✅ | ✅ | ✅ |
|
||||
|
@ -215,9 +234,11 @@ Just add the `Live` option with an `.m3u8` source.
|
|||
| Google Chrome | ✅ | ✅ | ✅ | ✅ |
|
||||
| Microsoft Edge | ✅ | ✅ | ✅ | ✅ |
|
||||
| Opera | ✅ | ✅ | ✅ | ✅ |
|
||||
| Vanadium | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
| Vivaldi | ✅ | ✅ | ✅ | ✅ |
|
||||
| Yandex | ✅ | ❌ | ✅ | ❌ |
|
||||
| Yandex | ✅ | ✅ | ✅ | ✅ |
|
||||
| **Firefox Browsers**|
|
||||
| Basilisk | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
| Falkon | ✅ | ✅ | ✅ | ✅ |
|
||||
| Firefox | ✅ | ✅ | ✅ | ✅ |
|
||||
| Floorp | ✅ | ✅ | ✅ | ✅ |
|
||||
|
@ -227,15 +248,12 @@ Just add the `Live` option with an `.m3u8` source.
|
|||
| Mullvad | ✅ | ✅ | ✅ | ✅ |
|
||||
| Tor | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
| Waterfox | ✅ | ✅ | ✅ | ✅ |
|
||||
| Zen | ✅ | ✅ | ✅ | ✅ |
|
||||
| **Outdated Browsers**|
|
||||
| Internet Explorer | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||
|
||||
> All browsers are tested as-is out of box. Some functions with ❌ can probably work if you tweak the settings or interact with a built-in extension.
|
||||
> [!NOTE]
|
||||
> All browsers are tested as-is out of box. Some functions with ❌ can probably work if you tweak the settings or interact with a built-in extension. 🔘 means it's not been tested yet.
|
||||
|
||||
> IC: By default, GNU/IceCat has the LibreJS extension installed, it will block all JS by default if it does not provide a valid license. Examples for settings menu do not provide one nor one is shown in the test version.
|
||||
|
||||
> N: The backdrop blur does not work. This should not affect the function of the video player.
|
||||
|
||||
## To Do
|
||||
- [x] Support HLS (HTTP Live Streaming)
|
||||
- [ ] Touch gestures for mobile
|
||||
> [!NOTE]
|
||||
> IC: By default, GNU/IceCat has the LibreJS extension installed, it will block all JS by default if it does not provide a valid license. Examples for settings menu do not provide one nor one is shown in the test version.
|
15
TODO.md
Normal file
15
TODO.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
- [x] Support HLS (HTTP Live Streaming)
|
||||
- [ ] Subtitles ([`textTracks`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/textTracks))
|
||||
- [ ] Multi-Video Tracks ([`videoTracks`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/videoTracks))
|
||||
- [ ] Multi-Audio Tracks ([`audioTracks`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/audioTracks))
|
||||
- [ ] Playback Rate ([`playbackRate`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/playbackRate))
|
||||
- [ ] Add Picture-in-Picture button
|
||||
- [ ] Volume Controller
|
||||
- [ ] Mobile Gestures
|
||||
- [ ] Cast Support
|
||||
- [ ] Allow for multiple players on one page
|
||||
- [ ] Modes
|
||||
- [ ] Audio-Only
|
||||
- [ ] Pop-Up
|
||||
- [ ] Presentation
|
||||
- [ ] Inline
|
BIN
bun.lockb
Executable file
BIN
bun.lockb
Executable file
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@minpluto/zorn",
|
||||
"author": "SudoVanilla",
|
||||
"description": "A video player tailored for MinPluto",
|
||||
"description": "Tailored for MinPluto, customizable for you.",
|
||||
"repository": {
|
||||
"url": "https://codeberg.org/MinPluto/Zorn"
|
||||
},
|
||||
|
@ -14,7 +14,7 @@
|
|||
"live-streaming"
|
||||
],
|
||||
"type": "module",
|
||||
"version": "0.4.5",
|
||||
"version": "0.4.52",
|
||||
"exports": {
|
||||
".": "./index.ts"
|
||||
},
|
||||
|
@ -33,4 +33,4 @@
|
|||
"npm:publish": "npm publish --registry https://npm.sudovanilla.org/",
|
||||
"test": "cd test/ && bun start"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,10 +8,11 @@ const {
|
|||
|
||||
// Icons
|
||||
import {
|
||||
Backward15Seconds,
|
||||
RewindSolid,
|
||||
Enlarge,
|
||||
Forward15Seconds,
|
||||
ForwardSolid,
|
||||
PlaySolid,
|
||||
Refresh
|
||||
} from "@iconoir/vue";
|
||||
---
|
||||
|
||||
|
@ -20,13 +21,14 @@ import {
|
|||
<p>{Title}</p>
|
||||
</div>
|
||||
<div class="vc-bottom">
|
||||
<button style="display: none" id="vc-playagain"><Refresh /></button>
|
||||
<div class="vc-start">
|
||||
<button id="vc-playpause"><PlaySolid /></button>
|
||||
{Live ?
|
||||
null
|
||||
:
|
||||
<button id="vc-backwards"><Backward15Seconds /></button>
|
||||
<button id="vc-forwards"><Forward15Seconds /></button>
|
||||
<button id="vc-backwards"><RewindSolid /></button>
|
||||
<button id="vc-forwards"><ForwardSolid /></button>
|
||||
}
|
||||
</div>
|
||||
<div class="vc-center">
|
||||
|
@ -56,6 +58,10 @@ import {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- HLS Script -->
|
||||
<!-- Required to support live streaming -->
|
||||
<!-- Script is not loaded if the video player is not set for a stream -->
|
||||
{Live ?
|
||||
<script is:inline>
|
||||
// Original Source: https://hlsjs.video-dev.org/dist/hls.js
|
||||
|
|
|
@ -34,6 +34,11 @@ var pause_solid_default = '<?xml version="1.0" encoding="UTF-8"?><svg width="24p
|
|||
var PlayIcon = play_solid_default;
|
||||
var PauseIcon = pause_solid_default;
|
||||
|
||||
var fullscreen_solid_default = '<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#ffffff"><path d="M15 9L20 4M20 4V8M20 4H16" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9 15L4 20M4 20V16M4 20H8" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>'
|
||||
var exit_fullscreen_solid_default = '<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#ffffff"><path d="M4 20L9 15M9 15V19M9 15H5" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M20 4L15 9M15 9V5M15 9H19" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>'
|
||||
var FullscreenIcon = fullscreen_solid_default
|
||||
var ExitFullscreenIcon = exit_fullscreen_solid_default
|
||||
|
||||
// Fullscreen
|
||||
function Fullscreen() {
|
||||
const Button_Fullscreen = document.getElementById("vc-fullscreen");
|
||||
|
@ -67,13 +72,16 @@ function Fullscreen() {
|
|||
document.querySelector('.video-container .video-controls').style.height = '100%'
|
||||
VideoContainer.requestFullscreen();
|
||||
}
|
||||
Update_FullscreenButton()
|
||||
}
|
||||
Button_Fullscreen.onclick = Toggle_Fullscreen;
|
||||
function Update_FullscreenButton() {
|
||||
if (document.fullscreenElement) {
|
||||
Button_Fullscreen.setAttribute("data-title", "Exit full screen (f)");
|
||||
Button_Fullscreen.innerHTML = `${FullscreenIcon}`;
|
||||
} else {
|
||||
Button_Fullscreen.setAttribute("data-title", "Full screen (f)");
|
||||
Button_Fullscreen.innerHTML = `${ExitFullscreenIcon}`;
|
||||
}
|
||||
}
|
||||
Player.addEventListener("dblclick", () => {
|
||||
|
@ -82,6 +90,17 @@ function Fullscreen() {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
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}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Play/Pause
|
||||
function PlayPause() {
|
||||
const Button_PlayPause = document.querySelector(".video-controls #vc-playpause");
|
||||
|
@ -227,10 +246,35 @@ function KeyboardShortcuts(events) {
|
|||
document.addEventListener("keyup", keyboardShortcuts);
|
||||
}
|
||||
|
||||
// If Media Ends, fade main controls and show a "Replay" button
|
||||
function PlayAgain() {
|
||||
Player.onended = (event) => {
|
||||
document.querySelector('.vc-start').style.opacity = '0'
|
||||
document.querySelector('.vc-start').style.pointerEvents = 'none'
|
||||
document.querySelector('.vc-center').style.opacity = '0'
|
||||
document.querySelector('.vc-center').style.pointerEvents = 'none'
|
||||
document.querySelector('#vc-playagain').style.display = 'inherit'
|
||||
}
|
||||
document.querySelector('#vc-playagain').onclick = PlayItAgain
|
||||
}
|
||||
|
||||
function PlayItAgain() {
|
||||
document.querySelector('.vc-start').style.opacity = '1'
|
||||
document.querySelector('.vc-start').style.pointerEvents = 'all'
|
||||
document.querySelector('.vc-center').style.opacity = '1'
|
||||
document.querySelector('.vc-center').style.pointerEvents = 'all'
|
||||
document.querySelector('#vc-playagain').style.display = 'none'
|
||||
|
||||
Player.pause();
|
||||
Player.currentTime = '0';
|
||||
Player.play();
|
||||
}
|
||||
|
||||
// Init All Functions
|
||||
AutoToggleControls()
|
||||
Fullscreen()
|
||||
KeyboardShortcuts()
|
||||
PlayPause()
|
||||
SkipAround()
|
||||
PlayAgain()
|
||||
</script>
|
|
@ -9,6 +9,8 @@
|
|||
}
|
||||
video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
z-index: 1;
|
||||
}
|
||||
canvas {
|
||||
|
@ -66,6 +68,10 @@
|
|||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.vc-start,
|
||||
.vc-center {
|
||||
transition: 0.3s opacity;
|
||||
}
|
||||
.vc-center {
|
||||
width: calc(100% - 220px);
|
||||
display: flex;
|
||||
|
@ -192,6 +198,7 @@
|
|||
gap: 6px;
|
||||
padding: 4px;
|
||||
backdrop-filter: blur(24px) contrast(0.8) brightness(0.8);
|
||||
-webkit-backdrop-filter: blur(24px) contrast(0.8) brightness(0.8);
|
||||
hr {
|
||||
margin: 0px;
|
||||
width: 100%;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import vue from '@astrojs/vue';
|
||||
|
||||
export default defineConfig({integrations: [vue()]});
|
||||
export default defineConfig({
|
||||
vite: {
|
||||
server: {
|
||||
hmr: false
|
||||
}
|
||||
},
|
||||
integrations: [vue()]
|
||||
});
|
|
@ -50,6 +50,9 @@ body {
|
|||
background: #010101;
|
||||
color: white;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ body {
|
|||
background: #010101;
|
||||
color: white;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -27,5 +27,8 @@ body {
|
|||
background: #010101;
|
||||
color: white;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in a new issue