diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..ce956ec
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+app/static/songs/** filter=lfs diff=lfs merge=lfs -text
diff --git a/app/static/songs/danger-zone/audio.mp3 b/app/static/songs/danger-zone/audio.mp3
index 25e367e..50069ff 100644
Binary files a/app/static/songs/danger-zone/audio.mp3 and b/app/static/songs/danger-zone/audio.mp3 differ
diff --git a/app/static/songs/danger-zone/cover.png b/app/static/songs/danger-zone/cover.png
index c4968ef..4e4139c 100644
Binary files a/app/static/songs/danger-zone/cover.png and b/app/static/songs/danger-zone/cover.png differ
diff --git a/app/static/songs/deja-vu/audio.m4a b/app/static/songs/deja-vu/audio.m4a
new file mode 100644
index 0000000..43eff68
--- /dev/null
+++ b/app/static/songs/deja-vu/audio.m4a
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1ffed6b030e6efac7b842aa1d04fe142ae67cc42676ef0863fd98c986e45167c
+size 4272439
diff --git a/app/static/songs/deja-vu/cover.jpg b/app/static/songs/deja-vu/cover.jpg
new file mode 100644
index 0000000..f64a267
--- /dev/null
+++ b/app/static/songs/deja-vu/cover.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:577320e227fedd883db36d7e1fd0399b4f7bae898a9c927de4b347c59f54917f
+size 36462
diff --git a/app/static/songs/xenogenesis/audio.m4a b/app/static/songs/xenogenesis/audio.m4a
new file mode 100644
index 0000000..481189a
--- /dev/null
+++ b/app/static/songs/xenogenesis/audio.m4a
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ed6986a60bd281410b2e47a21928280ef1b4ef8ea0015f046886e0c1ca38f1f8
+size 3780869
diff --git a/app/static/songs/xenogenesis/cover.jpg b/app/static/songs/xenogenesis/cover.jpg
new file mode 100644
index 0000000..b1705b3
--- /dev/null
+++ b/app/static/songs/xenogenesis/cover.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:60bb7c64e60ec007b423dcd427cb7c7cb8a5e075b504e3168b5a63a0d4b6cc7e
+size 79875
diff --git a/client/src/lib/Apps/MusicBrowser/Song.svelte b/client/src/lib/Apps/MusicBrowser/Song.svelte
index 5972a1a..00cee78 100644
--- a/client/src/lib/Apps/MusicBrowser/Song.svelte
+++ b/client/src/lib/Apps/MusicBrowser/Song.svelte
@@ -8,6 +8,7 @@
const handlePlay = () => {
musicStore.setCurrent(slug)
+ !$musicStore.playing && musicStore.toggle()
}
const handleQueueNext = () => {
@@ -17,6 +18,8 @@
const handleQueueLast = () => {
musicStore.push(slug)
}
+
+ $: nowPlaying = slug === $musicStore.queue[$musicStore.currentIndex]
{artist}
-
-
+
{/if}
diff --git a/client/src/lib/Dashboard/MediaPlayer/audioManager.ts b/client/src/lib/Dashboard/MediaPlayer/audioManager.ts
index 63bc198..c5522e1 100644
--- a/client/src/lib/Dashboard/MediaPlayer/audioManager.ts
+++ b/client/src/lib/Dashboard/MediaPlayer/audioManager.ts
@@ -1,11 +1,8 @@
export class AudioManager {
private audioContext: AudioContext | null = null
private currentSource: AudioBufferSourceNode | null = null
- private currentBuffer: AudioBuffer | null = null // Stores the current audio buffer
- private startTime: number = 0 // When the current playback started
- private pauseTime: number = 0 // Track where we paused
private currentToken: number = 0 // Unique token for each play request
- private isPaused: boolean = false
+ private isPlaying: boolean = false // Track whether audio is playing
constructor() {
this.initAudioContext()
@@ -18,13 +15,6 @@ export class AudioManager {
}
public async playAudio(url: string): Promise
{
- if (this.isPaused && this.currentBuffer) {
- // If paused, resume instead of reloading
- this.resume()
- return
- }
-
- this.pauseTime = 0 // Reset pause time for a new track
const playToken = ++this.currentToken // Update the token for this request
await this.initAudioContext()
@@ -34,69 +24,65 @@ export class AudioManager {
try {
const response = await fetch(url)
const arrayBuffer = await response.arrayBuffer()
+ // Before decoding, check if the token has changed
+ if (this.currentToken !== playToken) {
+ return // Abort this operation if a new play request has been made
+ }
+ const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer)
+
+ const source = this.audioContext.createBufferSource()
+ source.buffer = audioBuffer
+ source.connect(this.audioContext.destination)
+
+ // Again check the token before starting playback
if (this.currentToken !== playToken) {
return // Abort if a newer request has been made
}
- const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer)
- this.currentBuffer = audioBuffer // Save the buffer for potential pausing/resuming
- this.startPlayback(audioBuffer, 0) // Start playback from the beginning
+ source.start(0)
+ this.currentSource = source
+ this.isPlaying = true // Update the playing status
+
+ // Set the playing status to false when the audio ends
+ source.onended = () => {
+ if (this.currentToken === playToken) {
+ // Check to avoid race conditions
+ this.isPlaying = false
+ }
+ }
} catch (error) {
console.error('Error playing audio:', error)
+ this.isPlaying = false // Ensure status is accurate in case of error
}
}
}
- private startPlayback(buffer: AudioBuffer, offset: number) {
- const source = this.audioContext!.createBufferSource()
- source.buffer = buffer
- source.connect(this.audioContext!.destination)
- source.start(0, offset)
- this.startTime = this.audioContext!.currentTime - offset
- this.currentSource = source
- this.isPaused = false
-
- source.onended = () => {
- if (!this.isPaused) {
- this.currentBuffer = null // Clear the buffer if playback finishes normally
- }
- }
- }
-
- public pause() {
- if (!this.isPaused && this.currentSource && this.audioContext) {
- this.pauseTime = this.audioContext.currentTime - this.startTime
- this.currentSource.stop()
- this.isPaused = true
- }
- }
-
- public resume() {
- if (this.isPaused && this.currentBuffer) {
- this.startPlayback(this.currentBuffer, this.pauseTime)
- }
- }
-
public stopAudio() {
if (this.currentSource) {
this.currentSource.stop()
this.currentSource = null
- this.currentBuffer = null // Clear the current buffer
- this.isPaused = false
- this.pauseTime = 0
+ this.isPlaying = false // Update the playing status
}
}
+
+ // Method to check if audio is currently playing
+ public isAudioPlaying(): boolean {
+ return this.isPlaying
+ }
}
-// Usage example:
+// Usage example
const audioManager = new AudioManager()
-const audioUrl = 'https://example.com/path/to/your/audio/file.mp3'
+console.log(audioManager.isAudioPlaying()) // False, initially
-// To play the audio
-audioManager.playAudio(audioUrl)
+// To play audio
+audioManager
+ .playAudio('https://example.com/path/to/your/audio/file.mp3')
+ .then(() => {
+ console.log(audioManager.isAudioPlaying()) // Should log true when audio starts playing
+ })
-// To pause the audio
-audioManager.pause()
-
-// To resume the audio
-audioManager.resume()
+// Later, you can check if audio is still playing
+setTimeout(() => {
+ console.log(audioManager.isAudioPlaying()) // The result depends on the audio length and timing
+}, 1000)
diff --git a/client/src/lib/Dashboard/MediaPlayer/songList.ts b/client/src/lib/Dashboard/MediaPlayer/songList.ts
index d0a0dd6..8d2f288 100644
--- a/client/src/lib/Dashboard/MediaPlayer/songList.ts
+++ b/client/src/lib/Dashboard/MediaPlayer/songList.ts
@@ -5,10 +5,16 @@ export const songList: { [key: string]: SongData } = {
src: '/static/songs/danger-zone/audio.mp3',
coverImg: '/static/songs/danger-zone/cover.png',
},
- 'monko-zone': {
- title: 'Danger Zone',
- artist: 'Kenny Loggins',
- src: '/static/songs/danger-zone/audio.mp3',
- coverImg: '/static/songs/danger-zone/cover.png',
+ 'deja-vu': {
+ title: 'Deja Vu',
+ artist: 'Initial D',
+ src: '/static/songs/deja-vu/audio.m4a',
+ coverImg: '/static/songs/deja-vu/cover.jpg',
+ },
+ 'Xenogenesis': {
+ title: 'Xenogenesis',
+ artist: 'TheFatRat',
+ src: '/static/songs/xenogenesis/audio.m4a',
+ coverImg: '/static/songs/xenogenesis/cover.jpg',
},
}
diff --git a/client/src/lib/stores/musicStore.ts b/client/src/lib/stores/musicStore.ts
index b608c65..f990414 100644
--- a/client/src/lib/stores/musicStore.ts
+++ b/client/src/lib/stores/musicStore.ts
@@ -53,6 +53,11 @@ function createMusicStore() {
store.playing = !store.playing
return store
}),
+ rewind: () =>
+ update(store => {
+ store.currentIndex--
+ return store
+ }),
reset: () => set({ queue: [], currentIndex: 0, playing: false }),
}
}