2024-04-21 21:00:45 +00:00
|
|
|
<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>
|
|
|
|
|