make le diddy infinite radio better kinda
This commit is contained in:
parent
b75245648d
commit
71a2c5be93
3 changed files with 57 additions and 40 deletions
25
js/api.js
25
js/api.js
|
|
@ -1097,13 +1097,8 @@ export class LosslessAPI {
|
||||||
const recommendedTracks = [];
|
const recommendedTracks = [];
|
||||||
const seenTrackIds = new Set(tracks.map((t) => t.id));
|
const seenTrackIds = new Set(tracks.map((t) => t.id));
|
||||||
|
|
||||||
// Shuffle artists if refreshing to get different results
|
const shuffledArtists = [...artists].sort(() => Math.random() - 0.5);
|
||||||
let shuffledArtists = artists;
|
const artistsToProcess = shuffledArtists.slice(0, Math.min(15, shuffledArtists.length));
|
||||||
if (options.refresh) {
|
|
||||||
shuffledArtists = [...artists].sort(() => Math.random() - 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
const artistsToProcess = shuffledArtists.slice(0, Math.min(5, shuffledArtists.length));
|
|
||||||
|
|
||||||
const artistPromises = artistsToProcess.map(async (artist) => {
|
const artistPromises = artistsToProcess.map(async (artist) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -1111,11 +1106,19 @@ export class LosslessAPI {
|
||||||
const artistData = await this.getArtist(artist.id, { lightweight: true, skipCache: options.refresh });
|
const artistData = await this.getArtist(artist.id, { lightweight: true, skipCache: options.refresh });
|
||||||
if (artistData && artistData.tracks && artistData.tracks.length > 0) {
|
if (artistData && artistData.tracks && artistData.tracks.length > 0) {
|
||||||
const availableTracks = artistData.tracks.filter((track) => !seenTrackIds.has(track.id));
|
const availableTracks = artistData.tracks.filter((track) => !seenTrackIds.has(track.id));
|
||||||
// Shuffle and pick different tracks when refreshing
|
|
||||||
const shuffled = options.refresh
|
const newTracks = options.knownTrackIds
|
||||||
? availableTracks.sort(() => Math.random() - 0.5)
|
? availableTracks.filter(t => !options.knownTrackIds.has(t.id))
|
||||||
: availableTracks;
|
: availableTracks;
|
||||||
return shuffled.slice(0, 4);
|
const knownTracks = options.knownTrackIds
|
||||||
|
? availableTracks.filter(t => options.knownTrackIds.has(t.id))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const shuffledNew = [...newTracks].sort(() => Math.random() - 0.5);
|
||||||
|
const shuffledKnown = [...knownTracks].sort(() => Math.random() - 0.5);
|
||||||
|
|
||||||
|
const combined = [...shuffledNew, ...shuffledKnown];
|
||||||
|
return combined.slice(0, 2);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`No tracks found for artist ${artist.name}`);
|
console.warn(`No tracks found for artist ${artist.name}`);
|
||||||
return [];
|
return [];
|
||||||
|
|
|
||||||
56
js/player.js
56
js/player.js
|
|
@ -984,13 +984,15 @@ export class Player {
|
||||||
const pickedSeeds = await this.pickRadioSeeds();
|
const pickedSeeds = await this.pickRadioSeeds();
|
||||||
if (pickedSeeds.length > 0) {
|
if (pickedSeeds.length > 0) {
|
||||||
this.radioSeeds = pickedSeeds;
|
this.radioSeeds = pickedSeeds;
|
||||||
this.setQueue(pickedSeeds, 0, true);
|
const initialQueue = [...pickedSeeds].sort(() => 0.5 - Math.random()).slice(0, 5);
|
||||||
|
this.setQueue(initialQueue, 0, true);
|
||||||
this.playAtIndex(0);
|
this.playAtIndex(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.radioSeeds = Array.isArray(seeds) ? seeds : [seeds];
|
this.radioSeeds = Array.isArray(seeds) ? seeds : [seeds];
|
||||||
this.wipeQueue();
|
this.wipeQueue();
|
||||||
this.setQueue(this.radioSeeds, 0, true);
|
const initialQueue = Array.isArray(seeds) ? seeds.slice(0, 5) : [seeds];
|
||||||
|
this.setQueue(initialQueue, 0, true);
|
||||||
this.playAtIndex(0);
|
this.playAtIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1021,41 +1023,41 @@ export class Player {
|
||||||
this.radioSeeds = await this.pickRadioSeeds();
|
this.radioSeeds = await this.pickRadioSeeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
const seeds =
|
const shuffledSeeds = [...this.radioSeeds].sort(() => 0.5 - Math.random());
|
||||||
this.radioSeeds.length > 0 ? this.radioSeeds : this.currentTrack ? [this.currentTrack] : [];
|
const seeds = shuffledSeeds.length > 0
|
||||||
|
? shuffledSeeds.slice(0, 5)
|
||||||
|
: this.currentTrack ? [this.currentTrack] : [];
|
||||||
|
|
||||||
if (seeds.length === 0) {
|
if (seeds.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const recommendations = await this.api.getRecommendedTracksForPlaylist(seeds, 10);
|
const [favorites, userPlaylists, history] = await Promise.all([
|
||||||
|
db.getFavorites('track'),
|
||||||
|
db.getAll('user_playlists'),
|
||||||
|
db.getHistory(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const knownTrackIds = new Set([
|
||||||
|
...favorites.map((t) => t.id),
|
||||||
|
...userPlaylists.flatMap((p) => (p.tracks || []).map((t) => t.id)),
|
||||||
|
...history.map((t) => t.id),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const recommendations = await this.api.getRecommendedTracksForPlaylist(seeds, 20, {
|
||||||
|
knownTrackIds: knownTrackIds
|
||||||
|
});
|
||||||
|
|
||||||
if (recommendations && recommendations.length > 0) {
|
if (recommendations && recommendations.length > 0) {
|
||||||
const currentQueueIds = new Set(this.getCurrentQueue().map((t) => t.id));
|
const currentQueueIds = new Set(this.getCurrentQueue().map((t) => t.id));
|
||||||
|
|
||||||
const [favorites, userPlaylists, history] = await Promise.all([
|
let newTracks = recommendations.filter((t) => {
|
||||||
db.getFavorites('track'),
|
return !currentQueueIds.has(t.id);
|
||||||
db.getAll('user_playlists'),
|
|
||||||
db.getHistory(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const knownTrackIds = new Set([
|
|
||||||
...favorites.map((t) => t.id),
|
|
||||||
...userPlaylists.flatMap((p) => (p.tracks || []).map((t) => t.id)),
|
|
||||||
...history.map((t) => t.id),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const newTracks = recommendations.filter((t) => {
|
|
||||||
if (currentQueueIds.has(t.id)) return false;
|
|
||||||
|
|
||||||
if (knownTrackIds.has(t.id)) {
|
|
||||||
return Math.random() < 0.05;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (newTracks.length > 0) {
|
if (newTracks.length > 0) {
|
||||||
this.addToQueue(newTracks);
|
const tracksToAdd = newTracks.sort(() => 0.5 - Math.random()).slice(0, 5);
|
||||||
|
this.addToQueue(tracksToAdd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -1112,7 +1114,7 @@ export class Player {
|
||||||
potentialSeeds.find((s) => s.id === id)
|
potentialSeeds.find((s) => s.id === id)
|
||||||
);
|
);
|
||||||
|
|
||||||
return uniqueSeeds.sort(() => 0.5 - Math.random()).slice(0, 5);
|
return uniqueSeeds.sort(() => 0.5 - Math.random()).slice(0, 50);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to pick radio seeds:', error);
|
console.error('Failed to pick radio seeds:', error);
|
||||||
return this.currentTrack ? [this.currentTrack] : [];
|
return this.currentTrack ? [this.currentTrack] : [];
|
||||||
|
|
|
||||||
16
js/ui.js
16
js/ui.js
|
|
@ -2188,9 +2188,21 @@ export class UIRenderer {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const seeds = providedSeeds || (await this.getSeeds());
|
const seeds = providedSeeds || (await this.getSeeds());
|
||||||
const trackSeeds = seeds.slice(0, 5);
|
|
||||||
const recommendedTracks = await this.api.getRecommendedTracksForPlaylist(trackSeeds, 20, {
|
const [favorites, playlists, history] = await Promise.all([
|
||||||
|
db.getFavorites('track'),
|
||||||
|
db.getPlaylists(true),
|
||||||
|
db.getHistory(),
|
||||||
|
]);
|
||||||
|
const knownTrackIds = new Set([
|
||||||
|
...favorites.map(t => t.id),
|
||||||
|
...playlists.flatMap(p => (p.tracks || []).map(t => t.id)),
|
||||||
|
...history.map(t => t.id)
|
||||||
|
]);
|
||||||
|
|
||||||
|
const recommendedTracks = await this.api.getRecommendedTracksForPlaylist(seeds, 20, {
|
||||||
skipCache: forceRefresh,
|
skipCache: forceRefresh,
|
||||||
|
knownTrackIds: knownTrackIds
|
||||||
});
|
});
|
||||||
|
|
||||||
const filteredTracks = await this.filterUserContent(recommendedTracks, 'track');
|
const filteredTracks = await this.filterUserContent(recommendedTracks, 'track');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue