Skip to content

A high-performance Rust CLI audio player that connects to Music Assistant and plays synchronized audio using the Sendspin protocol.

License

Notifications You must be signed in to change notification settings

s3than/sendspin-rs-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

30 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Sendspin Rust CLI

A high-performance Rust CLI audio player that connects to Music Assistant and plays synchronized audio using the Sendspin protocol.

Features

  • 🎡 Synchronized Audio Playback - Time-synced playback across multiple players
  • πŸ” Automatic Server Discovery - Zero-config setup using mDNS service discovery
  • 🎚️ Volume Control - Software-based volume scaling (0-100)
  • ⏯️ Playback Control - Stop, resume, and skip commands
  • πŸ”Š Cross-Platform Audio - Uses CPAL for Linux, macOS, and Windows support
  • πŸ“¦ Lightweight - Minimal dependencies, fast startup time
  • 🧡 Multi-threaded - Separate threads for network and audio output

Installation

Pre-built Binaries

Download the latest release for your platform from the releases page:

  • Linux AMD64: sendspin-rs-cli-linux-amd64
  • Linux ARM64: sendspin-rs-cli-linux-arm64
  • macOS Intel: sendspin-rs-cli-darwin-amd64
  • macOS Apple Silicon: sendspin-rs-cli-darwin-arm64
  • Windows: sendspin-rs-cli-windows-amd64.exe
# Example installation (Linux AMD64)
wget https://github.com/s3than/sendspin-rs-cli/releases/latest/download/sendspin-rs-cli-linux-amd64
chmod +x sendspin-rs-cli-linux-amd64
sudo mv sendspin-rs-cli-linux-amd64 /usr/local/bin/sendspin-rs-cli

# Verify installation
sendspin-rs-cli --version

Build from Source

Requirements:

  • Rust 1.92 or later
  • ALSA development libraries (Linux only): libasound2-dev
# Clone the repository
git clone https://github.com/s3than/sendspin-rs-cli.git
cd sendspin-rs-cli

# Build release binary
cargo build --release

# Binary will be at: target/release/sendspin-rs-cli

Usage

Basic Usage

# Auto-discover server via mDNS (recommended)
sendspin-rs-cli

# Specify server manually
sendspin-rs-cli --server 192.168.1.100:8927

# Custom player name and volume
sendspin-rs-cli --name "Living Room" --volume 50

Command-line Options

Options:
  -s, --server <SERVER>        Server address (host:port). If not specified, uses mDNS discovery
  -n, --name <NAME>            Player name [default: "Sendspin-RS Player"]
      --client-id <CLIENT_ID>  Custom client ID (auto-generated if not specified)
  -v, --volume <VOLUME>        Initial volume (0-100) [default: 30]
  -b, --buffer <BUFFER>        Buffer size in milliseconds [default: 20]
  -h, --help                   Print help
      --version                Print version

Examples

Auto-discovery (zero-config):

sendspin-rs-cli

Specify server address:

sendspin-rs-cli --server 192.168.1.100:8927

Custom player configuration:

sendspin-rs-cli \
  --name "Bedroom Speaker" \
  --volume 75 \
  --server 192.168.1.100:8927

Enable debug logging:

RUST_LOG=debug sendspin-rs-cli

How It Works

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Music Assistantβ”‚
β”‚     Server      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚ WebSocket (Sendspin Protocol)
         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  sendspin-rs-cliβ”‚
β”‚                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Decoder  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β”‚
β”‚        β”‚        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   Queue   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β”‚
β”‚        β”‚        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚Time Sync  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β”‚
β”‚        β”‚        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   CPAL    β”‚  β”‚
β”‚  β”‚  Output   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
    πŸ”Š Speakers

Key Features

  1. mDNS Discovery: Automatically finds Music Assistant servers on the local network using mDNS (_sendspin-server._tcp.local.)

  2. Time Synchronization: Uses NTP-style clock sync to ensure audio plays at the exact right time across multiple players

  3. Simple Queue: Audio buffers are decoded and queued with timestamps, then played at the precise moment

  4. Protocol Compatibility: Includes a compatibility shim to handle protocol differences between the sendspin-rs library and Music Assistant server

Development

Running Tests

# Run all tests
cargo test

# Run with verbose output
cargo test -- --nocapture

# Run specific test
cargo test test_player_creation

# Generate coverage report
cargo tarpaulin --lib --exclude-files 'target/*'

Current test coverage: 49.62% (65/131 lines)

Building for Different Platforms

The project uses GitHub Actions to build binaries for multiple platforms:

# Native build (current platform)
cargo build --release

# Cross-compile for ARM64 Linux (requires cross)
cross build --release --target aarch64-unknown-linux-gnu

# Cross-compile for Windows (requires cross)
cross build --release --target x86_64-pc-windows-gnu

Project Structure

sendspin-rs-cli/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.rs      # Entry point and protocol handling
β”‚   β”œβ”€β”€ player.rs    # Audio playback and queue management
β”‚   β”œβ”€β”€ mdns.rs      # mDNS server discovery
β”‚   β”œβ”€β”€ compat.rs    # Protocol compatibility shim
β”‚   └── lib.rs       # Library exports for testing
β”œβ”€β”€ tests/
β”‚   └── integration_test.rs  # Integration tests
β”œβ”€β”€ Cross.toml       # Cross-compilation configuration
β”œβ”€β”€ rust-toolchain.toml      # Rust toolchain specification
└── .github/
    └── workflows/
        └── build.yml         # CI/CD pipeline

Troubleshooting

No server found via mDNS

If mDNS discovery fails, manually specify the server address:

sendspin-rs-cli --server <server-ip>:8927

Audio device errors (Linux)

Make sure ALSA libraries are installed:

sudo apt-get install libasound2-dev

Permission denied

Ensure the binary has execute permissions:

chmod +x sendspin-rs-cli

Technical Details

Supported Audio Formats

  • PCM: Uncompressed audio (16-bit, 24-bit)
  • Sample rates: 44.1kHz, 48kHz, 96kHz, etc.
  • Channels: Mono, Stereo, Multi-channel

Protocol

The player implements the Sendspin protocol for communicating with Music Assistant:

  • Transport: WebSocket over TCP
  • Serialization: JSON messages
  • Clock Sync: NTP-style time synchronization
  • Audio: Chunked streaming with timestamps

Dependencies

Major dependencies:

  • sendspin-rs: Core Sendspin protocol implementation
  • tokio: Async runtime
  • cpal: Cross-platform audio I/O
  • tokio-tungstenite: WebSocket client
  • mdns-sd: mDNS service discovery
  • clap: Command-line argument parsing

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

Development Setup

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/YOUR_USERNAME/sendspin-rs-cli.git
  3. Create a feature branch: git checkout -b feature/your-feature
  4. Make your changes and add tests
  5. Run tests: cargo test
  6. Run clippy: cargo clippy -- -D warnings
  7. Run formatter: cargo fmt
  8. Commit your changes: git commit -am 'Add new feature'
  9. Push to the branch: git push origin feature/your-feature
  10. Create a Pull Request

License

This project is licensed under the Apache License - see the LICENSE file for details.

Acknowledgments

  • Music Assistant - The music management system this player connects to
  • sendspin-rs - Core Sendspin protocol library * currently a forked library with various forks from the upstream merged in advanced.
  • cpal - Cross-platform audio library

Links

About

A high-performance Rust CLI audio player that connects to Music Assistant and plays synchronized audio using the Sendspin protocol.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages