Skip to content

Latest commit

 

History

History
354 lines (286 loc) · 13.3 KB

File metadata and controls

354 lines (286 loc) · 13.3 KB

Bluetooth Audio Implementation Summary

What Was Implemented

A complete Bluetooth audio streaming system for NodeNav that enables:

  • Real Bluetooth connectivity with phones
  • Audio streaming from phone to computer (A2DP)
  • Media playback control via AVRCP protocol
  • Live track metadata display
  • Play/pause, next, previous controls

Files Created/Modified

New Files

  1. src/services/bluetooth-audio-service.js (444 lines)

    • Core Bluetooth audio service
    • Handles A2DP audio streaming
    • Implements AVRCP media controls
    • Platform-specific implementations (Linux fully supported)
    • Metadata polling and state management
  2. BLUETOOTH_AUDIO_SETUP.md

    • Complete user documentation
    • Platform setup instructions
    • Troubleshooting guide
    • API reference
  3. setup-bluetooth-audio.sh

    • Automated Linux setup script
    • Installs required packages (BlueZ, PulseAudio)
    • Configures permissions and services
    • Sets up audio routing
  4. BLUETOOTH_AUDIO_IMPLEMENTATION.md (this file)

    • Technical implementation summary

Modified Files

  1. src/pages/MediaPlayer.jsx

    • Replaced simulation with real API calls
    • Added automatic device connection on mount
    • Implemented state polling from backend
    • Connected all controls to Bluetooth API
    • Added error handling
  2. src/server.js

    • Added Bluetooth audio service initialization
    • Added 8 new API endpoints for media control
    • Integrated cleanup for graceful shutdown
  3. src/services/api.js

    • Added 8 new methods in BluetoothAPI class:
      • connectAudio(address)
      • disconnectAudio()
      • getMediaState()
      • playMedia()
      • pauseMedia()
      • nextTrack()
      • previousTrack()
      • stopMedia()
  4. src/App.jsx

    • Added MediaPlayer import
    • Added 'media' route case
    • Connected Media card click handler

Architecture

┌─────────────────────────────────────────────────────────────┐
│                        Frontend (React)                      │
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │         MediaPlayer Component                       │    │
│  │  - Display track info                              │    │
│  │  - Playback controls                               │    │
│  │  - Progress bar                                    │    │
│  └───────────────┬────────────────────────────────────┘    │
│                  │ bluetoothAPI                             │
└──────────────────┼──────────────────────────────────────────┘
                   │
                   │ REST API (HTTP)
                   │
┌──────────────────▼──────────────────────────────────────────┐
│                   Backend (Express)                          │
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │     API Endpoints (server.js)                      │    │
│  │  /api/bluetooth/audio/connect/:address             │    │
│  │  /api/bluetooth/audio/state                        │    │
│  │  /api/bluetooth/audio/play                         │    │
│  │  /api/bluetooth/audio/pause                        │    │
│  │  /api/bluetooth/audio/next                         │    │
│  │  /api/bluetooth/audio/previous                     │    │
│  └───────────────┬────────────────────────────────────┘    │
│                  │                                           │
│  ┌───────────────▼────────────────────────────────────┐    │
│  │   Bluetooth Audio Service                          │    │
│  │  - Device connection management                    │    │
│  │  - A2DP profile configuration                      │    │
│  │  - AVRCP command transmission                      │    │
│  │  - Metadata polling                                │    │
│  └───────────────┬────────────────────────────────────┘    │
└──────────────────┼──────────────────────────────────────────┘
                   │
                   │ System Commands
                   │
┌──────────────────▼──────────────────────────────────────────┐
│                    System Level                              │
│                                                              │
│  ┌────────────────────────┐  ┌─────────────────────────┐   │
│  │   bluetoothctl         │  │   PulseAudio/PipeWire   │   │
│  │  (BlueZ D-Bus API)     │  │   (Audio Routing)       │   │
│  │  - Device pairing      │  │   - A2DP sink           │   │
│  │  - AVRCP commands      │  │   - Audio streaming     │   │
│  │  - Metadata retrieval  │  │   - Volume control      │   │
│  └────────────────────────┘  └─────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                   │
                   │ Bluetooth Radio
                   │
┌──────────────────▼──────────────────────────────────────────┐
│                   Phone/Device                               │
│  - Music player (Spotify, Apple Music, etc.)                │
│  - Audio source                                              │
│  - AVRCP controller support                                  │
└─────────────────────────────────────────────────────────────┘

Technical Details

Bluetooth Profiles Used

  1. A2DP (Advanced Audio Distribution Profile)

    • Purpose: High-quality audio streaming
    • Role: Computer acts as sink (receiver)
    • Codec: Typically SBC (SubBand Codec)
    • Bitrate: ~320 kbps for high quality
  2. AVRCP (Audio/Video Remote Control Profile)

    • Purpose: Media control and metadata
    • Version: AVRCP 1.5+ for full metadata support
    • Commands: Play, Pause, Stop, Next, Previous
    • Metadata: Title, Artist, Album, Duration, Position

Linux Implementation Details

Connection Flow:

  1. Device must be paired first (via BluetoothSettings page)
  2. Backend connects to device using bluetoothctl connect
  3. System automatically configures A2DP sink profile
  4. PulseAudio routes audio to default output device
  5. Metadata polling starts (every 2 seconds)

AVRCP Commands:

# Play
echo "player.play" | bluetoothctl

# Pause
echo "player.pause" | bluetoothctl

# Next
echo "player.next" | bluetoothctl

# Previous
echo "player.previous" | bluetoothctl

Metadata Retrieval:

# Get device info including player metadata
echo "info AA:BB:CC:DD:EE:FF" | bluetoothctl | grep -A 20 "Player"

State Management

Frontend:

  • Polls backend every 2 seconds for media state
  • Maintains local state for smooth UI
  • Handles optimistic updates (updates UI immediately, confirms with backend)

Backend:

  • Polls bluetoothctl every 2 seconds for metadata
  • Caches current track information
  • Updates position counter when playing

Error Handling

  • API failures fallback to local state
  • Connection errors are logged but don't crash the app
  • Missing metadata gracefully defaults to "Unknown"
  • Disconnection automatically stops polling

API Reference

REST Endpoints

POST /api/bluetooth/audio/connect/:address
  - Connects audio stream to specified device
  - Body: none
  - Response: { success: true, device: string }

POST /api/bluetooth/audio/disconnect
  - Disconnects current audio device
  - Body: none
  - Response: { success: true }

GET /api/bluetooth/audio/state
  - Gets current media playback state
  - Response: {
      connected: boolean,
      device: string,
      audioActive: boolean,
      isPlaying: boolean,
      track: {
        title: string,
        artist: string,
        album: string,
        duration: number,
        position: number
      }
    }

POST /api/bluetooth/audio/play
  - Sends play command to device
  - Response: { success: true, command: "play" }

POST /api/bluetooth/audio/pause
  - Sends pause command to device
  - Response: { success: true, command: "pause" }

POST /api/bluetooth/audio/next
  - Skips to next track
  - Response: { success: true, command: "next" }

POST /api/bluetooth/audio/previous
  - Goes to previous track
  - Response: { success: true, command: "previous" }

POST /api/bluetooth/audio/stop
  - Stops playback
  - Response: { success: true, command: "stop" }

Platform Support Status

Platform Status Implementation
Linux ✅ Full bluetoothctl + PulseAudio
Windows ⚠️ Partial Requires native module
macOS ⚠️ Partial Requires native module

Linux Requirements

  • BlueZ 5.50+
  • PulseAudio 10.0+ or PipeWire 0.3+
  • bluez-tools (optional, for advanced features)

Windows Requirements (Not Yet Implemented)

  • Would need: windows.devices.bluetooth via FFI
  • Or: Native Node.js addon using C++/WinRT

macOS Requirements (Not Yet Implemented)

  • Would need: IOBluetooth framework via FFI
  • Or: Native Node.js addon using Objective-C

Testing

With Real Device (Recommended)

  1. Run setup script: ./setup-bluetooth-audio.sh
  2. Start backend: cd src && node server.js
  3. Start frontend: npm run dev
  4. Pair phone via Bluetooth Settings
  5. Open Media Player
  6. Play music on phone

Without Real Device (Development)

The backend includes fallback mock data when no device is connected, allowing development without hardware.

Performance Considerations

  • Latency: 100-300ms typical for Bluetooth audio (acceptable for music)
  • Polling Overhead: 2-second intervals minimize CPU usage
  • Memory: Minimal, only stores current track info
  • Network: Local API calls only (no external services)

Security Considerations

  • Bluetooth pairing requires user confirmation on both devices
  • No authentication tokens stored (uses system Bluetooth stack)
  • Audio stream is direct phone → computer (no cloud services)
  • Metadata is parsed locally (no external API calls)

Known Limitations

  1. No seeking: AVRCP protocol doesn't support arbitrary position seeking
  2. No album art: Would require additional AVRCP 1.6+ support
  3. Single device: Only one audio source at a time
  4. Platform-specific: Full support currently only on Linux

Future Enhancements

Short-term (Feasible)

  • Album artwork support (AVRCP 1.6)
  • Volume control integration
  • Playlist/queue display
  • Audio visualizer

Medium-term (Requires Work)

  • Windows native support
  • macOS native support
  • Multiple device management
  • Bluetooth codec selection (aptX, AAC, LDAC)

Long-term (Ambitious)

  • Voice assistant integration
  • Podcast-specific features
  • Car integration features (steering wheel controls)
  • Navigation audio mixing

Dependencies

Runtime

  • express - Web server
  • cors - CORS middleware
  • System: bluetoothctl, pactl/pipewire

Development

  • React 19
  • Lucide React (icons)
  • Node.js 16+

How to Use

  1. Read the setup guide: BLUETOOTH_AUDIO_SETUP.md
  2. Run the setup script (Linux): ./setup-bluetooth-audio.sh
  3. Start the backend: node src/server.js
  4. Start the frontend: npm run dev
  5. Pair your device in Bluetooth Settings
  6. Navigate to Media Player and enjoy!

Credits

  • BlueZ project for Linux Bluetooth stack
  • PulseAudio/PipeWire for audio routing
  • AVRCP specification for media control protocol

Implementation Date: 2025-10-08 Status: Production Ready (Linux), Development (Windows/macOS) License: Same as NodeNav project