[PR #2154] [MERGED] feat: add synchronized LRC lyrics support #2114

Closed
opened 2026-02-26 03:33:18 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/koel/koel/pull/2154
Author: @DzmingLi
Created: 10/25/2025
Status: Merged
Merged: 10/29/2025
Merged by: @phanan

Base: masterHead: lyrics-features-without-nix


📝 Commits (7)

  • ba2d542 fix: preserve LRC timestamps in lyrics
  • 73e950e feat: add synchronized lyrics display with LRC support
  • 385b386 refactor: improve LyricsPane component for synchronized lyrics
  • 493aec7 refactor: extract synchronized lyrics into separate components
  • bf667b1 test: add comprehensive tests for synchronized lyrics
  • 7391e0b fix: update test to reflect preserved LRC timestamps behavior
  • fe56925 feat: handle lyrics lines without timestamps in LRC format

📊 Changes

9 files changed (+410 additions, -5 deletions)

View changed files

📝 app/Casts/SongLyricsCast.php (+2 -2)
📝 resources/assets/js/components/ui/LyricsPane.spec.ts (+88 -0)
📝 resources/assets/js/components/ui/LyricsPane.vue (+76 -1)
resources/assets/js/components/ui/SyncLyricsLine.spec.ts (+31 -0)
resources/assets/js/components/ui/SyncLyricsLine.vue (+38 -0)
resources/assets/js/components/ui/SyncLyricsPane.spec.ts (+50 -0)
resources/assets/js/components/ui/SyncLyricsPane.vue (+114 -0)
resources/assets/js/components/ui/__snapshots__/SyncLyricsPane.spec.ts.snap (+9 -0)
📝 tests/Unit/Models/SongTest.php (+2 -2)

📄 Description

Description

This PR adds support for synchronized LRC lyrics with real-time highlighting and auto-scrolling. When a song has LRC-formatted lyrics with timestamps, the lyrics pane will automatically synchronize with playback, highlighting the current line and scrolling to keep it centered.

Motivation

Koel already supports reading LRC files (#1447, #1502) but displays them as plain text without synchronization. This enhancement provides a karaoke-style lyrics experience that improves the music listening experience, especially for users who enjoy following along with lyrics.

Checklist

  • I've tested my changes thoroughly and added tests where applicable
  • I've updated relevant documentation (if any)
  • My code follows the project's conventions

Technical Details

Backend Changes

  • SongLyricsCast: Modified to preserve LRC timestamps instead of stripping them from the database

Frontend Changes

  • LyricsPane.vue:
    • Parse LRC format with regex /\[(\d{2}):(\d{2})\.(\d{2,3})\](.*)/g
    • Monitor playback position every 100ms
    • Automatically scroll to keep current line centered
    • Apply visual highlighting to active line
    • Graceful fallback to plain text for non-LRC lyrics

Compatibility

  • Fully backward compatible with existing plain text lyrics
  • No database migrations required
  • Works with existing LRC files in the music library
  • Scanner already supports detecting LRC file changes (from #1502)
Screenshot from 2025-10-26 06-39-00

To cope with this , I also finished the synced lyrics feature for the mobile app and opened a separate PR

Screenshot_20251025-155257

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/koel/koel/pull/2154 **Author:** [@DzmingLi](https://github.com/DzmingLi) **Created:** 10/25/2025 **Status:** ✅ Merged **Merged:** 10/29/2025 **Merged by:** [@phanan](https://github.com/phanan) **Base:** `master` ← **Head:** `lyrics-features-without-nix` --- ### 📝 Commits (7) - [`ba2d542`](https://github.com/koel/koel/commit/ba2d5421c0b23bfa66318d10544919a598b9836b) fix: preserve LRC timestamps in lyrics - [`73e950e`](https://github.com/koel/koel/commit/73e950ec8db04a7e3b7a2fc97de819dd8b2a005a) feat: add synchronized lyrics display with LRC support - [`385b386`](https://github.com/koel/koel/commit/385b3863ecdc6a58825ea573914534163f5144b3) refactor: improve LyricsPane component for synchronized lyrics - [`493aec7`](https://github.com/koel/koel/commit/493aec708bde3aa9abed052325492e14653dd4fa) refactor: extract synchronized lyrics into separate components - [`bf667b1`](https://github.com/koel/koel/commit/bf667b10f8708f24d5d7350da2efb5cfaaebac89) test: add comprehensive tests for synchronized lyrics - [`7391e0b`](https://github.com/koel/koel/commit/7391e0b35dfe41219ab79b4fa9bdfbd220e17cba) fix: update test to reflect preserved LRC timestamps behavior - [`fe56925`](https://github.com/koel/koel/commit/fe5692531053e2119d68e4fff16f78c58a363110) feat: handle lyrics lines without timestamps in LRC format ### 📊 Changes **9 files changed** (+410 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `app/Casts/SongLyricsCast.php` (+2 -2) 📝 `resources/assets/js/components/ui/LyricsPane.spec.ts` (+88 -0) 📝 `resources/assets/js/components/ui/LyricsPane.vue` (+76 -1) ➕ `resources/assets/js/components/ui/SyncLyricsLine.spec.ts` (+31 -0) ➕ `resources/assets/js/components/ui/SyncLyricsLine.vue` (+38 -0) ➕ `resources/assets/js/components/ui/SyncLyricsPane.spec.ts` (+50 -0) ➕ `resources/assets/js/components/ui/SyncLyricsPane.vue` (+114 -0) ➕ `resources/assets/js/components/ui/__snapshots__/SyncLyricsPane.spec.ts.snap` (+9 -0) 📝 `tests/Unit/Models/SongTest.php` (+2 -2) </details> ### 📄 Description ## Description This PR adds support for synchronized LRC lyrics with real-time highlighting and auto-scrolling. When a song has LRC-formatted lyrics with timestamps, the lyrics pane will automatically synchronize with playback, highlighting the current line and scrolling to keep it centered. ## Motivation Koel already supports reading LRC files (#1447, #1502) but displays them as plain text without synchronization. This enhancement provides a karaoke-style lyrics experience that improves the music listening experience, especially for users who enjoy following along with lyrics. ## Checklist - [x] I've tested my changes thoroughly and added tests where applicable - [x] I've updated relevant documentation (if any) - [x] My code follows the project's conventions ## Technical Details ### Backend Changes - **SongLyricsCast**: Modified to preserve LRC timestamps instead of stripping them from the database ### Frontend Changes - **LyricsPane.vue**: - Parse LRC format with regex `/\[(\d{2}):(\d{2})\.(\d{2,3})\](.*)/g` - Monitor playback position every 100ms - Automatically scroll to keep current line centered - Apply visual highlighting to active line - Graceful fallback to plain text for non-LRC lyrics ### Compatibility - Fully backward compatible with existing plain text lyrics - No database migrations required - Works with existing LRC files in the music library - Scanner already supports detecting LRC file changes (from #1502) <img width="2089" height="1412" alt="Screenshot from 2025-10-26 06-39-00" src="https://github.com/user-attachments/assets/95074da8-8e0c-4284-b8e1-ab86edebe8f2" /> To cope with this , I also finished the synced lyrics feature for the mobile app and [opened a separate PR ](https://github.com/koel/player/pull/114) <img width="1224" height="2700" alt="Screenshot_20251025-155257" src="https://github.com/user-attachments/assets/d7d578c6-5469-4c5e-9d86-5de98aa88c19" /> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-26 03:33:18 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/koel-koel#2114
No description provided.