UNPKG

justlyrics

Version:

A comprehensive TypeScript library for parsing, converting, and processing various lyric formats including LRC, ALRC, YRC, QRC, and more

333 lines (252 loc) 9.29 kB
# JustLyrics A powerful TypeScript library for parsing, manipulating, and converting lyrics in multiple formats. JustLyrics provides a unified API for handling synchronized lyrics with support for syllable-level timing, multi-language annotations, and various popular lyric formats. ## Features - **Multiple Format Support**: Convert between LRC, QRC, YRC, SRT, ALRC, LYS, LYL, LQE, SPL, and TTML formats - **Syllable-Level Timing**: Handle precise syllable synchronization for karaoke-style applications - **Multi-Language Support**: Built-in support for translations and pronunciation annotations - **Voice Agent Detection**: Distinguish between main vocals, background vocals, and duet parts - **CJK Character Detection**: Advanced handling of Chinese, Japanese, and Korean text - **AMLL Integration**: Import and convert AMLL (Another Music Lyrics Library) format lyrics - **Browser File API**: Read and write lyric files directly in the browser ## Installation ```bash npm install justlyrics ``` ## Quick Start ```typescript import { CoreLyric, LyricIO, LyricFormat } from 'justlyrics'; // Create a simple line-synced lyric const line = new CoreLyric.LineSyncedLine({ text: "Hello world", start: new CoreLyric.Timestamp(1000), // 1 second end: new CoreLyric.Timestamp(3000) // 3 seconds }); // Convert to LRC format const lrcOutput = LyricIO.Dumping.dumpLRC([line]); console.log(lrcOutput); // [00:01.000]Hello world // Convert to other formats const qrcOutput = LyricIO.Dumping.dumpQRC([line]); const srtOutput = LyricIO.Dumping.dumpSRT([line]); ``` ## Core Concepts ### Timestamps ```typescript // Create timestamps (in milliseconds) const start = new CoreLyric.Timestamp(1500); // 1.5 seconds console.log(start.seconds()); // 1.5 console.log(start.formatted()); // "0:01" // Timestamp utilities const maxTime = CoreLyric.Timestamp.max(start, new CoreLyric.Timestamp(2000)); const minTime = CoreLyric.Timestamp.min(start, new CoreLyric.Timestamp(500)); ``` ### Line Types #### LineSyncedLine (Line-level timing) ```typescript const lineSynced = new CoreLyric.LineSyncedLine({ text: "This is a complete line", start: new CoreLyric.Timestamp(1000), end: new CoreLyric.Timestamp(4000), voiceAgent: { type: CoreLyric.VoiceAgentType.Vocal, n: 1 } }); ``` #### SyllableSyncedLine (Syllable-level timing) ```typescript const syllables = [ { text: "Hel", start: new CoreLyric.Timestamp(1000), end: new CoreLyric.Timestamp(1300), annotations: [] }, { text: "lo", start: new CoreLyric.Timestamp(1300), end: new CoreLyric.Timestamp(1600), annotations: [] } ]; const syllableSynced = new CoreLyric.SyllableSyncedLine({ syllables, voiceAgent: { type: CoreLyric.VoiceAgentType.Vocal, n: 1 }, annotations: [] }); ``` ### Voice Agents Distinguish between different vocal parts: ```typescript // Main vocal const mainVocal = { type: CoreLyric.VoiceAgentType.Vocal, n: 1 }; // Background vocal const backgroundVocal = { type: CoreLyric.VoiceAgentType.BackgroundVocal, n: 1 }; // Duet (second singer) const duetVocal = { type: CoreLyric.VoiceAgentType.Vocal, n: 2 }; ``` ### Annotations Add translations and pronunciations: ```typescript const lineWithTranslation = new CoreLyric.LineSyncedLine({ text: "こんにちは", start: new CoreLyric.Timestamp(1000), end: new CoreLyric.Timestamp(3000), annotations: [ { role: CoreLyric.LineAnnotationRole.Translation, line: CoreLyric.LineSyncedLine.fromText("Hello") }, { role: CoreLyric.LineAnnotationRole.Prononciation, line: CoreLyric.LineSyncedLine.fromText("konnichiwa") } ] }); // Extract annotations const translations = lineWithTranslation.extractAnnotations( CoreLyric.LineAnnotationRole.Translation ); ``` ## Format Support ### Supported Output Formats | Format | Description | Extension | | ------ | ------------------------------------ | --------- | | LRC | Standard LRC format | `.lrc` | | QRC | QQ Music format with syllable timing | `.qrc` | | YRC | NetEase Cloud Music format | `.yrc` | | SRT | SubRip subtitle format | `.srt` | | ALRC | Advanced LRC with JSON structure | `.alrc` | | LYS | Lyricify Syllable format | `.lys` | | LYL | Lyricify Lines format | `.lyl` | | LQE | Lyricify Quick Export | `.lqe` | | SPL | Salt Player Lyrics | `.lrc` | ### Format Conversion ```typescript const lines = [/* your lyric lines */]; // Convert to different formats const lrcOutput = LyricIO.Dumping.dump('lrc', lines); const qrcOutput = LyricIO.Dumping.dump('qrc', lines); const yrcOutput = LyricIO.Dumping.dump('yrc', lines); const srtOutput = LyricIO.Dumping.dump('srt', lines); // Check format support const isSupported = LyricIO.Dumping.supportDump('lrc'); // true ``` ## Browser File Operations ### Reading Lyric Files ```typescript // Request file from user const content = await LyricFormat.requestReadLyricsFile( "Select lyric file", [".lrc", ".qrc", ".yrc"] ); if (content) { // Process the lyric content console.log("File content:", content); } ``` ### Writing Lyric Files ```typescript const lyricContent = LyricIO.Dumping.dumpLRC(lines); // Save file to user's system const saved = await LyricFormat.requestWriteLyricsFile( "Save lyrics as LRC", [".lrc"], lyricContent, { fileName: "my-lyrics.lrc" } ); if (saved) { console.log("File saved successfully!"); } ``` ## AMLL Integration Convert from AMLL format: ```typescript import { attLinesToCoreLyric, attMetaToLrcHeader } from 'justlyrics'; // Convert AMLL lines to CoreLyric format const coreLines = attLinesToCoreLyric(amllLines); // Generate LRC header from AMLL metadata const lrcHeader = attMetaToLrcHeader(amllMetadata); ``` ## Utilities ### CJK Character Detection ```typescript import { isCJKChar } from 'justlyrics'; console.log(isCJKChar('你')); // true console.log(isCJKChar('A')); // false console.log(isCJKChar('こんにちは')); // true ``` ### DOM Utilities ```typescript import { waitFor, autoTrimContainer } from 'justlyrics'; // Wait for element to appear const element = await waitFor<HTMLDivElement>('.lyric-container'); // Auto-trim container based on condition autoTrimContainer(container, (el) => el.textContent?.trim() === ''); ``` ## Advanced Usage ### Preprocessing for Lyricify ```typescript // Preprocess lines for better syllable splitting const preprocessedLines = CoreLyric.Utils.preprocessLinesForLyricify(lines); ``` ### Extracting Annotations ```typescript // Extract all translations from multiple lines const translations = CoreLyric.Utils.extractLineAnnotations( lines, CoreLyric.LineAnnotationRole.Translation ); // Extract all pronunciations const pronunciations = CoreLyric.Utils.extractLineAnnotations( lines, CoreLyric.LineAnnotationRole.Prononciation ); ``` ### Word Syllable Splitting ```typescript // Split a syllable into word components const syllable = { text: "Hello world", start: new CoreLyric.Timestamp(1000), end: new CoreLyric.Timestamp(3000), annotations: [] }; const splitSyllables = CoreLyric.Utils.splitWordSyllables(syllable); ``` ## API Reference ### CoreLyric Namespace - `Timestamp` - Time representation with utilities - `LineSyncedLine` - Line-level synchronized lyrics - `SyllableSyncedLine` - Syllable-level synchronized lyrics - `VoiceAgentType` - Enum for vocal types - `LineAnnotationRole` - Enum for annotation types - `Utils` - Utility functions for lyric processing ### LyricIO Namespace - `Dumping` - Functions for converting to various formats - `Abstraction.ALRC` - ALRC format type definitions ### LyricFormat Namespace - `TYPES` - Supported format definitions - `requestReadLyricsFile()` - Browser file reading - `requestWriteLyricsFile()` - Browser file writing ## Contributing We welcome contributions from the community. Please read our license terms to understand the different rights for Tier 1 and Tier 2 licensees. ## Support For support and questions, please check our documentation or open an issue on the project repository. ## License This project is licensed under the Lakelink's University Campus Access Public License (LKLK-CAPL) Version 3.0. © [2025] Sheng Fan Licensed under the Lakelink's University Campus Access Public License (LKLK-CAPL) Version 3.0: https://github.com/Lakelink/LKLK-CAPL/blob/main/LICENSE By exercising your rights under LKLK-CAPL, you affirm that you have read and understand this license and you confirm whether you're authorized as Tier 1 or Tier 2. Rights might differ depending on your authorization status.