No description
Find a file
Markus Walther acf5110cbf .
2025-12-21 08:08:16 +01:00
.github init semi-runnning 2025-12-19 18:27:07 +01:00
.vscode i18n 2025-12-20 20:45:55 +01:00
backend sync QM tag 2025-12-21 01:44:04 +01:00
frontend sync QM tag 2025-12-21 01:44:04 +01:00
locales library changes 2025-12-20 16:22:00 +01:00
plugins init semi-runnning 2025-12-19 18:27:07 +01:00
scripts init semi-runnning 2025-12-19 18:27:07 +01:00
tests fixes 2025-12-19 20:29:34 +01:00
.aider.conf.yml init semi-runnning 2025-12-19 18:27:07 +01:00
.cursorrules init semi-runnning 2025-12-19 18:27:07 +01:00
.gitignore init semi-runnning 2025-12-19 18:27:07 +01:00
config.json init semi-runnning 2025-12-19 18:27:07 +01:00
I18N_EXAMPLES.md init semi-runnning 2025-12-19 18:27:07 +01:00
I18N_GUIDE.md init semi-runnning 2025-12-19 18:27:07 +01:00
I18N_QUICKREF.md init semi-runnning 2025-12-19 18:27:07 +01:00
IDENTIFIER_REFACTOR_SUMMARY.md . 2025-12-20 14:26:51 +01:00
LICENSE Initial commit 2025-12-19 11:46:38 +01:00
LOCALIZATION_COMPLETE.md init semi-runnning 2025-12-19 18:27:07 +01:00
LOCALIZATION_STATUS.md init semi-runnning 2025-12-19 18:27:07 +01:00
migrate_data.py . 2025-12-20 14:26:51 +01:00
migrate_to_identifier.py . 2025-12-20 14:26:51 +01:00
PROJECT_GUIDE.md init semi-runnning 2025-12-19 18:27:07 +01:00
pyproject.toml init semi-runnning 2025-12-19 18:27:07 +01:00
README.md . 2025-12-21 07:54:08 +01:00
requirements.txt init semi-runnning 2025-12-19 18:27:07 +01:00
setup-pi-client.sh . 2025-12-21 07:58:27 +01:00
setup-pi-server.sh . 2025-12-21 08:08:16 +01:00
SONG_LIBRARY_CHANGES.md library changes 2025-12-20 16:22:00 +01:00
test_identifier_fixes.py . 2025-12-20 16:14:36 +01:00
test_output.txt . 2025-12-20 14:26:51 +01:00
uv.lock init semi-runnning 2025-12-19 18:27:07 +01:00
VERIFICATION_CHECKLIST.md init semi-runnning 2025-12-19 18:27:07 +01:00

Organist - Music Player for Religious Services

A real-time synchronized music player server application built with Python, FastAPI, and Socket.IO. Designed for live music playback in religious services with multi-device synchronization.

Features

  • Real-time Synchronization: All connected clients see the same state instantly
  • Song Library Management: Upload, tag, and edit songs with identifiers
  • Flexible Playlist Editor: Build playlists with auto-stop flags; search and add songs dynamically
  • Smart Quick-Play: Live-search dropdown to find and play songs by identifier, filename, or tags
  • Auto-Advance: Automatically progress through playlists with customizable stop points
  • Full-Width Controls: Large, touch-friendly player buttons with clear visual feedback
  • Responsive Layout: Flexible panes for songs/playlists (scrollable list + fixed editor)
  • Volume Synchronization: Real-time volume control synchronized across server and clients
  • Multi-Language Support: Internationalized UI with language selector
  • Plugin System: Extend functionality with local plugins for emergency control
  • Remote Control: Control playback from any connected browser on any device

Architecture

Backend (Python)

  • FastAPI: Modern, async web framework
  • Socket.IO: Real-time bidirectional communication with fallbacks
  • python-vlc: Server-side audio playback through system audio interface
  • Async I/O: Non-blocking operations for smooth real-time updates

Frontend (Vanilla JavaScript)

  • No build tools: Plain JavaScript, HTML, and CSS—works in any browser
  • No browser audio playback: All audio plays only on the server
  • Client-side rendering: Dynamic UI with i18n support
  • Socket.IO client: Real-time state synchronization
  • Responsive design: Mobile-friendly, touch-optimized interface

Key Design Principles

  • Server-authoritative state: All state changes happen on the server and broadcast to clients
  • Single source of truth: No conflicting local state between clients
  • Immediate UI sync: All connected clients update within milliseconds
  • Touch-friendly: Large buttons, clear labels, and responsive spacing for live service use

Installation

Prerequisites

  • Python 3.8+
  • VLC media player installed on the system
  • uv - Fast Python package installer

Setup

  1. Clone the repository:
git clone https://github.com/your-organization/Organist.git
cd Organist
  1. Install uv (if not already installed):
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
  1. Install dependencies and create virtual environment:
uv sync
  1. Run the server:
uv run python -m backend.main
  1. Open your browser to: http://localhost:8000

Alternative: Quick Start

# One command to install and run
uv run python -m backend.main

Installation on Raspberry Pi 5 with Raspbian Trixie

Two automated setup scripts are provided to deploy Organist on a Raspberry Pi 5:

  • setup-pi-server.sh - WiFi hotspot/access point mode (10.76.x.x subnet)
  • setup-pi-client.sh - WiFi client mode (connects to existing network)

Prerequisites

  • Raspberry Pi 5 with Raspbian Trixie (Debian Trixie derivative)
  • Micro-SD card (32GB recommended)
  • Power supply
  • Organist repository checked out on the Pi

Quick Setup (Automated)

  1. Clone the repository (or copy it to the Pi):
cd ~
git clone https://github.com/your-organization/Organist.git
cd Organist
  1. Run the appropriate setup script:

For WiFi Hotspot/Server Mode (creates "Organist" WiFi network):

sudo bash setup-pi-server.sh

For WiFi Client Mode (connects to existing WiFi):

sudo bash setup-pi-client.sh
  1. Follow the prompts to configure:

    • WiFi SSID and password
    • IP address (server mode only)
    • DHCP range (server mode only)
    • System user (default: organist)
  2. Reboot when prompted.

What the Scripts Install

Both scripts automatically:

  • Update system packages
  • Install dependencies (Python, VLC, uv, networking tools)
  • Create system user
  • Copy Organist to /opt/organist
  • Install Python dependencies with uv
  • Create systemd service for auto-start
  • Enable and configure services

Server Mode (setup-pi-server.sh) additionally:

  • Configures WiFi access point (hostapd)
  • Sets up DHCP server (dnsmasq)
  • Assigns static IP (default: 10.76.0.1)
  • Enables IP forwarding

Client Mode (setup-pi-client.sh) additionally:

  • Configures wpa_supplicant for WiFi client
  • Connects to existing network
  • Uses DHCP-assigned IP from your router

Verify Installation

For Server Mode:

  1. Look for WiFi network: Organist (or your chosen SSID)
  2. Connect with the password you configured
  3. Open browser: http://10.76.0.1:8000 (or your chosen IP)

For Client Mode:

  1. Find the Pi's IP from your router (or use organist.local)
  2. Open browser: http://<pi-ip>:8000

Check service status on the Pi:

sudo systemctl status organist
sudo journalctl -u organist -f

Manual Setup (Advanced)

If you prefer manual setup or need to customize beyond the script options, follow the detailed steps in the script source code or contact the maintainers.

Network Details (Server Mode Default)

  • WiFi SSID: Organist
  • WiFi Password: (configured during setup)
  • AP IP Address: 10.76.0.1
  • DHCP Range: 10.76.0.2 10.76.0.254
  • App URL: http://10.76.0.1:8000

Troubleshooting

WiFi not appearing (server mode):

sudo rfkill list
sudo rfkill unblock all  # If blocked
sudo systemctl restart hostapd

Cannot connect to app:

# Check Organist status
sudo systemctl status organist

# Restart all services
sudo systemctl restart organist hostapd dnsmasq  # server mode
sudo systemctl restart organist  # client mode

# View logs
sudo journalctl -u organist -n 50 -f

Find IP address (client mode):

hostname -I  # Shows all IP addresses
ip addr show wlan0  # WiFi interface details

Change WiFi password (server mode): Edit /etc/hostapd/hostapd.conf, change wpa_passphrase, then:

sudo systemctl restart hostapd

Usage

Player View

  • Play/Pause Button (green when ready to play): Start or resume playback
  • Stop Button (red): Stop playback and clear current song
  • Previous/Next Buttons: Navigate through loaded playlist
  • Volume Slider: Adjust volume with live feedback (synchronized across all clients)
  • Quick-Play Search: Type to search songs by identifier, filename, or tags; click a result to fill the field, then press Play

Song Library

  1. Navigate to the Library section
  2. Upload audio files individually, as folders, or as ZIP archives
  3. Optionally add identifiers and tags during upload
  4. Click the Edit button next to any song to modify filename, identifier, or tags
  5. Songs appear as a scrollable list; editor panel stays fixed at bottom

Playlist Editor

  1. Navigate to the Playlists section
  2. Create a new playlist using the form
  3. Click Edit on a playlist to open the editor:
    • Search results appear on the left (searchable by identifier, filename, or tags)
    • Your playlist entries appear on the right
    • Drag-add songs from search results to your playlist
    • Mark songs with "Stop After" to pause at that point
    • Save your changes
  4. On the player, use the dropdown to load a playlist and press Play

Auto-Advance

  • When a song ends and has the "Stop After" flag set, Organist automatically advances to the next song in the playlist
  • If it's the last song in the playlist, it wraps to the first song
  • Manual stop (clicking the Stop button) does not trigger auto-advance

Multi-Client Synchronization

  • Open the app on multiple devices connected to the same network
  • All clients mirror each other's state in real-time
  • Any client can control playback; all others update simultaneously
  • Perfect for distributed service leadership and coordination

Plugin Development

Create custom plugins in the plugins/ directory:

class Plugin:
    def __init__(self):
        self.name = "My Plugin"
    
    def setup(self):
        # Initialize plugin
        pass

See plugins/local_interface.py for an emergency control example.

Configuration

Edit config.json to customize:

  • Server host and port
  • Data directories
  • Default audio settings
  • Plugin settings

Project Structure

Organist/
├── backend/
│   ├── main.py              # FastAPI + Socket.IO server, HTTP endpoints
│   ├── audio_player.py      # VLC audio interface
│   ├── song_manager.py      # Song library and metadata management
│   ├── playlist_manager.py  # Playlist CRUD and lifecycle
│   └── plugin_manager.py    # Plugin loading and management
├── frontend/
│   ├── index.html           # Single-page application markup
│   └── static/
│       ├── app.js           # Socket.IO client, UI logic, state management
│       ├── style.css        # Dark theme styling, responsive layout
│       └── i18n.js          # Internationalization engine
├── locales/                 # Translation JSON files
│   ├── en.json
│   ├── es.json
│   └── ...
├── plugins/
│   └── local_interface.py   # Example plugin: emergency local control
├── data/                    # Runtime data (created on first run)
│   ├── songs/               # Uploaded audio files
│   ├── songs.json           # Song metadata with identifiers and tags
│   └── playlists.json       # Playlist definitions
├── pyproject.toml           # Python dependencies (uv)
├── config.json              # Application configuration
└── README.md

HTTP API Endpoints

Songs

  • GET /api/songs - List all songs with metadata
  • GET /api/tags - List all unique tags across songs
  • POST /api/songs/upload - Upload a single song file
  • POST /api/songs/bulk-upload - Upload multiple files (folder or ZIP)
  • PUT /api/songs/{song_id} - Update song metadata (identifier, tags)

Playlists

  • GET /api/playlists - List all playlists
  • POST /api/playlists - Create a new playlist
  • PUT /api/playlists/{playlist_id} - Update playlist entries

Health & Status

  • GET / - Main application interface
  • GET /health - Server health check

Socket.IO Events

Client → Server

  • play_song(song_id) - Play a song by ID
  • play_next() - Advance to next song in playlist
  • pause_playback() - Toggle play/pause
  • stop_playback() - Stop and clear current song
  • load_playlist(playlist_id) - Load a playlist
  • load_song_at_index(playlist_index, auto_play) - Load song at playlist position
  • change_view(view) - Switch UI section (synced across all clients)
  • set_volume(volume) - Set volume (0100)

Server → Client

  • state_update(state) - Full application state
  • songs_updated(songs) - Song library changed
  • playlists_updated(playlists) - Playlists changed

Data Models

Song

{
  "id": "uuid",
  "filename": "My Song.mp3",
  "identifier": "101",
  "tags": ["hymn", "morning"],
  "file_path": "data/songs/101_My Song.mp3",
  "uploaded_at": "2025-12-21T10:30:00Z",
  "duration": 180000
}

Playlist

{
  "id": "uuid",
  "name": "Sunday Service",
  "created_at": "2025-12-21T09:00:00Z",
  "modified_at": "2025-12-21T10:00:00Z",
  "entries": [
    {
      "song_id": "uuid",
      "stop_after": false
    },
    {
      "song_id": "uuid",
      "stop_after": true
    }
  ]
}

Troubleshooting

VLC Not Found

Ensure VLC media player is installed on your system. The python-vlc library requires the VLC executable.

Audio Not Playing

  • Check the server console for VLC errors
  • Verify audio file paths and supported formats (MP3, WAV, FLAC, OGG, M4A, AAC, WMA)
  • Test VLC playback directly to confirm system audio setup

Clients Out of Sync

  • Refresh the browser page
  • Check browser console for Socket.IO connection errors
  • Ensure all clients can reach the server IP/port

Bulk Upload Fails

  • Verify ZIP or folder contains only supported audio files
  • Check file permissions and disk space
  • Ensure identifiers are unique or generated correctly

Future Enhancements

  • Keyboard shortcuts for playback control
  • Drag-and-drop playlist reordering
  • Playback position tracking
  • Volume fade in/out
  • Song search within playlists
  • Multiple audio output device selection
  • Playlist import/export
  • Song editing UI (currently API only)

License

See LICENSE file for details.

Support

For issues or questions, please open an issue in the repository.