Skip to content

Commit c46a1d5

Browse files
authored
Merge pull request #27 from Absulit/dev
Player controls
2 parents 626cead + 646abab commit c46a1d5

3 files changed

Lines changed: 136 additions & 7 deletions

File tree

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# GRAVITY PULL
22

3-
An Audio Visualizer made with [POINTS](https://github.com/Absulit/points) a WebGPU library
3+
4+
[TRY GRAVITY PULL HERE](https://absulit.github.io/Gravity-Pull/)
5+
6+
An Audio Visualizer (and free audio player) made with [POINTS](https://github.com/Absulit/points) a WebGPU library
47

58
Load your favorite flac, mp3, ogg, m4a audio files
69

710

8-
[Live Demo here](https://absulit.github.io/Gravity-Pull/)
911

1012
![Alt Text](./docs/example1.webp)

src/main.js

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const MAXCHARS = 30;
1919
let audio = null;
2020
let loop = false;
2121
let pauseClickTimeout = null;
22+
let currentSong = null;
2223

2324
const options = {
2425
volume: 0.500,
@@ -48,8 +49,27 @@ function clickSong() {
4849
playSong(this);
4950
}
5051

52+
function assingMediaSession(song) {
53+
if ('mediaSession' in navigator) {
54+
console.log(song);
55+
56+
navigator.mediaSession.metadata = new MediaMetadata({
57+
title: song.title || song.name,
58+
artist: song.artist,
59+
album: song.album,
60+
});
61+
62+
if (song.artworkImageUrl) {
63+
navigator.mediaSession.metadata.artwork = [
64+
{ src: song.artworkImageUrl, sizes: '1024x1024', type: 'image/jpeg' }
65+
]
66+
}
67+
}
68+
}
69+
5170
async function playSong(song) {
5271
const { file } = song;
72+
currentSong = song;
5373
points.setUniform('showMessage', 0);
5474
const audioUrl = URL.createObjectURL(file);
5575
const name = song?.name || file.name;
@@ -69,6 +89,8 @@ async function playSong(song) {
6989
points.setUniform('artworkLoaded', artworkLoaded);
7090
audio.id = song?.id;
7191

92+
assingMediaSession(song);
93+
7294
audio.addEventListener('timeupdate', onTimeUpdate);
7395
audio.addEventListener('ended', async e => {
7496
const id = +e.target.id;
@@ -133,8 +155,8 @@ function loadFolder() {
133155
async function onCompleteTags(result) {
134156
const { tag, song } = result;
135157
const { file } = song;
136-
const { title, album, picture } = tag.tags;
137-
const albumExists = album?` - ${album}`: '';
158+
const { title, album, artist, picture } = tag.tags;
159+
const albumExists = album ? ` - ${album}` : '';
138160
const name = `${title}${albumExists}`
139161
let artworkImageUrl = null;
140162
let artworkColors = null;
@@ -153,16 +175,22 @@ async function onCompleteTags(result) {
153175
}
154176

155177
song.name = name || file.name;
156-
song.title = name;
178+
song.title = title;
179+
song.album = album;
180+
song.artist = artist;
181+
182+
assingMediaSession(song); // this is a duplicate call only on file load
157183

158184

159185
if (!song.default) {
160186
await db.songs.add({
161187
file,
162188
artworkImageUrl,
163189
artworkColors,
190+
title,
191+
album,
192+
artist,
164193
name: song.name,
165-
title: song.title
166194
});
167195
}
168196

@@ -224,18 +252,24 @@ const songs = [
224252
{
225253
default: true,
226254
name: 'Pulse 🎵',
255+
title: 'Pulse',
256+
artist: 'nickpanek620',
227257
src: './music/80s-pulse-synthwave-dude-212407.mp3',
228258
fn: clickSong
229259
},
230260
{
231261
default: true,
232262
name: 'Robot Swarm 🎵',
263+
title: 'Robot Swarm',
264+
artist: 'nickpanek620',
233265
src: './music/synthwave-80s-robot-swarm-218092.mp3',
234266
fn: clickSong
235267
},
236268
{
237269
default: true,
238270
name: 'Fading Echoes 🎵',
271+
title: 'Fading Echoes',
272+
artist: 'Mezhdunami',
239273
src: './music/mezhdunami-fading-echoes-129291.mp3',
240274
fn: clickSong
241275
}
@@ -295,6 +329,7 @@ songsFromDB.forEach(item => {
295329
artworkImageUrl: item.artworkImageUrl,
296330
name: item.name,
297331
title: item.title,
332+
artist: item.artist,
298333
src: audioUrl,
299334
fn: clickSong
300335
}
@@ -350,7 +385,7 @@ await points.setTextureImage('font', './src/img/inconsolata_regular_8x22.png');
350385

351386

352387
const size = { x: 8, y: 22 };
353-
const atlas = await loadImage('src/img/inconsolata_regular_8x22.png');
388+
const atlas = await loadImage('src/img/inconsolata_regular_8x22.png');
354389
const messageStringImg = strToImage('Select a song to Play', atlas, size);
355390
await points.setTextureImage('messageString', messageStringImg);
356391

@@ -455,3 +490,31 @@ async function loadSongFromURL() {
455490
}
456491

457492
loadSongFromURL()
493+
494+
495+
496+
// ----------------------------------
497+
498+
if ('mediaSession' in navigator) {
499+
navigator.mediaSession.setActionHandler('play', _ => audio?.play());
500+
navigator.mediaSession.setActionHandler('pause', _ => audio?.pause());
501+
502+
navigator.mediaSession.setActionHandler('stop', () => {
503+
audio.pause()
504+
audio.currentTime = 0; // Reset playback()
505+
assingMediaSession(currentSong);
506+
navigator.mediaSession.setActionHandler('play', _ => audio?.play());
507+
});
508+
509+
navigator.mediaSession.setActionHandler('previoustrack', _ => {
510+
const id = +currentSong.id;
511+
const nextSong = songs[id - 1] || songs[songs.length - 1];
512+
playSong(nextSong);
513+
});
514+
515+
navigator.mediaSession.setActionHandler('nexttrack', _ => {
516+
const id = +currentSong.id;
517+
const nextSong = songs[id + 1] || songs[0];
518+
playSong(nextSong);
519+
});
520+
}

todo.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
It sounds like your audio player is missing proper metadata handling and full media control integration. Here’s how you can fix these issues:
2+
1. Displaying Artist and Album Art
3+
4+
Linux Mint relies on the Media Session API to retrieve metadata for the audio controls. Ensure your JavaScript player sets this correctly:
5+
6+
```js
7+
if ('mediaSession' in navigator) {
8+
navigator.mediaSession.metadata = new MediaMetadata({
9+
title: 'Your Song Title',
10+
artist: 'Your Artist Name',
11+
album: 'Your Album Name',
12+
artwork: [
13+
{ src: 'album-art-url.jpg', sizes: '512x512', type: 'image/jpeg' }
14+
]
15+
});
16+
}
17+
```
18+
19+
20+
21+
Make sure the album-art-url.jpg is a valid image path.
22+
2. Improving Media Controls (Play, Pause, Stop)
23+
24+
By default, Linux Mint integrates system-wide media controls through the Media Session API. You can add better handlers like this:
25+
26+
27+
```js
28+
29+
if ('mediaSession' in navigator) {
30+
navigator.mediaSession.setActionHandler('play', () => {
31+
audioElement.play();
32+
});
33+
34+
navigator.mediaSession.setActionHandler('pause', () => {
35+
audioElement.pause();
36+
});
37+
38+
navigator.mediaSession.setActionHandler('stop', () => {
39+
audioElement.pause();
40+
audioElement.currentTime = 0; // Reset playback
41+
});
42+
43+
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
44+
audioElement.currentTime -= details.seekOffset || 10;
45+
});
46+
47+
navigator.mediaSession.setActionHandler('seekforward', (details) => {
48+
audioElement.currentTime += details.seekOffset || 10;
49+
});
50+
}
51+
52+
53+
```
54+
55+
56+
57+
58+
3. Fixing Stop Functionality
59+
60+
Your stop function likely prevents restart because the audio is fully reset. If you want to allow playback again, ensure audioElement.src isn't reset when stopping.
61+
62+
If you are still having issues, you might need to check if your audio player correctly initializes the audioElement every time it is interacted with.
63+
64+
This should get your player fully functional with system controls. Let me know if anything else is acting up!

0 commit comments

Comments
 (0)