1
0
Fork
You've already forked tuners
0
No description
  • Rust 75.3%
  • Nix 15.4%
  • Just 9.3%
2025年11月23日 19:46:29 -05:00
.config chore: reuse compliance 2025年11月21日 14:13:06 -05:00
LICENSES chore: reuse compliance 2025年11月21日 14:13:06 -05:00
packages chore: reuse compliance 2025年11月21日 14:13:06 -05:00
src feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
.copier-answers.yml chore: reuse compliance 2025年11月21日 14:13:06 -05:00
.editorconfig chore: reuse compliance 2025年11月21日 14:13:06 -05:00
.envrc chore: reuse compliance 2025年11月21日 14:13:06 -05:00
.gitignore chore: reuse compliance 2025年11月21日 14:13:06 -05:00
.ignore chore: reuse compliance 2025年11月21日 14:13:06 -05:00
BEETS_CONFIG_MAPPING.md feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
biome.json chore: initial commit 2025年11月19日 03:25:33 -05:00
biome.json.license chore: reuse compliance 2025年11月21日 14:13:06 -05:00
Cargo.lock feat: parallelism with rayon 2025年11月21日 22:10:23 -05:00
Cargo.lock.license chore: reuse compliance 2025年11月21日 14:13:06 -05:00
Cargo.toml feat: parallelism with rayon 2025年11月21日 22:10:23 -05:00
CLAUDE.md feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
cog.toml chore: reuse compliance 2025年11月21日 14:13:06 -05:00
COPYING chore: initial commit 2025年11月19日 03:25:33 -05:00
flake.lock chore: initial commit 2025年11月19日 03:25:33 -05:00
flake.lock.license chore: reuse compliance 2025年11月21日 14:13:06 -05:00
flake.nix chore: reuse compliance 2025年11月21日 14:13:06 -05:00
Justfile chore: reuse compliance 2025年11月21日 14:13:06 -05:00
README.md feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
ROADMAP.md feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
rustfmt.toml feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
test.gif feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
test.tape feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00
treefmt.toml chore: reuse compliance 2025年11月21日 14:13:06 -05:00
tuners-current.tape feat: musicbrainz lookup 2025年11月23日 19:46:29 -05:00

Tuners

A proof-of-concept music library manager inspired by beets.

This project is in its very early stages. And I am still learning Rust.

Current Status

Phase 0: Proof of Concept (In Progress)

The core scaffold is complete. MusicBrainz search integration is working. Currently implementing the remaining auto-tagging workflow components (scoring, track mapping, tag writing).

What Works Now

  • TUI interface with ratatui
  • Sequential directory scanning with concurrent MusicBrainz searching
  • Metadata extraction from MP3, M4A, and FLAC files
  • Duration calculation from audio streams (MP3, FLAC, M4A)
  • Album clustering based on directory and tags
  • Multi-disc album support with proper track sorting
  • Interactive cluster detail view with track listings
  • Keyboard navigation (j/k, arrows, space, Enter)
  • MusicBrainz API client with rate limiting (1 req/sec)
  • Concurrent scan/search pipeline with bounded queue
  • Basic match result display (artist, title, date, track count)

What's Next

See ROADMAP.md for the complete development plan.

Immediate next steps (completing auto-tagging workflow):

  • Similarity scoring algorithm (0-100% match confidence)
  • Track mapping preview showing proposed tag changes
  • Manual search implementation (enter custom artist/album query)
  • Dry-run tag writing (show what would be written without modifying files)
  • Apply functionality (actually write tags to files)
  • Proper handling of NoResults and Error cases

The goal is to replicate beets' core auto-tagging experience: scan → auto-search → score matches → prompt → preview changes → apply.

Quick Start

Building

cargo build

Running

Scan current directory:

cargo run
# or after building: tune

Scan specific directory:

cargo run /path/to/music
# or after building: tune /path/to/music

Controls

Scanning screen:

  • Enter - Continue to cluster list (when scan complete)
  • q or Ctrl-C - Quit

Cluster list screen:

  • ↑/↓ or j/k - Navigate clusters
  • Space or Enter - View cluster details
  • q or Ctrl-C - Quit

Cluster detail screen:

  • ↑/↓ or j/k - Navigate tracks
  • Esc or h - Back to cluster list
  • q or Ctrl-C - Quit

Architecture

Module Structure

src/
 main.rs - Entry point (argument parsing only)
 app.rs - Application state machine and event loop
 ui.rs - TUI rendering for each state
 models.rs - Domain types (AudioFile, AlbumCluster)
 codecs.rs - Audio codec enumeration
 scanner.rs - Directory scanning and clustering (with rayon parallelism)
 scanner/
 metadata.rs - Tag extraction by format (MP3, M4A, FLAC)
 musicbrainz/
 mod.rs - Public API and SearchMessage types
 client.rs - Rate-limited MusicBrainz API wrapper
 search.rs - Search logic with message passing

Design Principles

Separation of Concerns:

  • main.rs handles only argument parsing and error reporting
  • app.rs owns the application lifecycle and event loop
  • terminal.rs encapsulates crossterm setup/teardown
  • UI rendering is isolated from business logic

Error Handling:

  • color_eyre::eyre::Result for application-level errors
  • Beautiful error reports with backtraces and suggestions
  • Proper cleanup via RAII (terminal restoration happens even on panic)
  • Context added to errors for debugging

State Machine:

  • Explicit AppState enum prevents invalid states
  • State transitions are centralized in app.rs
  • Each state has well-defined entry/exit behavior

Modularity:

  • Scanner functionality is split into public API (mod.rs) and implementation details (metadata.rs)
  • Future expansion: add matching/, musicbrainz/ modules without changing existing code

Project Documentation

Dependencies

  • ratatui - TUI framework
  • crossterm - Terminal handling (backend for ratatui)
  • rayon - Data parallelism for concurrent directory scanning
  • musicbrainz_rs - MusicBrainz API wrapper (not yet used)
  • tokio - Async runtime (for future MusicBrainz calls)
  • id3, mp4ameta, metaflac - Tag reading libraries
  • mp3-duration - Calculate MP3 duration from audio stream
  • walkdir - Directory traversal
  • color-eyre - Error handling with beautiful reports
  • strsim - String similarity (for matching algorithm)

Development

Running with Better Errors

Enable backtraces for debugging:

RUST_BACKTRACE=1 cargo run /path/to/music
# or after building: RUST_BACKTRACE=1 tune /path/to/music

Code Organization

The project follows idiomatic Rust practices:

  • Pure functions where possible
  • Clear ownership boundaries
  • Explicit error handling
  • Minimal unsafe code (currently none)

See PATTERNS.md for detailed explanations of patterns used.

Contributing

This is a personal learning project, but observations and suggestions are welcome.

When adding features:

  1. Read the relevant section in ROADMAP.md
  2. Follow patterns from existing code
  3. Add tests for new functionality
  4. Update documentation

License

To be determined (project is in early stages)

Acknowledgments

  • beets - The original and inspiration
  • ratatui - Excellent TUI framework
  • Rust community for helpful libraries and documentation