Files
QZMusic_PC/CLAUDE.md

4.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

QZ Music is a cross-platform desktop music player (Electron + Vue 3 + TypeScript). The backend is a separate FastAPI Python project at C:\Develop\SuperApi\app_api. This repo is the Electron client only.

Build & Dev Commands

# Install dependencies
npm install

# Development (hot reload)
npm run dev

# Production build
npm run build

# Build Windows installer
npm run electron:build

No test runner is configured. No linter is configured.

Architecture

Three-Process Model (Critical)

The app uses Electron's three-process architecture with strict separation:

Renderer (Vue)  →  Preload (IPC bridge)  →  Main Process  →  HTTP fetch  →  Backend API

The renderer process NEVER makes HTTP requests directly. All API calls go through this chain:

  1. Renderer calls window.electronAPI.xxx() methods
  2. Preload (src/preload/index.ts) maps each method to ipcRenderer.invoke('channel:name', args)
  3. Main process (src/main/index.ts) registers ipcMain.handle('channel:name', handler)
  4. Main process calls the backend via qzFetch() (defined in src/main/authStore.ts) which uses native fetch()

To add a new API feature, you must touch all 4 layers:

  • Backend endpoint (FastAPI)
  • Main process function (src/main/authStore.ts or similar)
  • IPC handler (src/main/index.ts)
  • Preload bridge (src/preload/index.ts)
  • Type definition (src/renderer/src/types/electron.d.ts)

Backend API

  • Base URL: https://api.qz.shiqianjiang.cn/app
  • Auth: JWT Bearer token, auto-refreshed via getValidAccessToken()
  • qzFetch(path, init) is the universal API caller — attaches auth, handles errors

Key Directories

src/main/           - Electron main process (window, IPC handlers, audio engine control)
  authStore.ts      - Auth state, token management, qzFetch(), user API calls
  playlistStore.ts  - Playlist CRUD (local JSON files + cloud API)
  qzpController.ts  - IPC controller for QZPlayer (C audio engine binary)
  proxyServer.ts    - Local HTTP proxy (:5266) that streams remote music to QZPlayer
  pluginSystem.ts   - Plugin framework for music source plugins
  settingsStore.ts  - App settings persistence

src/preload/        - Context bridge (ONLY file that can use both Node and browser APIs)
  index.ts          - Defines the complete window.electronAPI surface

src/renderer/src/   - Vue 3 frontend
  main.ts           - App entry, Vue Router config, Pinia setup
  stores/           - Pinia stores (player, playlists, auth, listenTogether)
  views/            - Page components (Playlist.vue is reused for 5+ routes)
  components/       - Shared UI components
  types/            - TypeScript interfaces (electron.d.ts is the IPC contract)

Audio Pipeline

QZPlayer is a C binary (core/ directory) that plays audio via WASAPI+FFmpeg. Communication:

  • Main process sends commands via IPC (src/main/qzpController.ts)
  • Music is streamed through a local HTTP proxy (src/main/proxyServer.ts on port 5266)
  • URL format: http://localhost:5266/music?source={source}&id={id}&quality={quality}

Local vs Cloud Playlists

  • Local (scope: 'local'): JSON files in userData/playlists/, UUID-based IDs
  • Cloud (scope: 'cloud'): Backend API at /playlist/*, auto-incrementing numeric IDs
  • Plugin (scope: 'plugin'): Read-only collections from music source plugins

AMLL (Apple Music-like Lyrics)

amll-local/ is a local copy of the AMLL library (lyrics rendering + background effects). It's aliased in electron.vite.config.ts to resolve from source. Do not modify AMLL packages directly — they are a third-party dependency.

Conventions

  • Use Icon component from @iconify/vue for all icons (e.g. <Icon icon="lucide:play" />)
  • UI component library: Element Plus (ElMessage for toasts, ElMessageBox for confirmations)
  • State management: Pinia stores in src/renderer/src/stores/
  • Routing: Vue Router with hash history, defined inline in src/renderer/src/main.ts
  • CSS: Scoped styles with CSS custom properties (--color-accent, --color-bg-*, etc.)
  • Playlist.vue is a monolithic view serving multiple routes (Liked, Recent, PlaylistDetail, UserLikedPlaylist, PluginCollection) — use route.name and computed properties to branch behavior