lydstyrke/src/routes/+page.svelte

160 lines
4.3 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";
import PlayerFrame from "$lib/components/custom/PlayerFrame.svelte";
//let audioSource: HTMLAudioElement = $state(new Audio());
//let paused: boolean = $derived(audioSource.paused);
//let volume: number = $derived(audioSource.volume);
let source: HTMLAudioElement = $state();
let audio = $state({
get paused() {
if (source) {
return source.paused;
}
else {
return true;
}
},
get volume() {
if (source) {
return source.volume;
}
else {
return 0;
}
},
set volume(volume) {
source.volume = volume;
},
get duration() {
if (source) {
return source.duration;
}
else {
return 0;
}
},
get currentTime() {
if (source) {
return source.currentTime;
}
else {
return 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);
}
}
async function playSong(songIndex: number) {
console.log(queue[songIndex].title);
const chosenSong = queue[songIndex];
let parameters = [
{ parameter: "id", value: chosenSong.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);
await pause();
source = new Audio(url);
await play();
}
async function play() {
await source.play().catch(() => {});
await new Promise(resolve => {setTimeout(resolve, 50)});
audio.volume = 0.2;
forceUpdate();
}
async function pause() {
source.pause();
await new Promise(resolve => {setTimeout(resolve, 50)});
forceUpdate();
//audio.paused = audio.source.paused;
}
function forceUpdate() {
let tmp = audio;
audio = {};
audio = tmp;
}
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>
<button onclick={() => audio.volume += 0.1}>Louder</button>
<button onclick={() => audio.volume -= 0.1}>Quieter</button>
{#if typeof audio !== "undefined"}
<p>{audio.currentTime}</p>
{/if}
</div>
<QueueFrame {queue} {fetchQueue} {saveQueue} {removeSongFromQueue} {playSong} />
</div>
<div class="border border-2 min-h-24 h-24">
{#if typeof audio !== "undefined"}
<PlayerFrame
audio={audio}
pause={pause}
play={play}
/>
{/if}
</div>