qobuz-dl

repository·main·Indexed 21 days ago

https://github.com/qobuzdl/qobuz-dl

A browser-based application for downloading music from Qobuz. It supports downloading songs, albums, and entire artist discographies, with features for re-encoding audio into various lossless and lossy codecs via FFmpeg, applying metadata and album art, and fixing FLAC MD5 hashes. The tool can be deployed via npm or Docker and requires Qobuz API credentials (App ID and Secret) to function.

Tokens
7.2K
Snippets
29
Records
33
Agent score
74%

What's inside qobuz-dl

  1. Overview of Qobuz-DL features

    main

    Qobuz-DL is a browser-based tool that allows users to download music from Qobuz. Key capabilities include:

    • Downloading any song or album from Qobuz.
    • Re-encoding audio using FFmpeg into various lossless and lossy codecs.
    • Applying metadata to downloaded tracks.
  2. Install Qobuz-DL via Docker

    main

    To run Qobuz-DL using Docker, clone the repository and use Docker build and compose to set up the containerized environment:

    git clone https://github.com/QobuzDL/Qobuz-DL.git
    cd Qobuz-DL
    docker build -t qobuz-dl .
    docker-compose up -d
  3. Install Qobuz-DL via npm

    main

    To run Qobuz-DL in a development environment, ensure you have Node.js (LTS recommended) and npm installed. Follow these steps to clone, install dependencies, and start the development server:

    git clone https://github.com/QobuzDL/Qobuz-DL.git
    cd Qobuz-DL
    npm i
    npm run dev
  4. Configure environment variables for Qobuz-DL

    main

    Qobuz-DL requires specific credentials in a .env file located in the root directory to function. The default configuration will not work. You must set the following keys:

    • QOBUZ_APP_ID: Your Qobuz Application ID.
    • QOBUZ_SECRET: Your Qobuz Application Secret.

    You can obtain these values using the Qobuz-AppID-Secret-Tool.

    Note on downloading long files: To download audio files longer than 30 seconds, you must provide a valid Qobuz token. This token can be retrieved from the localuser.token key in the localStorage of the official Qobuz website for active paying members.

  5. Configure required environment variables for Qobuz-DL

    main

    To use the server-side API functions, the following environment variables must be configured in your deployment. The testForRequirements() function validates these before any API call is made:

    • QOBUZ_APP_ID: The Qobuz application ID.
    • QOBUZ_AUTH_TOKENS: A JSON array of valid Qobuz user authentication tokens.
    • QOBUZ_SECRET: The Qobuz secret used for generating request signatures.
    • QOBUZ_API_BASE: The base URL for the Qobuz API.
    • SOCKS5_PROXY (Optional): A SOCKS5 proxy URL (e.g., socks5://host:port) to route requests through.
    • CORS_PROXY (Optional): A proxy URL used to wrap API requests to bypass CORS restrictions.
  6. Run qobuz-dl using Docker Compose

    main

    You can deploy qobuz-dl as a containerized service using Docker Compose. The service maps port 3000 on the host to port 3000 inside the container and is configured to restart automatically unless explicitly stopped.

    services:
        qobuz-dl:
            container_name: qobuz-dl
            image: qobuz-dl
            ports:
                - 3000:3000
            restart: unless-stopped
  7. Configure application settings via SettingsProps

    main

    The application's download and output behavior is controlled by the SettingsProps object. These settings are persisted in localStorage under the key 'settings'.

    Available Settings

    KeyTypeDescription / Constraints
    particlesbooleanEnables/disables particle effects.
    outputQuality'27' | '7' | '6' | '5'Specific quality preset identifier.
    outputCodec'FLAC' | 'WAV' | 'ALAC' | 'MP3' | 'AAC' | 'OPUS'The audio codec for the output files.
    bitratenumber | undefinedBitrate in kbps. Must be between 24 and 320.
    applyMetadatabooleanWhether to apply metadata to files.
    fixMD5booleanWhether to fix MD5 hashes.
    explicitContentbooleanWhether to allow/handle explicit content.
    albumArtSizenumberSize of album art in pixels. Must be between 100 and 3600.
    albumArtQualitynumberQuality of album art. Must be between 0.1 and 1.
    zipNamestringNaming template for zip files.
    trackNamestringNaming template for track files.

    Naming Variables

    When defining zipName or trackName, you can use the following placeholders:

    • {artists}
    • {name}
    • {year}
    • {duration}
    const settings: SettingsProps = {
        particles: true,
        outputQuality: '27',
        outputCodec: 'FLAC',
        bitrate: 320,
        applyMetadata: true,
        fixMD5: false,
        explicitContent: true,
        albumArtSize: 3600,
        albumArtQuality: 1,
        zipName: '{artists} - {name}',
        trackName: '{artists} - {name}'
    };
  8. Format artist names with formatArtists()

    main

    The formatArtists function extracts and joins artist names for an album or track.

    • For albums, it maps through the artists array.
    • For tracks without an explicit artist array, it falls back to the performer.name.
    • If no performer is found, it defaults to 'Various Artists'.

    You can provide a custom separator string (defaults to ', ').

    export function formatArtists(input: QobuzAlbum | QobuzTrack, separator: string = ', ') {
        return (getAlbum(input) as QobuzAlbum).artists && (getAlbum(input) as QobuzAlbum).artists.length > 0
            ? (getAlbum(input) as QobuzAlbum).artists.map((artist) => artist.name).join(separator)
            : (input as QobuzTrack).performer?.name || 'Various Artists';
    }
  9. Download an artist's entire discography

    main

    The downloadArtistDiscography function automates the process of downloading multiple releases by an artist.

    You specify a type to filter which releases to download:

    • 'album'
    • 'epSingle'
    • 'live'
    • 'compilation'
    • 'all' (downloads all the above categories)

    The function iterates through the artist's releases, uses the provided fetchMore callback to handle pagination (loading more results if has_more is true), and then calls createDownloadJob for every item found in the specified category.

    await downloadArtistDiscography(
        artistResults, // QobuzArtistResults
        setArtistResults, 
        fetchMore, 
        'all', // type: 'album' | 'epSingle' | 'live' | 'compilation' | 'all'
        setStatusBar, 
        settings, 
        toast, 
        ffmpegState, 
        country?
    );
  10. Get album information

    main

    The getAlbumInfo(album_id, options?) function retrieves detailed metadata for a specific album, including track IDs, by calling the /album/get endpoint with the extra=track_ids parameter.

    import { getAlbumInfo } from '@/lib/qobuz-dl-server';
    
    const album = await getAlbumInfo('123456');
    console.log(album.tracks); // Contains track information
  11. Fetch full album information with getFullAlbumInfo()

    main

    The getFullAlbumInfo function asynchronously fetches detailed album data from the /api/get-album endpoint.

    Parameters:

    • fetchedAlbumData: The current state of fetched album data (used for caching/memoization).
    • setFetchedAlbumData: A React state setter to update the fetched data.
    • result: The QobuzAlbum object to fetch details for (uses result.id).
    • country (optional): A string used in the Token-Country header for the request.
    export async function getFullAlbumInfo(
        fetchedAlbumData: FetchedQobuzAlbum | null,
        setFetchedAlbumData: React.Dispatch<React.SetStateAction<FetchedQobuzAlbum | null>>,
        result: QobuzAlbum,
        country?: string
    ) {
        if (fetchedAlbumData && (fetchedAlbumData as FetchedQobuzAlbum).id === (result as QobuzAlbum).id) return fetchedAlbumData;
        setFetchedAlbumData(null);
        const albumDataResponse = await axios.get('/api/get-album', { params: { album_id: (result as QobuzAlbum).id }, headers: { 'Token-Country': country } });
        setFetchedAlbumData(albumDataResponse.data.data);
        return albumDataResponse.data.data;
    }
  12. Use the useSettings hook to manage application state

    main

    The useSettings hook provides access to the global application settings within a React component tree. It must be used within a <SettingsProvider> component.

    The hook returns an object containing:

    • settings: The current SettingsProps object.
    • setSettings: A React state dispatcher to update settings.
    • resetSettings: A function to revert all settings to defaultSettings.
    import { useSettings } from './lib/settings-provider';
    
    const MyComponent = () => {
        const { settings, setSettings, resetSettings } = useSettings();
    
        const updateCodec = (newCodec: 'FLAC' | 'WAV' | 'ALAC' | 'MP3' | 'AAC' | 'OPUS') => {
            setSettings({ ...settings, outputCodec: newCodec });
        };
    
        return (
            <button onClick={resetSettings}>
                Reset to Defaults
            </button>
        );
    };