A web-based tool to create, manage, and edit synchronized lyrics files (LRC and SRT) for audio tracks.
- Invite-only access with admin provisioning
- Optional MFA (TOTP) per user
- Per-user storage for audio, lyrics, LRC, and SRT files
- Track quota enforcement to prevent disk overuse
- Browser-based editor for synchronized lyrics
- Generate both LRC and SRT format synchronized lyrics files
- View and download the generated files directly from the browser
- Optional numbered SRT variant for editors that expect cue indices
- AI First Pass transcription + alignment (OpenAI Whisper) with a review UI
- Optional vocal stem input for AI runs
- Separate manual vs AI outputs (LRC/SRT)
- Python 3.9+
- SQLite (default)
- ffmpeg (required for AI transcription when audio exceeds API limits)
- Clone the repository:
git clone https://github.com/pexus/synced-lyrics-generator.git
cd synced-lyrics-generator- Create a virtual environment (optional but recommended):
python -m venv venv
source venv/bin/activate # On Windows, use `venv\Scripts\activate`- Install the requirements:
pip install -r requirements.txt- Configure environment variables (local example):
cp env.sample .env
# edit .env with your values- Run the application:
python app.py- Open your browser and navigate to:
http://127.0.0.1:5000/setup
This first-time setup lets you create the initial admin account.
If you want a clean slate locally:
rm -rf data storageThen run the app and visit /setup to create the first admin:
python app.py- Admins can invite users from the
/adminpanel. - Users receive an email invite, set their password, and can optionally enable MFA.
- Track quota is enforced per user (default: 20). Users must delete older tracks to upload new ones.
PUBLIC_BASE_URL: Used in invite emails. Set to your external host in production.MAX_TRACKS_PER_USER: Default quota used if no admin setting exists.SECRET_KEY: Required for session security.DATABASE_URL: Override the default SQLite path (optional).STORAGE_ROOT: Base directory for per-user files (optional).SMTP_*: SMTP server settings for invite emails.MFA_ISSUER: Optional label shown in authenticator apps.OPENAI_API_KEY: Required to use AI First Pass.OPENAI_TRANSCRIBE_TIMEOUT: Optional request timeout (seconds) for AI transcription.
storage/
user_<id>/
audio_input/
vocal_input/
lyrics_input/
ai_drafts/
lrc_output/
srt_output/
ai_lrc_output/
ai_srt_output/
Manual outputs are saved under lrc_output/ and srt_output/. AI outputs are saved separately under ai_lrc_output/ and ai_srt_output/.
The AI flow generates a draft SRT/LRC using OpenAI Whisper and then lets you review and correct timestamps.
- Upload an audio file and a lyrics
.txtfile. - (Optional) Upload a vocal stem for the same track.
- Click Generate using AI in the library.
- Choose whether to use the vocal stem, then start the run.
- Review and refine the AI draft in the AI Review page.
Notes:
- Use romanized (Latin letters) lyrics for the best alignment.
- Vocal stems can help some tracks, but full mixes may work better depending on the song.
Build and run locally:
docker build -t synced-lyrics .
docker run -p 5000:5000 \
-v $PWD/data:/app/data \
-v $PWD/storage:/app/storage \
synced-lyricsThe app auto-loads /app/data/.env if it exists. To use the sample values:
cp env.sample ./data/.envmkdir -p data storage
cp env.sample ./data/.env
docker compose up -dTo stop:
docker compose downA GitHub Actions workflow is included to build and publish images to GHCR on every push to main.
Pull the image:
docker pull ghcr.io/pexus/synced-lyrics-generator:latestManual build/push (optional, if you don't want to use GitHub Actions):
docker login ghcr.io
docker build -t ghcr.io/pexus/synced-lyrics-generator:latest .
docker push ghcr.io/pexus/synced-lyrics-generator:latest- Pull and run the container:
docker pull ghcr.io/pexus/synced-lyrics-generator:latest
docker run -d --name synced-lyrics \
-p 5000:5000 \
-v /opt/synced-lyrics/data:/app/data \
-v /opt/synced-lyrics/storage:/app/storage \
ghcr.io/pexus/synced-lyrics-generator:latestStore your environment values in /opt/synced-lyrics/data/.env so the container picks them up.
You can also use Docker Compose on the VPS (clone the repo to get docker-compose.yml):
cd /opt/synced-lyrics
mkdir -p data storage
cp env.sample /opt/synced-lyrics/data/.env
docker compose pull
docker compose up -d- Apache reverse proxy setup (Ubuntu example):
sudo apt-get update
sudo apt-get install -y apache2
sudo a2enmod proxy proxy_http headers rewrite sslCreate /etc/apache2/sites-available/synced-lyrics.conf:
<VirtualHost *:80>
ServerName your-domain.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
RequestHeader set X-Forwarded-Proto "http"
RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
</VirtualHost>Enable the site and reload:
sudo a2ensite synced-lyrics.conf
sudo apache2ctl configtest
sudo systemctl reload apache2- Free SSL via Certbot:
sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d your-domain.com --redirectCertbot will update the Apache vhost to include SSL and auto-renew certificates. After it runs, ensure the SSL vhost includes:
RequestHeader set X-Forwarded-Proto "https"This project is licensed under the MIT License - see the LICENSE file for details.
This project was created using "vibe coding" with GitHub Copilot, leveraging various AI models available.
- WaveSurfer.js for the audio waveform visualization
- Flask for the web framework
See FUTURE.md for planned enhancements.
Contributions are welcome! Please feel free to submit a Pull Request.
