Merge branch 'main' of github.com:monochrome-music/monochrome
This commit is contained in:
commit
2a6c763176
15 changed files with 696 additions and 244 deletions
|
|
@ -7,7 +7,7 @@
|
|||
"postCreateCommand": "git config --local core.editor \"code --wait\" && git config --local commit.gpgsign false && npm install && bun install",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
|
||||
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "anthropic.claude-code"]
|
||||
}
|
||||
},
|
||||
"mounts": ["source=${env:HOME}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,consistency=cached"]
|
||||
|
|
|
|||
26
index.html
26
index.html
|
|
@ -3825,6 +3825,32 @@
|
|||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Fullscreen Cover Tilt</span>
|
||||
<span class="description"
|
||||
>3D tilt effect on album cover in fullscreen view</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="fullscreen-tilt-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Preload Next Track</span>
|
||||
<span class="description">Seconds before track ends to start loading next</span>
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
id="preload-time-input"
|
||||
min="5"
|
||||
max="60"
|
||||
value="15"
|
||||
style="width: 60px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
|
|
|
|||
13
js/api.js
13
js/api.js
|
|
@ -1751,6 +1751,7 @@ export class LosslessAPI {
|
|||
|
||||
const { lookup, enrichedTrack, isVideo } = await this.enrichTrack(track, { downloadQuality });
|
||||
|
||||
let postProcessingQuality = lookup.info?.audioQuality ?? null;
|
||||
let streamUrl;
|
||||
let blob;
|
||||
|
||||
|
|
@ -1783,6 +1784,10 @@ export class LosslessAPI {
|
|||
const manifest = await fetch(stream.url, { signal: options.signal });
|
||||
const manifestText = await manifest.text();
|
||||
streamUrl = this.extractStreamUrlFromManifest(btoa(manifestText));
|
||||
|
||||
if (streamUrl) {
|
||||
postProcessingQuality = 'DOLBY_ATMOS';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to extract Dolby Atmos stream URL:', err);
|
||||
}
|
||||
|
|
@ -1878,13 +1883,7 @@ export class LosslessAPI {
|
|||
}
|
||||
|
||||
if (!isVideo) {
|
||||
blob = await applyAudioPostProcessing(
|
||||
blob,
|
||||
quality,
|
||||
onProgress,
|
||||
options.signal,
|
||||
track?.audioQuality ?? null
|
||||
);
|
||||
blob = await applyAudioPostProcessing(blob, quality, onProgress, options.signal, postProcessingQuality);
|
||||
}
|
||||
|
||||
// Add metadata if track information is provided
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ export async function applyAudioPostProcessing(
|
|||
if (format) {
|
||||
try {
|
||||
blob = await transcodeWithCustomFormat(blob, format, onProgress, signal);
|
||||
|
||||
return blob;
|
||||
} catch (encodingError) {
|
||||
if (onProgress) {
|
||||
onProgress({
|
||||
|
|
|
|||
|
|
@ -238,6 +238,10 @@ export function updateDownloadProgress(trackId, progress) {
|
|||
progressFill.style.background = '#3b82f6'; // Blue for encoding
|
||||
statusEl.textContent = `Converting: ${percent}%`;
|
||||
} else if (progress instanceof ProgressMessage || progress.message) {
|
||||
if (progress instanceof FfmpegProgress && (progress.stage == 'parsing' || progress.stage == 'stdout')) {
|
||||
return;
|
||||
}
|
||||
|
||||
progressFill.style.width = '100%';
|
||||
progressFill.style.background = '#3b82f6';
|
||||
statusEl.textContent = progress.message;
|
||||
|
|
@ -961,7 +965,7 @@ function updateBulkDownloadProgress(notifEl, current, total, currentItem, progre
|
|||
}
|
||||
|
||||
if (progress instanceof FfmpegProgress) {
|
||||
if (progress.stage == 'stdout') {
|
||||
if (progress.stage == 'stdout' || progress.stage == 'parsing') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1868,8 +1868,9 @@ export async function handleTrackAction(
|
|||
} else if (action === 'block-album') {
|
||||
const { contentBlockingSettings } = await import('./storage.js');
|
||||
const albumId = type === 'album' ? item.id : item.album?.id;
|
||||
const albumTitle = type === 'album' ? (item.title || item.name) : (item.album?.title || item.album?.name);
|
||||
const albumArtist = type === 'album' ? (item.artist?.name || item.artist) : (item.album?.artist?.name || item.album?.artist);
|
||||
const albumTitle = type === 'album' ? item.title || item.name : item.album?.title || item.album?.name;
|
||||
const albumArtist =
|
||||
type === 'album' ? item.artist?.name || item.artist : item.album?.artist?.name || item.album?.artist;
|
||||
|
||||
if (!albumId) {
|
||||
showNotification('No album information available');
|
||||
|
|
|
|||
15
js/ffmpeg.js
15
js/ffmpeg.js
|
|
@ -55,11 +55,13 @@ async function ffmpegWorker(
|
|||
const assets = loadFfmpeg();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let endCategory = null;
|
||||
const worker = new FfmpegWorker();
|
||||
|
||||
// Handle abort signal
|
||||
const abortHandler = () => {
|
||||
worker.terminate();
|
||||
endCategory?.();
|
||||
reject(new FfmpegError('FFMPEG aborted'));
|
||||
};
|
||||
|
||||
|
|
@ -72,20 +74,30 @@ async function ffmpegWorker(
|
|||
}
|
||||
|
||||
worker.onmessage = (e) => {
|
||||
const { type, blob, message, stage, progress } = e.data;
|
||||
const { type, blob, message, stage, progress, command } = e.data;
|
||||
|
||||
if (type === 'complete') {
|
||||
if (signal) signal.removeEventListener('abort', abortHandler);
|
||||
worker.terminate();
|
||||
endCategory?.();
|
||||
resolve(blob);
|
||||
} else if (type === 'error') {
|
||||
if (signal) signal.removeEventListener('abort', abortHandler);
|
||||
worker.terminate();
|
||||
endCategory?.();
|
||||
reject(new FfmpegError(message));
|
||||
} else if (type === 'progress' && message) {
|
||||
onProgress?.(new FfmpegProgress(stage, progress || 0, message));
|
||||
} else if (type === 'progress' && stage != 'loading' && progress !== null) {
|
||||
onProgress?.(new FfmpegProgress(stage, progress || 0, message));
|
||||
} else if (type === 'command') {
|
||||
if (logConsole) {
|
||||
const consoleCategory = `ffmpeg ${command?.join(' ')}`;
|
||||
// eslint-disable-next-line no-console
|
||||
console.groupCollapsed(consoleCategory);
|
||||
// eslint-disable-next-line no-console
|
||||
endCategory = () => console.groupEnd();
|
||||
}
|
||||
} else if (type === 'log') {
|
||||
onProgress?.(new FfmpegProgress('stdout', 0, message));
|
||||
if (logConsole) {
|
||||
|
|
@ -97,6 +109,7 @@ async function ffmpegWorker(
|
|||
worker.onerror = (error) => {
|
||||
if (signal) signal.removeEventListener('abort', abortHandler);
|
||||
worker.terminate();
|
||||
endCategory?.();
|
||||
reject(new FfmpegError('Worker failed: ' + error.message));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export class FfmpegProgress implements MonochromeProgress {
|
||||
constructor(
|
||||
public readonly stage: 'loading' | 'encoding' | 'finalizing' | 'stdout',
|
||||
public readonly stage: 'loading' | 'parsing' | 'encoding' | 'finalizing' | 'stdout',
|
||||
public readonly progress: number,
|
||||
public readonly message?: string
|
||||
) {}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ async function loadFFmpeg(loadOptions = {}) {
|
|||
ffmpeg = new FFmpeg();
|
||||
|
||||
ffmpeg.on('log', ({ message }) => {
|
||||
self.postMessage({ type: 'log', message });
|
||||
self.postMessage({ type: 'log', stage: 'stdout', message });
|
||||
|
||||
// Try to extract total duration from input log
|
||||
if (totalDurationSeconds === null) {
|
||||
|
|
@ -124,7 +124,7 @@ self.onmessage = async (e) => {
|
|||
}
|
||||
|
||||
const ffmpegArgs = ['-i', 'input', ...args, ...(output.name ? [output.name] : [])];
|
||||
self.postMessage({ type: 'log', message: `FFmpeg command: ffmpeg ${ffmpegArgs.join(' ')}` });
|
||||
self.postMessage({ type: 'command', command: ffmpegArgs });
|
||||
|
||||
const exitCode = await ffmpeg.exec(ffmpegArgs);
|
||||
|
||||
|
|
|
|||
30
js/player.js
30
js/player.js
|
|
@ -16,6 +16,7 @@ import {
|
|||
exponentialVolumeSettings,
|
||||
audioEffectsSettings,
|
||||
radioSettings,
|
||||
playbackSettings,
|
||||
} from './storage.js';
|
||||
import { audioContextManager } from './audio-context.js';
|
||||
import { isIos, isSafari } from './platform-detection.js';
|
||||
|
|
@ -48,6 +49,7 @@ export class Player {
|
|||
this.repeatMode = REPEAT_MODE.OFF;
|
||||
this.preloadCache = new Map();
|
||||
this.preloadAbortController = null;
|
||||
this._lastPreloadTime = null;
|
||||
this.currentTrack = null;
|
||||
this.currentRgValues = null;
|
||||
this.userVolume = parseFloat(localStorage.getItem('volume') || '0.7');
|
||||
|
|
@ -106,7 +108,6 @@ export class Player {
|
|||
bufferingGoal: 30,
|
||||
rebufferingGoal: 2,
|
||||
bufferBehind: 30,
|
||||
jumpLargeGaps: true,
|
||||
},
|
||||
abr: {
|
||||
enabled: true,
|
||||
|
|
@ -150,7 +151,6 @@ export class Player {
|
|||
document.addEventListener('visibilitychange', () => {
|
||||
const el = this.activeElement;
|
||||
if (document.visibilityState === 'visible' && !el.paused) {
|
||||
// Ensure audio context is resumed when user returns to the app
|
||||
if (!audioContextManager.isReady()) {
|
||||
audioContextManager.init(el);
|
||||
}
|
||||
|
|
@ -162,6 +162,17 @@ export class Player {
|
|||
}
|
||||
});
|
||||
|
||||
// Time-based preload trigger for Safari background playback
|
||||
this._timeUpdateHandler = this._handleTimeUpdateForPreload.bind(this);
|
||||
this.audio.addEventListener('timeupdate', this._timeUpdateHandler);
|
||||
if (this.video) {
|
||||
this.video.addEventListener('timeupdate', this._timeUpdateHandler);
|
||||
}
|
||||
|
||||
window.addEventListener('preload-time-change', () => {
|
||||
this._lastPreloadTime = null;
|
||||
});
|
||||
|
||||
this._setupVideoSync();
|
||||
}
|
||||
|
||||
|
|
@ -516,6 +527,21 @@ export class Player {
|
|||
}
|
||||
}
|
||||
|
||||
_handleTimeUpdateForPreload() {
|
||||
const el = this.activeElement;
|
||||
if (!el || !el.duration || el.paused) return;
|
||||
|
||||
const preloadTime = playbackSettings.getPreloadTime();
|
||||
const timeRemaining = el.duration - el.currentTime;
|
||||
if (timeRemaining <= preloadTime && timeRemaining > 0) {
|
||||
const now = Date.now();
|
||||
if (!this._lastPreloadTime || now - this._lastPreloadTime > 5000) {
|
||||
this._lastPreloadTime = now;
|
||||
this.preloadNextTracks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async setupHlsVideo(video, result, fallbackImg) {
|
||||
const url = result.videoUrl || result.hlsUrl || result;
|
||||
const Hls = (await import('hls.js')).default;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import {
|
|||
visualizerSettings,
|
||||
playlistSettings,
|
||||
equalizerSettings,
|
||||
playbackSettings,
|
||||
listenBrainzSettings,
|
||||
malojaSettings,
|
||||
libreFmSettings,
|
||||
|
|
@ -1111,6 +1112,27 @@ export async function initializeSettings(scrobbler, player, api, ui) {
|
|||
});
|
||||
}
|
||||
|
||||
// Fullscreen Cover Tilt Toggle
|
||||
const fullscreenTiltToggle = document.getElementById('fullscreen-tilt-toggle');
|
||||
if (fullscreenTiltToggle) {
|
||||
fullscreenTiltToggle.checked = playbackSettings.isFullscreenTiltEnabled();
|
||||
fullscreenTiltToggle.addEventListener('change', (e) => {
|
||||
playbackSettings.setFullscreenTiltEnabled(e.target.checked);
|
||||
window.dispatchEvent(new CustomEvent('fullscreen-tilt-toggle', { detail: { enabled: e.target.checked } }));
|
||||
});
|
||||
}
|
||||
|
||||
// Preload Time Input
|
||||
const preloadTimeInput = document.getElementById('preload-time-input');
|
||||
if (preloadTimeInput) {
|
||||
preloadTimeInput.value = playbackSettings.getPreloadTime();
|
||||
preloadTimeInput.addEventListener('change', (e) => {
|
||||
const val = Math.max(5, Math.min(60, parseInt(e.target.value, 10) || 15));
|
||||
playbackSettings.setPreloadTime(val);
|
||||
window.dispatchEvent(new CustomEvent('preload-time-change', { detail: { seconds: val } }));
|
||||
});
|
||||
}
|
||||
|
||||
// ReplayGain Settings
|
||||
const replayGainMode = document.getElementById('replay-gain-mode');
|
||||
if (replayGainMode) {
|
||||
|
|
@ -3732,7 +3754,7 @@ function initializeBlockedContentManager() {
|
|||
if (typeof showNotification === 'function') {
|
||||
showNotification(`Unblocked ${type}: ${itemName}`);
|
||||
}
|
||||
|
||||
|
||||
renderBlockedLists();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -999,6 +999,36 @@ export const visualizerSettings = {
|
|||
},
|
||||
};
|
||||
|
||||
export const playbackSettings = {
|
||||
FULLSCREEN_TILT_KEY: 'playback-fullscreen-tilt',
|
||||
PRELOAD_TIME_KEY: 'playback-preload-time',
|
||||
|
||||
isFullscreenTiltEnabled() {
|
||||
try {
|
||||
return localStorage.getItem(this.FULLSCREEN_TILT_KEY) !== 'false';
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
setFullscreenTiltEnabled(enabled) {
|
||||
localStorage.setItem(this.FULLSCREEN_TILT_KEY, enabled ? 'true' : 'false');
|
||||
},
|
||||
|
||||
getPreloadTime() {
|
||||
try {
|
||||
const val = localStorage.getItem(this.PRELOAD_TIME_KEY);
|
||||
return val ? parseInt(val, 10) : 15;
|
||||
} catch {
|
||||
return 15;
|
||||
}
|
||||
},
|
||||
|
||||
setPreloadTime(seconds) {
|
||||
localStorage.setItem(this.PRELOAD_TIME_KEY, seconds.toString());
|
||||
},
|
||||
};
|
||||
|
||||
export const equalizerSettings = {
|
||||
ENABLED_KEY: 'equalizer-enabled',
|
||||
GAINS_KEY: 'equalizer-gains',
|
||||
|
|
|
|||
76
js/ui.js
76
js/ui.js
|
|
@ -26,6 +26,7 @@ import {
|
|||
fontSettings,
|
||||
contentBlockingSettings,
|
||||
settingsUiState,
|
||||
playbackSettings,
|
||||
} from './storage.js';
|
||||
import { db } from './db.js';
|
||||
import { getVibrantColorFromImage } from './vibrant-color.js';
|
||||
|
|
@ -150,6 +151,9 @@ export class UIRenderer {
|
|||
this.lastRecommendedTracks = [];
|
||||
this.currentArtistId = null;
|
||||
|
||||
this._handleTiltMove = this._handleTiltMove.bind(this);
|
||||
this._handleTiltLeave = this._handleTiltLeave.bind(this);
|
||||
|
||||
// Listen for dynamic color reset events
|
||||
window.addEventListener('reset-dynamic-color', () => {
|
||||
this.resetVibrantColor();
|
||||
|
|
@ -708,7 +712,7 @@ export class UIRenderer {
|
|||
return this.createBaseCardHTML({
|
||||
type: 'album',
|
||||
id: album.id,
|
||||
href: `/album/${album.id}`,
|
||||
href: album._href || `/album/${album.id}`,
|
||||
title: `${escapeHtml(album.title)} ${explicitBadge} ${qualityBadge}`,
|
||||
subtitle: `${escapeHtml(artistName)} • ${yearDisplay}${typeLabel}`,
|
||||
imageHTML: this.getCoverHTML(
|
||||
|
|
@ -1227,6 +1231,14 @@ export class UIRenderer {
|
|||
|
||||
overlay.style.display = 'flex';
|
||||
|
||||
// Apply vanilla-tilt effect to fullscreen cover if enabled
|
||||
this._applyFullscreenTilt(overlay);
|
||||
|
||||
// Listen for tilt setting changes
|
||||
window.addEventListener('fullscreen-tilt-toggle', (e) => {
|
||||
this._applyFullscreenTilt(overlay, e.detail.enabled);
|
||||
});
|
||||
|
||||
const startVisualizer = async () => {
|
||||
if (!visualizerSettings.isEnabled()) {
|
||||
if (this.visualizer) this.visualizer.stop();
|
||||
|
|
@ -1320,6 +1332,46 @@ export class UIRenderer {
|
|||
clearTimeout(this.uiToggleMouseTimer);
|
||||
this.uiToggleMouseTimer = null;
|
||||
}
|
||||
|
||||
// Clean up vanilla-tilt if applied
|
||||
this._removeFullscreenTilt();
|
||||
}
|
||||
|
||||
_applyFullscreenTilt(overlay, enabled = playbackSettings.isFullscreenTiltEnabled()) {
|
||||
const image = document.getElementById('fullscreen-cover-image');
|
||||
if (!image) return;
|
||||
|
||||
this._removeFullscreenTilt();
|
||||
|
||||
if (!enabled) return;
|
||||
|
||||
image.addEventListener('mousemove', this._handleTiltMove);
|
||||
image.addEventListener('mouseleave', this._handleTiltLeave);
|
||||
}
|
||||
|
||||
_handleTiltMove(e) {
|
||||
const image = e.target;
|
||||
const rect = image.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
const rotateX = ((y - centerY) / centerY) * -10;
|
||||
const rotateY = ((x - centerX) / centerX) * 10;
|
||||
|
||||
image.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.02)`;
|
||||
}
|
||||
|
||||
_handleTiltLeave(e) {
|
||||
e.target.style.transform = 'perspective(1000px) rotateX(0) rotateY(0) scale(1)';
|
||||
}
|
||||
|
||||
_removeFullscreenTilt() {
|
||||
const image = document.getElementById('fullscreen-cover-image');
|
||||
if (!image) return;
|
||||
image.removeEventListener('mousemove', this._handleTiltMove);
|
||||
image.removeEventListener('mouseleave', this._handleTiltLeave);
|
||||
image.style.transform = '';
|
||||
}
|
||||
|
||||
setupUIToggleButton(overlay) {
|
||||
|
|
@ -2569,6 +2621,28 @@ export class UIRenderer {
|
|||
itemsToStore.push({ el: null, data: result.album, type: 'album' });
|
||||
}
|
||||
}
|
||||
} else if (item.type === 'userplaylist') {
|
||||
if (item.id && item.title) {
|
||||
const playlist = {
|
||||
id: item.id,
|
||||
name: item.title,
|
||||
cover: item.cover,
|
||||
numberOfTracks: item.numberOfTracks || 0,
|
||||
};
|
||||
cardsHTML.push(
|
||||
this.createAlbumCardHTML({
|
||||
...playlist,
|
||||
title: item.title,
|
||||
artist: item.artist,
|
||||
cover: item.cover,
|
||||
explicit: item.explicit,
|
||||
releaseDate: item.releaseDate,
|
||||
type: 'ALBUM',
|
||||
_href: `/userplaylist/${item.id}`,
|
||||
})
|
||||
);
|
||||
itemsToStore.push({ el: null, data: playlist, type: 'user-playlist' });
|
||||
}
|
||||
} else if (item.type === 'artist') {
|
||||
if (item.name && item.picture) {
|
||||
// Use cached data directly
|
||||
|
|
|
|||
|
|
@ -1,299 +1,189 @@
|
|||
[
|
||||
{
|
||||
"type": "album",
|
||||
"id": 18083938,
|
||||
"title": "The Glow, Pt. 2",
|
||||
"artist": { "id": 3941394, "name": "The Microphones" },
|
||||
"releaseDate": "2001-09-25",
|
||||
"cover": "ec648c22-9140-41d3-a7ae-0ba69ef0420e",
|
||||
"id": 510893864,
|
||||
"title": "BULLY",
|
||||
"artist": { "id": 25022, "name": "Kanye West" },
|
||||
"releaseDate": "2026-03-28",
|
||||
"cover": "cf2f2c9c-ff67-44f6-83aa-a7622f8c6b64",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 403172104,
|
||||
"title": "From A Man's Perspective",
|
||||
"artist": { "id": 3561564, "name": "Dax" },
|
||||
"releaseDate": "2024-12-06",
|
||||
"cover": "c52a53ea-f021-44bf-8cef-fb31d3b82940",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 341529881,
|
||||
"title": "FACTS",
|
||||
"artist": { "id": 5691796, "name": "Tom MacDonald" },
|
||||
"releaseDate": "2024-01-26",
|
||||
"cover": "34198718-cc7d-47eb-9bf1-1dc5c26fc8a1",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 382839956,
|
||||
"title": "my anti-aircraft friend",
|
||||
"artist": { "id": 19359095, "name": "julie" },
|
||||
"releaseDate": "2024-09-13",
|
||||
"cover": "ac790b52-61cc-460c-9277-bdac88722cc3",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 456475370,
|
||||
"title": "It Aint Nun",
|
||||
"artist": { "id": 9981740, "name": "CHRIST DILLINGER" },
|
||||
"releaseDate": "2024-09-12",
|
||||
"cover": "3ffc27f6-a77c-4e68-ba44-e04f034783be",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 112547160,
|
||||
"title": "R F Y",
|
||||
"artist": { "id": 36042731, "name": "RFY" },
|
||||
"releaseDate": "2019-06-27",
|
||||
"cover": "ffe3f6f9-5bc8-4b53-99c3-9b83676c099a",
|
||||
"id": 452163300,
|
||||
"title": "Tackle Box",
|
||||
"artist": { "id": 44771714, "name": "JamWayne" },
|
||||
"releaseDate": "2025-09-01",
|
||||
"cover": "bf7d2e55-52dc-4e41-9f53-1db31918798e",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 18658568,
|
||||
"title": "100% Ghetto 4",
|
||||
"artist": { "id": 4191963, "name": "DJ Clent" },
|
||||
"releaseDate": "2010-10-02",
|
||||
"cover": "82b839bd-7cf6-4650-bade-192f47301ffd",
|
||||
"id": 106210035,
|
||||
"title": "Supermarket (Soundtrack)",
|
||||
"artist": { "id": 3533999, "name": "LOGIC" },
|
||||
"releaseDate": "2019-03-26",
|
||||
"cover": "bdd39738-7177-4836-bd7f-cd4fe4ccf535",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 504004321,
|
||||
"title": "Half Blood (BloodLuxe)",
|
||||
"artist": { "id": 50799233, "name": "slayr" },
|
||||
"releaseDate": "2025-11-05",
|
||||
"cover": "2767cc63-7e92-4a48-aa4b-806a3ea7ec1c",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 89313048,
|
||||
"title": "DAYTONA",
|
||||
"artist": { "id": 3972883, "name": "Pusha T" },
|
||||
"releaseDate": "2018-05-25",
|
||||
"cover": "30288caf-2bdd-4511-a95c-57117936b2b6",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 324660713,
|
||||
"title": "JOECHILLWORLD",
|
||||
"artist": { "id": 3972883, "name": "Devon Hendryx" },
|
||||
"releaseDate": "2010-08-10",
|
||||
"cover": "25d45544-3e82-4184-b8c2-2c2c6f0f152a",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 418729278,
|
||||
"title": "I LAY DOWN MY LIFE FOR YOU: DIRECTOR'S CUT",
|
||||
"artist": { "id": 7958797, "name": "JPEGMAFIA" },
|
||||
"releaseDate": "2025-02-03",
|
||||
"cover": "9c84302b-2584-4c0a-9db7-e648542f459f",
|
||||
"id": 138458381,
|
||||
"title": "JOKER",
|
||||
"artist": { "id": 39109746, "name": "Dax" },
|
||||
"releaseDate": "2020-05-06",
|
||||
"cover": "d6a39491-fece-4594-a538-9cfbce7c6c68",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 118353565,
|
||||
"title": "Dyn-O-Mite",
|
||||
"artist": { "id": 5755811, "name": "ZelooperZ" },
|
||||
"releaseDate": "2019-05-18",
|
||||
"cover": "c42f0025-9839-4dd2-b5de-9fd05ed5e917",
|
||||
"id": 318467376,
|
||||
"title": "The Draco Tape 2",
|
||||
"artist": { "id": 22467779, "name": "60PERCENTHOMO" },
|
||||
"releaseDate": "2023-09-30",
|
||||
"cover": "9169e8ab-fdb0-49d1-a14f-82a2b541223c",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 4527433,
|
||||
"title": "Flockaveli",
|
||||
"artist": { "id": 3654061, "name": "Waka Flocka Flame" },
|
||||
"releaseDate": "2010-10-05",
|
||||
"cover": "05702b51-45cf-4157-b9ed-dd7ca7e7b7b3",
|
||||
"id": 456582219,
|
||||
"title": "bbno$",
|
||||
"artist": { "id": 8173944, "name": "bbno$" },
|
||||
"releaseDate": "2025-10-17",
|
||||
"cover": "8162c739-4bb2-4218-8915-93cb1f0d9eea",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 90502209,
|
||||
"title": "NASIR",
|
||||
"artist": { "id": 1003, "name": "Nas" },
|
||||
"releaseDate": "2018-06-15",
|
||||
"cover": "503ea6b2-0829-438e-8e4e-9a988154b3bc",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 413189044,
|
||||
"title": "Jump Out",
|
||||
"artist": { "id": 27836827, "name": "OsamaSon" },
|
||||
"releaseDate": "2025-01-24",
|
||||
"cover": "ec4a4ef2-69fe-4d3c-aaba-05dc2d546e84",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 209061256,
|
||||
"title": "Super Tecmo Bo",
|
||||
"artist": { "id": 4839917, "name": "Boldy James" },
|
||||
"releaseDate": "2021-12-17",
|
||||
"cover": "f58ca804-1da7-4953-a26d-2b3258310db5",
|
||||
"id": 506216548,
|
||||
"title": "Declassified",
|
||||
"artist": { "id": 5691796, "name": "Tom MacDonald" },
|
||||
"releaseDate": "2026-03-13",
|
||||
"cover": "5cf188e5-1660-4a01-bacc-10ca81e7af73",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 488297983,
|
||||
"title": "So Much Country 'Till We Get There",
|
||||
"artist": { "id": 51427239, "name": "Westside Cowboy" },
|
||||
"id": 486673299,
|
||||
"title": "Novelty",
|
||||
"artist": { "id": 3589848, "name": "Goofy" },
|
||||
"releaseDate": "2026-01-23",
|
||||
"cover": "dd9d4f23-1517-4a76-8e3f-31e341dcd525",
|
||||
"cover": "dd543595-e604-440e-a24c-e2eaccda3804",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 440469641,
|
||||
"title": "Tha Carter VI",
|
||||
"artist": { "id": 27518, "name": "Lil Wayne" },
|
||||
"releaseDate": "2025-06-06",
|
||||
"cover": "f2807cfe-6df8-4ea0-ab32-fd0ad9e91072",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 384057608,
|
||||
"title": "FREE VIPER!",
|
||||
"artist": { "id": 10285483, "name": "Viper" },
|
||||
"releaseDate": "2024-08-28",
|
||||
"cover": "642d73d9-2a45-4598-bec3-033a09181bdf",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 460015533,
|
||||
"title": "CHARLIE",
|
||||
"artist": { "id": 5691796, "name": "Tom MacDonald" },
|
||||
"releaseDate": "2025-09-11",
|
||||
"cover": "18180e3d-e178-4bd3-aada-e26ca32bc8f4",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 447277344,
|
||||
"title": "REST IN BASS",
|
||||
"artist": { "id": 50418386, "name": "Che" },
|
||||
"releaseDate": "2025-07-18",
|
||||
"cover": "d1397066-72ed-4481-b508-77f7c7a03073",
|
||||
"id": 123319314,
|
||||
"title": "BABY G.O.A.T.",
|
||||
"artist": { "id": 9160626, "name": "Kevo Muney" },
|
||||
"releaseDate": "2019-12-12",
|
||||
"cover": "6c87aee6-76da-413e-a639-79b670b3e3d1",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 490209783,
|
||||
"title": "My Ghosts Go Ghost",
|
||||
"artist": { "id": 39920098, "name": "By Storm" },
|
||||
"releaseDate": "2026-01-30",
|
||||
"cover": "bc470b88-3583-4853-976e-593855672322",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 279082597,
|
||||
"title": "Noktifer's Symphony",
|
||||
"artist": { "id": 22055243, "name": "axxturel" },
|
||||
"releaseDate": "2020-11-17",
|
||||
"cover": "a886acd8-b915-4a77-9c1f-eecf7fa6091c",
|
||||
"id": 510493672,
|
||||
"title": "ADL",
|
||||
"artist": { "id": 9318056, "name": "Yeat" },
|
||||
"releaseDate": "2026-03-27",
|
||||
"cover": "b799025a-7ff6-494c-aa11-5e0461bbca40",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 380211863,
|
||||
"title": "Sayso Says",
|
||||
"artist": { "id": 50418386, "name": "Che" },
|
||||
"releaseDate": "2024-08-30",
|
||||
"cover": "917c7e0f-3ebb-471e-9c88-fcdf6a9f21a5",
|
||||
"id": 440096189,
|
||||
"title": "Rebel",
|
||||
"artist": { "id": 52081927, "name": "EsDeeKid" },
|
||||
"releaseDate": "2025-06-20",
|
||||
"cover": "3433b56c-6386-4e21-90ee-f2369d4bfde7",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 464463900,
|
||||
"title": "A-Rhythm Absolute",
|
||||
"artist": { "id": 30049790, "name": "Sunday Mourners" },
|
||||
"releaseDate": "2026-01-16",
|
||||
"cover": "d04e2ed8-f6d7-43c0-bcb2-fb99d3de0d5d",
|
||||
"id": 85287313,
|
||||
"title": "Toilet",
|
||||
"artist": { "id": 9598562, "name": "Clown Core" },
|
||||
"releaseDate": "2018-03-03",
|
||||
"cover": "d6d32464-864e-422f-b8c3-0c30baa563b1",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": "344201347",
|
||||
"title": "Flex Musix (FLXTRA)",
|
||||
"artist": { "id": 27836827, "name": "OsamaSon" },
|
||||
"releaseDate": "2024-02-16",
|
||||
"cover": "5d1812fc-b9f9-4467-ac78-90d78ea542e4",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 365819314,
|
||||
"title": "One Life",
|
||||
"artist": { "id": "17300439", "name": "1oneam" },
|
||||
"releaseDate": "2024-05-30",
|
||||
"cover": "eb5d74f6-7403-4404-8452-9b68713445fe",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 379517195,
|
||||
"title": "Haram",
|
||||
"artist": { "id": 5225704, "name": "Armand Hammer" },
|
||||
"releaseDate": "2021-03-26",
|
||||
"cover": "69ebc3e7-bd0b-4dd7-88a5-a2e180b84f0d",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 36160524,
|
||||
"title": "Nasa Gang (Remastered)",
|
||||
"artist": { "id": 4611745, "name": "SpaceGhostPurrp" },
|
||||
"releaseDate": "2014-10-07",
|
||||
"cover": "359d42ec-1984-4d63-a4ae-ecf286463372",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 445752470,
|
||||
"title": "FOR NOTHING",
|
||||
"artist": { "id": 49124576, "name": "nine vicious" },
|
||||
"releaseDate": "2025-07-04",
|
||||
"cover": "8b9018dd-d3c3-46e0-be5a-c16d48180176",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 435083611,
|
||||
"title": "Buddha Therapy",
|
||||
"artist": { "id": 4858188, "name": "Metro Zu" },
|
||||
"releaseDate": "2017-05-01",
|
||||
"cover": "5c6c367a-99ed-4fa4-8e91-ea10d6066e26",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 473188494,
|
||||
"title": "Blue Flame",
|
||||
"artist": { "id": 3799089, "name": "Lil B" },
|
||||
"releaseDate": "2010-09-13",
|
||||
"cover": "35b19623-cb5c-491a-81ea-ebac108c58f2",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
}
|
||||
]
|
||||
|
|
|
|||
365
public/editors-picks.json.old
Normal file
365
public/editors-picks.json.old
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
[
|
||||
{
|
||||
"type": "album",
|
||||
"id": 510893864,
|
||||
"title": "BULLY",
|
||||
"artist": { "id": 25022, "name": "Kanye West" },
|
||||
"releaseDate": "2026-03-28",
|
||||
"cover": "cf2f2c9c-ff67-44f6-83aa-a7622f8c6b64",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 453241376,
|
||||
"title": "Mercy",
|
||||
"artist": { "id": 5225704, "name": "Armand Hammer" },
|
||||
"releaseDate": "2025-11-07",
|
||||
"cover": "ef736301-dbd1-4a41-8668-9dfcdac8d9ad",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 234935928,
|
||||
"title": "Hellfire",
|
||||
"artist": { "id": 10932434, "name": "black midi" },
|
||||
"releaseDate": "2022-07-15",
|
||||
"cover": "71e4b49b-ada3-4e08-b08c-3a7c264117f0",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 310478316,
|
||||
"title": "Lone Wolf",
|
||||
"artist": { "id": 4225137, "name": "Jay Lewis" },
|
||||
"releaseDate": "2023-09-08",
|
||||
"cover": "b1c432b6-2e3a-483f-9026-853741756ad3",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 509288326,
|
||||
"title": "BBY LOBOTOMY",
|
||||
"artist": { "id": 48966543, "name": "Percatric" },
|
||||
"releaseDate": "2026-03-20",
|
||||
"cover": "9b0bbcef-1cc2-44ef-b741-40880cea49b9",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 101715365,
|
||||
"title": "Icedancer",
|
||||
"artist": { "id": 5555246, "name": "Bladee" },
|
||||
"releaseDate": "2018-12-29",
|
||||
"cover": "11465814-2e0b-4d46-8a72-5df21f1ac0b8",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 18083938,
|
||||
"title": "The Glow, Pt. 2",
|
||||
"artist": { "id": 3941394, "name": "The Microphones" },
|
||||
"releaseDate": "2001-09-25",
|
||||
"cover": "ec648c22-9140-41d3-a7ae-0ba69ef0420e",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 382839956,
|
||||
"title": "my anti-aircraft friend",
|
||||
"artist": { "id": 19359095, "name": "julie" },
|
||||
"releaseDate": "2024-09-13",
|
||||
"cover": "ac790b52-61cc-460c-9277-bdac88722cc3",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 456475370,
|
||||
"title": "It Aint Nun",
|
||||
"artist": { "id": 9981740, "name": "CHRIST DILLINGER" },
|
||||
"releaseDate": "2024-09-12",
|
||||
"cover": "3ffc27f6-a77c-4e68-ba44-e04f034783be",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 112547160,
|
||||
"title": "R F Y",
|
||||
"artist": { "id": 36042731, "name": "RFY" },
|
||||
"releaseDate": "2019-06-27",
|
||||
"cover": "ffe3f6f9-5bc8-4b53-99c3-9b83676c099a",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 18658568,
|
||||
"title": "100% Ghetto 4",
|
||||
"artist": { "id": 4191963, "name": "DJ Clent" },
|
||||
"releaseDate": "2010-10-02",
|
||||
"cover": "82b839bd-7cf6-4650-bade-192f47301ffd",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 504004321,
|
||||
"title": "Half Blood (BloodLuxe)",
|
||||
"artist": { "id": 50799233, "name": "slayr" },
|
||||
"releaseDate": "2025-11-05",
|
||||
"cover": "2767cc63-7e92-4a48-aa4b-806a3ea7ec1c",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 89313048,
|
||||
"title": "DAYTONA",
|
||||
"artist": { "id": 3972883, "name": "Pusha T" },
|
||||
"releaseDate": "2018-05-25",
|
||||
"cover": "30288caf-2bdd-4511-a95c-57117936b2b6",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 324660713,
|
||||
"title": "JOECHILLWORLD",
|
||||
"artist": { "id": 3972883, "name": "Devon Hendryx" },
|
||||
"releaseDate": "2010-08-10",
|
||||
"cover": "25d45544-3e82-4184-b8c2-2c2c6f0f152a",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 418729278,
|
||||
"title": "I LAY DOWN MY LIFE FOR YOU: DIRECTOR'S CUT",
|
||||
"artist": { "id": 7958797, "name": "JPEGMAFIA" },
|
||||
"releaseDate": "2025-02-03",
|
||||
"cover": "9c84302b-2584-4c0a-9db7-e648542f459f",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 118353565,
|
||||
"title": "Dyn-O-Mite",
|
||||
"artist": { "id": 5755811, "name": "ZelooperZ" },
|
||||
"releaseDate": "2019-05-18",
|
||||
"cover": "c42f0025-9839-4dd2-b5de-9fd05ed5e917",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 4527433,
|
||||
"title": "Flockaveli",
|
||||
"artist": { "id": 3654061, "name": "Waka Flocka Flame" },
|
||||
"releaseDate": "2010-10-05",
|
||||
"cover": "05702b51-45cf-4157-b9ed-dd7ca7e7b7b3",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 90502209,
|
||||
"title": "NASIR",
|
||||
"artist": { "id": 1003, "name": "Nas" },
|
||||
"releaseDate": "2018-06-15",
|
||||
"cover": "503ea6b2-0829-438e-8e4e-9a988154b3bc",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 413189044,
|
||||
"title": "Jump Out",
|
||||
"artist": { "id": 27836827, "name": "OsamaSon" },
|
||||
"releaseDate": "2025-01-24",
|
||||
"cover": "ec4a4ef2-69fe-4d3c-aaba-05dc2d546e84",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 209061256,
|
||||
"title": "Super Tecmo Bo",
|
||||
"artist": { "id": 4839917, "name": "Boldy James" },
|
||||
"releaseDate": "2021-12-17",
|
||||
"cover": "f58ca804-1da7-4953-a26d-2b3258310db5",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 488297983,
|
||||
"title": "So Much Country 'Till We Get There",
|
||||
"artist": { "id": 51427239, "name": "Westside Cowboy" },
|
||||
"releaseDate": "2026-01-23",
|
||||
"cover": "dd9d4f23-1517-4a76-8e3f-31e341dcd525",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 447277344,
|
||||
"title": "REST IN BASS",
|
||||
"artist": { "id": 50418386, "name": "Che" },
|
||||
"releaseDate": "2025-07-18",
|
||||
"cover": "d1397066-72ed-4481-b508-77f7c7a03073",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 490209783,
|
||||
"title": "My Ghosts Go Ghost",
|
||||
"artist": { "id": 39920098, "name": "By Storm" },
|
||||
"releaseDate": "2026-01-30",
|
||||
"cover": "bc470b88-3583-4853-976e-593855672322",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 279082597,
|
||||
"title": "Noktifer's Symphony",
|
||||
"artist": { "id": 22055243, "name": "axxturel" },
|
||||
"releaseDate": "2020-11-17",
|
||||
"cover": "a886acd8-b915-4a77-9c1f-eecf7fa6091c",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 380211863,
|
||||
"title": "Sayso Says",
|
||||
"artist": { "id": 50418386, "name": "Che" },
|
||||
"releaseDate": "2024-08-30",
|
||||
"cover": "917c7e0f-3ebb-471e-9c88-fcdf6a9f21a5",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 464463900,
|
||||
"title": "A-Rhythm Absolute",
|
||||
"artist": { "id": 30049790, "name": "Sunday Mourners" },
|
||||
"releaseDate": "2026-01-16",
|
||||
"cover": "d04e2ed8-f6d7-43c0-bcb2-fb99d3de0d5d",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": "344201347",
|
||||
"title": "Flex Musix (FLXTRA)",
|
||||
"artist": { "id": 27836827, "name": "OsamaSon" },
|
||||
"releaseDate": "2024-02-16",
|
||||
"cover": "5d1812fc-b9f9-4467-ac78-90d78ea542e4",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 365819314,
|
||||
"title": "One Life",
|
||||
"artist": { "id": "17300439", "name": "1oneam" },
|
||||
"releaseDate": "2024-05-30",
|
||||
"cover": "eb5d74f6-7403-4404-8452-9b68713445fe",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 379517195,
|
||||
"title": "Haram",
|
||||
"artist": { "id": 5225704, "name": "Armand Hammer" },
|
||||
"releaseDate": "2021-03-26",
|
||||
"cover": "69ebc3e7-bd0b-4dd7-88a5-a2e180b84f0d",
|
||||
"explicit": false,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 36160524,
|
||||
"title": "Nasa Gang (Remastered)",
|
||||
"artist": { "id": 4611745, "name": "SpaceGhostPurrp" },
|
||||
"releaseDate": "2014-10-07",
|
||||
"cover": "359d42ec-1984-4d63-a4ae-ecf286463372",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 445752470,
|
||||
"title": "FOR NOTHING",
|
||||
"artist": { "id": 49124576, "name": "nine vicious" },
|
||||
"releaseDate": "2025-07-04",
|
||||
"cover": "8b9018dd-d3c3-46e0-be5a-c16d48180176",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 435083611,
|
||||
"title": "Buddha Therapy",
|
||||
"artist": { "id": 4858188, "name": "Metro Zu" },
|
||||
"releaseDate": "2017-05-01",
|
||||
"cover": "5c6c367a-99ed-4fa4-8e91-ea10d6066e26",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
|
||||
},
|
||||
{
|
||||
"type": "album",
|
||||
"id": 473188494,
|
||||
"title": "Blue Flame",
|
||||
"artist": { "id": 3799089, "name": "Lil B" },
|
||||
"releaseDate": "2010-09-13",
|
||||
"cover": "35b19623-cb5c-491a-81ea-ebac108c58f2",
|
||||
"explicit": true,
|
||||
"audioQuality": "LOSSLESS",
|
||||
"mediaMetadata": { "tags": ["LOSSLESS"] }
|
||||
}
|
||||
]
|
||||
Loading…
Reference in a new issue