lydstyrke/src/routes/+page.svelte

159 lines
4.6 KiB
Svelte
Raw Normal View History

<svelte:options runes={true} />
<script lang="ts">
import {OpenSubsonic} from "$lib/opensubsonic";
import {onMount} from "svelte";
import QueueFrame from "$lib/components/custom/QueueFrame.svelte";
2024-04-21 21:39:56 +00:00
//import PlayerFrame from "$lib/components/custom/PlayerFrame.svelte";
import {Button} from "$lib/components/ui/button";
import {browser} from "$app/environment";
//let audioSource: HTMLAudioElement = $state(new Audio());
//let paused: boolean = $derived(audioSource.paused);
//let volume: number = $derived(audioSource.volume);
let source: HTMLAudioElement = $state();
2024-04-21 21:39:56 +00:00
let isPaused = $state(true);
let volume = $state(0.2);
let progress = $state(0);
let duration = $state(0);
let queue: Array<unknown> = $state([]);
async function fetchQueue() {
const data = await OpenSubsonic.get("getPlayQueue");
if (data) {
queue = [];
queue = queue.concat(data.playQueue.entry);
}
}
async function saveQueue() {
let songs = [];
queue.forEach((song, idx) => {
if (idx === 0) {
songs.push({parameter: "current", value: song.id})
songs.push({parameter: "id", value: song.id})
// Add Progress within current song
}
else {
songs.push({parameter: "id", value: song.id})
}
})
const data = await OpenSubsonic.get("savePlayQueue", songs);
if (data) {
await fetchQueue();
}
}
function removeSongFromQueue(idx: number) {
if (idx > -1) {
queue.splice(idx, 1);
}
}
function playSong(song: unknown, songIndex: number) {
//const chosenSong = queue[songIndex];
pause();
newSong(song);
play();
}
function newSong(song: number) {
let parameters = [
{ parameter: "id", value: song.id },
//{ parameter: "maxBitRate", value: } // TODO
//{ parameter: "format", value: } // TODO
//{ parameter: "timeOffset", value: } // TODO? Only Video related
//{ parameter: "size", value: } // TODO? Only Video related
{ parameter: "estimateContentLength", value: "true" },
//{ parameter: "converted", value: } // TODO? Only Video related
];
let url = OpenSubsonic.getApiUrl("stream", parameters);
2024-04-21 21:39:56 +00:00
source = new Audio(url); // Assign new URL
// Reassign Event Handlers
source.onloadedmetadata = () => {
duration = source.duration;
};
source.onplay = () => {
source.volume = volume;
isPaused = source.paused;
}
source.onpause = () => {
isPaused = source.paused;
}
source.ontimeupdate = () => {
progress = source.currentTime;
}
source.load();
2024-04-21 21:39:56 +00:00
}
function play() {
source.play().catch(() => {});
}
2024-04-21 21:39:56 +00:00
function pause() {
source.pause();
}
2024-04-21 21:39:56 +00:00
$effect(() => {
if (source) {
source.volume = volume;
}
});
function progressPercent() {
return progress / duration * 100 || 0;
}
function displayTime(rawSeconds: number) {
const intSeconds = rawSeconds.toFixed(0);
const seconds = intSeconds % 60;
const minutes = (intSeconds / 60).toFixed(0) % 60;
const hours = (intSeconds / 360).toFixed(0);
if (hours == 0) {
return `${minutes.toString()}:${seconds.toString().padStart(2, 0)}`
}
else {
return `${hours}:${minutes.toString().padStart(2, 0)}:${seconds.toString().padStart(2, 0)}`
}
}
onMount(() => {
fetchQueue();
source = new Audio();
})
</script>
<div class="border border-2 flex-1 grid grid-cols-5">
<div class="border border-2 col-span-1">
<h1>Left Sidebar</h1>
</div>
<div class="border border-2 col-span-3">
<h1>Center</h1>
2024-04-21 21:39:56 +00:00
<button onclick={() => volume += 0.1}>Louder</button>
<button onclick={() => volume -= 0.1}>Quieter</button>
</div>
<QueueFrame {queue} {fetchQueue} {saveQueue} {removeSongFromQueue} {playSong} />
</div>
<div class="border border-2 min-h-24 h-24">
2024-04-21 21:39:56 +00:00
<div class="flex flex-row gap-2">
<p class="border p-2">Volume: {volume}</p>
<p class="border p-2">{displayTime(progress)}/{displayTime(duration)}</p>
<p class="border p-2">{progressPercent().toFixed(2)}%</p>
{#if isPaused}
<Button onclick={play}>Play</Button>
{:else}
<Button onclick={pause}>Pause</Button>
{/if}
</div>
</div>