npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@orchardmusic/qobuz

v0.2.0

Published

Host-neutral Qobuz API, catalog matching, reporting, and CMAF-to-FLAC playback for Node.js.

Readme

@orchardmusic/qobuz

A host-neutral Node.js API for Qobuz catalog matching, playback sessions, reporting, and conversion of segmented Qobuz CMAF streams into seekable FLAC responses.

This is an unofficial integration and is not affiliated with or endorsed by Qobuz. It requires a valid Qobuz account and access appropriate to the content being played. Qobuz's private web APIs and media format can change without notice.

Install

npm install @orchardmusic/qobuz

The package is ESM-only, requires Node.js 18 or newer, and has no runtime npm dependencies. The default entry point does not import Electron or any Orchard code.

Quick start

The host supplies credentials and, optionally, its own fetch implementation. The returned service owns session renewal, catalog matching, reporting, and segmented playback state.

import { createQobuz } from '@orchardmusic/qobuz';

const qobuz = createQobuz({
  credentials: async () => ({
    token: process.env.QOBUZ_USER_TOKEN,
    userId: Number(process.env.QOBUZ_USER_ID)
  }),
  logger: console,
  softwareVersion: 'ExamplePlayer/1.0.0'
});

const results = await qobuz.search('artist track');

const resolved = await qobuz.resolveTrack({
  title: 'Track title',
  artists: ['Artist name'],
  album: 'Album title',
  durationMs: 180_000,
  isrc: 'USABC1200001',
  explicit: false
}, 'hires');

if (resolved) {
  console.log(resolved.match);
  console.log(resolved.source);
}

await qobuz.close();

The package expects credentials obtained through an authorized Qobuz login flow. It intentionally does not ship copied application credentials.

Building a login flow

Web and desktop hosts can construct their own redirect flow with the exported OAuth helpers:

import {
  createQobuzAuthorizationUrl,
  exchangeQobuzAuthorizationCode,
  fetchQobuzBootstrap
} from '@orchardmusic/qobuz';

const web = await fetchQobuzBootstrap();
const loginUrl = createQobuzAuthorizationUrl({
  appId: web.appId,
  redirectUrl: 'https://player.example/qobuz/callback'
});

// Redirect the user to loginUrl. In the callback handler:
const credentials = await exchangeQobuzAuthorizationCode({
  code: authorizationCode,
  web
});

Credential storage, callback routing, CSRF protection, and browser navigation belong to the host. The optional Electron adapter provides one complete desktop implementation.

Serving playback

resolveTrack() and resolveStream() return an opaque playback ID and FLAC metadata. Expose that ID through a host-owned HTTP route and delegate requests to proxyStream():

import { createServer } from 'node:http';

const server = createServer(async (request, response) => {
  const playbackId = new URL(request.url, 'http://localhost').pathname.slice(1);
  await qobuz.proxyStream(playbackId, request, response);
});

server.listen(3000);

The proxy supports GET, HEAD, OPTIONS, and single HTTP byte ranges. Call playbackStarted(playbackId, positionSeconds) and playbackEnded(playbackId, positionSeconds) when the player changes state so required playback reports reflect actual listening time.

Core API

createQobuz(options)

Creates the high-level service. Options:

  • credentials: Required async function returning { token, userId } or null.
  • fetchImpl: Fetch-compatible network function; defaults to global fetch.
  • logger: Object with optional info and warn methods; defaults to console.
  • softwareVersion: Host identifier included in playback-end reports.
  • bootstrap: Optional custom bootstrap loader with a get() method.
  • bootstrapMaxAgeMs: Cache duration for the built-in bootstrap loader.
  • matcherCacheTtlMs: Cache duration for canonical track matches.

The service exposes:

  • search(query) and streamingInfo(trackId, quality) for direct API use.
  • matchTrack(track) to match canonical metadata without resolving media.
  • resolveStream(match, quality) to resolve an existing match.
  • resolveTrack(track, quality) to match and resolve in one call.
  • proxyStream(playbackId, request, response) to serve seekable FLAC.
  • playbackStarted(...), playbackEnded(...), and close() for reporting and cleanup.
  • client and bootstrap for advanced session control.

Supported quality values are auto, lossless, and hires.

Lower-level exports

The package root also exports the individual building blocks:

  • createQobuzClient, createQobuzBootstrapLoader, fetchQobuzBootstrap, and extractQobuzBootstrap.
  • createQobuzAuthorizationUrl and exchangeQobuzAuthorizationCode for host-owned login flows.
  • createQobuzMatcher, selectQobuzMatch, canonicalTrack, and normalizedQobuzText.
  • createQobuzPlayback and createQobuzReporter.
  • parseQobuzInitSegment, parseQobuzAudioSegment, key derivation helpers, and segment decryption helpers.
  • API URLs, format IDs, CMAF UUIDs, quality values, and normalization helpers.

Electron adapter

Electron login and encrypted session persistence are available separately, so non-Electron consumers never load that code:

import { setupQobuzElectron } from '@orchardmusic/qobuz/electron';

const provider = setupQobuzElectron({
  app,
  applicationName: 'Example Player',
  BrowserWindow,
  ipcChannels: {
    CONNECT: 'qobuz:connect',
    DISCONNECT: 'qobuz:disconnect',
    STATUS: 'qobuz:status',
    UPDATE: 'qobuz:update'
  },
  ipcMain,
  net,
  safeStorage,
  session,
  softwareVersion: 'ExamplePlayer/1.0.0'
});

The adapter also accepts custom partition and recordPath values. createQobuzAuth is exported from the /electron entry point for hosts that want authentication without the composed provider.

The authentication helper persists a user token only when Electron safeStorage reports a secure backend. Otherwise the login remains memory-only and public status reports that it is not persistent.

Security

Hosts should avoid logging account tokens, signed media URLs, bootstrap secrets, session information, or content keys. Keep credentials server-side or in an OS-backed secret store, validate playback IDs at any public HTTP boundary, and call close() during shutdown.

License

AGPL-3.0-or-later. See the Orchard repository for source and license terms.