diff --git a/src/lib/components/audio-loader.svelte b/src/lib/components/audio-loader.svelte index 56f2bd9..d396daf 100644 --- a/src/lib/components/audio-loader.svelte +++ b/src/lib/components/audio-loader.svelte @@ -1,10 +1,10 @@ {#key src} @@ -42,34 +42,34 @@ // console.log('emptied', e); }} on:loadeddata={() => { - __internal_audio_metadata.update((m) => ({ ...m, loading: false })); + audio_metadata.update((m) => ({ ...m, loading: false })); }} on:loadstart={() => { - __internal_audio_metadata.update((m) => ({ ...m, loading: true })); + audio_metadata.update((m) => ({ ...m, loading: true })); }} on:playing={(e) => { // @ts-expect-error event is not fully typed const is_paused = e.target.paused; if (!isBoolean(is_paused)) return; - __internal_audio_metadata.update((m) => ({ ...m, paused: is_paused })); + audio_metadata.update((m) => ({ ...m, paused: is_paused })); }} on:pause={(e) => { // @ts-expect-error event is not fully typed const is_paused = e.target.paused; if (!isBoolean(is_paused)) return; - __internal_audio_metadata.update((m) => ({ ...m, paused: is_paused })); + audio_metadata.update((m) => ({ ...m, paused: is_paused })); }} on:ratechange={(e) => { // @ts-expect-error event is not fully typed const playbackRate = e.target.playbackRate; if (!isNumber(playbackRate)) return; - __internal_audio_metadata.update((m) => ({ ...m, playbackRate })); + audio_metadata.update((m) => ({ ...m, playbackRate })); }} on:durationchange={(e) => { // @ts-expect-error event is not fully typed const duration = e.target?.duration; if (!isNumber(duration)) return; - __internal_audio_metadata.update((m) => ({ ...m, duration })); + audio_metadata.update((m) => ({ ...m, duration })); }} /> {/key} diff --git a/src/lib/context/audio-internals.ts b/src/lib/context/audio-internals.ts new file mode 100644 index 0000000..5083a48 --- /dev/null +++ b/src/lib/context/audio-internals.ts @@ -0,0 +1,13 @@ +import type { PlayerElement, PlayerMetadata } from '$lib/types/types'; +import { writable } from 'svelte/store'; + +export const audio_current_time = writable(0); +export const audio_src = writable(null); +export const audio_element = writable(); +export const audio_metadata = writable({ + duration: 0, + muted: false, + paused: true, + playbackRate: 1, + loading: false, +}); diff --git a/src/lib/context/audio.ts b/src/lib/context/audio.ts index b5b70f0..c91a837 100644 --- a/src/lib/context/audio.ts +++ b/src/lib/context/audio.ts @@ -1,36 +1,27 @@ -import type { PlayerElement, PlayerMetadata } from '$lib/types/types'; +import { + audio_current_time, + audio_element, + audio_metadata, + audio_src, +} from '$lib/context/audio-internals'; import { secondsToTimestamp } from '$lib/utility/seconds-to-timestamp'; import { info, warn } from '$pkg/log'; import clamp from 'just-clamp'; -import { derived, writable } from 'svelte/store'; +import { derived } from 'svelte/store'; -export const __internal_audio_current_time = writable(0); -export const __internal_audio_src = writable(null); -export const __internal_audio_element = writable(); -export const __internal_audio_metadata = writable({ - duration: 0, - muted: false, - paused: true, - playbackRate: 1, - loading: false, +const audio_state = derived([audio_metadata, audio_current_time], ([$metadata, $current_time]) => { + return { + current_time: $current_time, + timestamp: secondsToTimestamp($current_time), + ...$metadata, + }; }); -const state = derived( - [__internal_audio_metadata, __internal_audio_current_time], - ([$metadata, $current_time]) => { - return { - current_time: $current_time, - timestamp: secondsToTimestamp($current_time), - ...$metadata, - }; - }, -); - type HandleType = 'toggle' | 'set'; function play(type: HandleType = 'set') { info('play: ', type); - return __internal_audio_element.subscribe((el) => { + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); if (type === 'toggle') { el.paused ? el.play() : el.pause(); @@ -41,7 +32,7 @@ function play(type: HandleType = 'set') { } function pause(type: HandleType = 'set') { info('pause: ', type); - return __internal_audio_element.subscribe((el) => { + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); if (type === 'toggle') { el.paused ? el.play() : el.pause(); @@ -53,7 +44,7 @@ function pause(type: HandleType = 'set') { function mute(type: HandleType = 'set') { info('mute: ', type); - return __internal_audio_element.subscribe((el) => { + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); if (type === 'toggle') { el.muted = !el.muted; @@ -64,7 +55,7 @@ function mute(type: HandleType = 'set') { } function unmute(type: HandleType = 'set') { info('unmute: ', type); - return __internal_audio_element.subscribe((el) => { + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); if (type === 'toggle') { el.muted = !el.muted; @@ -76,8 +67,8 @@ function unmute(type: HandleType = 'set') { function load(src: string) { info('load: ', src); - __internal_audio_src.set(src); - return __internal_audio_element.subscribe((el) => { + audio_src.set(src); + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); el.volume = 1; el.pause(); @@ -85,12 +76,12 @@ function load(src: string) { } function unload() { info('unload: '); - __internal_audio_src.set(null); + audio_src.set(null); } function setPlaybackRate(rate: number) { info('setPlaybackRate: ', rate); - return __internal_audio_element.subscribe((el) => { + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); el.playbackRate = clamp(0, 10, rate); })(); @@ -98,7 +89,7 @@ function setPlaybackRate(rate: number) { function seek(seconds: number, from: 'from-start' | 'from-end' = 'from-start') { info('seek: ', seconds, from); - return __internal_audio_element.subscribe((el) => { + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); if (from === 'from-end') { el.currentTime = clamp(0, el.duration, el.duration - seconds); @@ -110,7 +101,7 @@ function seek(seconds: number, from: 'from-start' | 'from-end' = 'from-start') { function skip(seconds: number, type: 'forward' | 'backward' = 'forward') { info('skip: ', seconds, type); - return __internal_audio_element.subscribe((el) => { + return audio_element.subscribe((el) => { if (!el) return warn('no audio element'); if (type === 'backward') { el.currentTime = clamp(0, el.duration, el.currentTime - seconds); @@ -121,7 +112,7 @@ function skip(seconds: number, type: 'forward' | 'backward' = 'forward') { } export const audio = { - subscribe: state.subscribe, + subscribe: audio_state.subscribe, play, pause, mute,