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)
|
![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
|
## Installation
|
||||||
To install Zorn for your Astro project, run the following:
|
To install Zorn for your Astro project, run the following:
|
||||||
|
@ -79,6 +95,7 @@ Local:
|
||||||
```jsx
|
```jsx
|
||||||
<Zorn Video="/media/video.webm"/>
|
<Zorn Video="/media/video.webm"/>
|
||||||
```
|
```
|
||||||
|
> [!NOTE]
|
||||||
> Use the `/public/` folder in your Astro project.
|
> Use the `/public/` folder in your Astro project.
|
||||||
|
|
||||||
Remote:
|
Remote:
|
||||||
|
@ -94,6 +111,7 @@ Local:
|
||||||
```jsx
|
```jsx
|
||||||
<Zorn Audio="/media/audio.ogg"/>
|
<Zorn Audio="/media/audio.ogg"/>
|
||||||
```
|
```
|
||||||
|
> [!NOTE]
|
||||||
> Use the `/public/` folder in your Astro project.
|
> Use the `/public/` folder in your Astro project.
|
||||||
|
|
||||||
Remote:
|
Remote:
|
||||||
|
@ -127,7 +145,7 @@ Then, as a slot, add your menu like so:
|
||||||
</div>
|
</div>
|
||||||
</Zorn>
|
</Zorn>
|
||||||
```
|
```
|
||||||
|
> [!NOTE]
|
||||||
> Use `OpenZornMenu()` as the open menu function. You can use the scripts provided in `/test/` of this package.
|
> 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:
|
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**|
|
| **Other Browsers**|
|
||||||
| FOSS Browser | ✅ | ✅ | ❌ | ✅ |
|
| FOSS Browser | ✅ | ✅ | ❌ | ✅ |
|
||||||
| Ladybird | 🔘 | 🔘 | 🔘 | 🔘 |
|
| Ladybird | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||||
|
| Pale Moon | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||||
| **WebKit Browsers**|
|
| **WebKit Browsers**|
|
||||||
| Safari | 🔘 | 🔘 | 🔘 | 🔘 |
|
| Safari | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||||
| GNOME Web | ✅ | ✅ | ✅*N| ✅ |
|
| GNOME Web | ✅ | ✅ | ✅ | ✅ |
|
||||||
| DuckDuckGo | 🔘 | 🔘 | 🔘 | 🔘 |
|
| DuckDuckGo | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||||
| **Electron Browsers**|
|
| **Electron Browsers**|
|
||||||
| Min | 🔘 | ✅ | ✅ | ✅ |
|
| Min | 🔘 | ✅ | ✅ | ✅ |
|
||||||
|
@ -215,9 +234,11 @@ Just add the `Live` option with an `.m3u8` source.
|
||||||
| Google Chrome | ✅ | ✅ | ✅ | ✅ |
|
| Google Chrome | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Microsoft Edge | ✅ | ✅ | ✅ | ✅ |
|
| Microsoft Edge | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Opera | ✅ | ✅ | ✅ | ✅ |
|
| Opera | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| Vanadium | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||||
| Vivaldi | ✅ | ✅ | ✅ | ✅ |
|
| Vivaldi | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Yandex | ✅ | ❌ | ✅ | ❌ |
|
| Yandex | ✅ | ✅ | ✅ | ✅ |
|
||||||
| **Firefox Browsers**|
|
| **Firefox Browsers**|
|
||||||
|
| Basilisk | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||||
| Falkon | ✅ | ✅ | ✅ | ✅ |
|
| Falkon | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Firefox | ✅ | ✅ | ✅ | ✅ |
|
| Firefox | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Floorp | ✅ | ✅ | ✅ | ✅ |
|
| Floorp | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
@ -227,15 +248,12 @@ Just add the `Live` option with an `.m3u8` source.
|
||||||
| Mullvad | ✅ | ✅ | ✅ | ✅ |
|
| Mullvad | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Tor | 🔘 | 🔘 | 🔘 | 🔘 |
|
| Tor | 🔘 | 🔘 | 🔘 | 🔘 |
|
||||||
| Waterfox | ✅ | ✅ | ✅ | ✅ |
|
| Waterfox | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| Zen | ✅ | ✅ | ✅ | ✅ |
|
||||||
| **Outdated Browsers**|
|
| **Outdated Browsers**|
|
||||||
| Internet Explorer | 🔘 | 🔘 | 🔘 | 🔘 |
|
| 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.
|
> [!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.
|
||||||
> 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
|
|
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",
|
"name": "@minpluto/zorn",
|
||||||
"author": "SudoVanilla",
|
"author": "SudoVanilla",
|
||||||
"description": "A video player tailored for MinPluto",
|
"description": "Tailored for MinPluto, customizable for you.",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "https://codeberg.org/MinPluto/Zorn"
|
"url": "https://codeberg.org/MinPluto/Zorn"
|
||||||
},
|
},
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
"live-streaming"
|
"live-streaming"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.4.5",
|
"version": "0.4.52",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./index.ts"
|
".": "./index.ts"
|
||||||
},
|
},
|
||||||
|
@ -33,4 +33,4 @@
|
||||||
"npm:publish": "npm publish --registry https://npm.sudovanilla.org/",
|
"npm:publish": "npm publish --registry https://npm.sudovanilla.org/",
|
||||||
"test": "cd test/ && bun start"
|
"test": "cd test/ && bun start"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,10 +8,11 @@ const {
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import {
|
import {
|
||||||
Backward15Seconds,
|
RewindSolid,
|
||||||
Enlarge,
|
Enlarge,
|
||||||
Forward15Seconds,
|
ForwardSolid,
|
||||||
PlaySolid,
|
PlaySolid,
|
||||||
|
Refresh
|
||||||
} from "@iconoir/vue";
|
} from "@iconoir/vue";
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -20,13 +21,14 @@ import {
|
||||||
<p>{Title}</p>
|
<p>{Title}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="vc-bottom">
|
<div class="vc-bottom">
|
||||||
|
<button style="display: none" id="vc-playagain"><Refresh /></button>
|
||||||
<div class="vc-start">
|
<div class="vc-start">
|
||||||
<button id="vc-playpause"><PlaySolid /></button>
|
<button id="vc-playpause"><PlaySolid /></button>
|
||||||
{Live ?
|
{Live ?
|
||||||
null
|
null
|
||||||
:
|
:
|
||||||
<button id="vc-backwards"><Backward15Seconds /></button>
|
<button id="vc-backwards"><RewindSolid /></button>
|
||||||
<button id="vc-forwards"><Forward15Seconds /></button>
|
<button id="vc-forwards"><ForwardSolid /></button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="vc-center">
|
<div class="vc-center">
|
||||||
|
@ -56,6 +58,10 @@ import {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- HLS Script -->
|
||||||
|
<!-- Required to support live streaming -->
|
||||||
|
<!-- Script is not loaded if the video player is not set for a stream -->
|
||||||
{Live ?
|
{Live ?
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
// Original Source: https://hlsjs.video-dev.org/dist/hls.js
|
// 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 PlayIcon = play_solid_default;
|
||||||
var PauseIcon = pause_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
|
// Fullscreen
|
||||||
function Fullscreen() {
|
function Fullscreen() {
|
||||||
const Button_Fullscreen = document.getElementById("vc-fullscreen");
|
const Button_Fullscreen = document.getElementById("vc-fullscreen");
|
||||||
|
@ -67,13 +72,16 @@ function Fullscreen() {
|
||||||
document.querySelector('.video-container .video-controls').style.height = '100%'
|
document.querySelector('.video-container .video-controls').style.height = '100%'
|
||||||
VideoContainer.requestFullscreen();
|
VideoContainer.requestFullscreen();
|
||||||
}
|
}
|
||||||
|
Update_FullscreenButton()
|
||||||
}
|
}
|
||||||
Button_Fullscreen.onclick = Toggle_Fullscreen;
|
Button_Fullscreen.onclick = Toggle_Fullscreen;
|
||||||
function Update_FullscreenButton() {
|
function Update_FullscreenButton() {
|
||||||
if (document.fullscreenElement) {
|
if (document.fullscreenElement) {
|
||||||
Button_Fullscreen.setAttribute("data-title", "Exit full screen (f)");
|
Button_Fullscreen.setAttribute("data-title", "Exit full screen (f)");
|
||||||
|
Button_Fullscreen.innerHTML = `${FullscreenIcon}`;
|
||||||
} else {
|
} else {
|
||||||
Button_Fullscreen.setAttribute("data-title", "Full screen (f)");
|
Button_Fullscreen.setAttribute("data-title", "Full screen (f)");
|
||||||
|
Button_Fullscreen.innerHTML = `${ExitFullscreenIcon}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Player.addEventListener("dblclick", () => {
|
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
|
// Play/Pause
|
||||||
function PlayPause() {
|
function PlayPause() {
|
||||||
const Button_PlayPause = document.querySelector(".video-controls #vc-playpause");
|
const Button_PlayPause = document.querySelector(".video-controls #vc-playpause");
|
||||||
|
@ -227,10 +246,35 @@ function KeyboardShortcuts(events) {
|
||||||
document.addEventListener("keyup", keyboardShortcuts);
|
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
|
// Init All Functions
|
||||||
AutoToggleControls()
|
AutoToggleControls()
|
||||||
Fullscreen()
|
Fullscreen()
|
||||||
KeyboardShortcuts()
|
KeyboardShortcuts()
|
||||||
PlayPause()
|
PlayPause()
|
||||||
SkipAround()
|
SkipAround()
|
||||||
|
PlayAgain()
|
||||||
</script>
|
</script>
|
|
@ -9,6 +9,8 @@
|
||||||
}
|
}
|
||||||
video {
|
video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
canvas {
|
canvas {
|
||||||
|
@ -66,6 +68,10 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
.vc-start,
|
||||||
|
.vc-center {
|
||||||
|
transition: 0.3s opacity;
|
||||||
|
}
|
||||||
.vc-center {
|
.vc-center {
|
||||||
width: calc(100% - 220px);
|
width: calc(100% - 220px);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -192,6 +198,7 @@
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
backdrop-filter: blur(24px) contrast(0.8) brightness(0.8);
|
backdrop-filter: blur(24px) contrast(0.8) brightness(0.8);
|
||||||
|
-webkit-backdrop-filter: blur(24px) contrast(0.8) brightness(0.8);
|
||||||
hr {
|
hr {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
import vue from '@astrojs/vue';
|
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;
|
background: #010101;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ body {
|
||||||
background: #010101;
|
background: #010101;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,8 @@ body {
|
||||||
background: #010101;
|
background: #010101;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
Loading…
Reference in a new issue