diff options
| author | salmonik <raisersoft@proton.me> | 2026-06-07 21:56:40 +0300 |
|---|---|---|
| committer | salmonik <raisersoft@proton.me> | 2026-06-07 21:56:40 +0300 |
| commit | 3aea522b0969e0d41cb3d0eec737563518dfe861 (patch) | |
| tree | 04d28e1fed7613419f3bc96dd9fcdc844f91ca12 | |
| parent | Add lyrics support (diff) | |
| download | rsplayer-3aea522b0969e0d41cb3d0eec737563518dfe861.tar.gz rsplayer-3aea522b0969e0d41cb3d0eec737563518dfe861.zip | |
change lrc lyrics display.
| -rw-r--r-- | Cargo.lock | 46 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | src/daemon.rs | 22 |
3 files changed, 44 insertions, 27 deletions
| @@ -3,6 +3,29 @@ | |||
| 3 | version = 4 | 3 | version = 4 |
| 4 | 4 | ||
| 5 | [[package]] | 5 | [[package]] |
| 6 | name = "RSPlayer" | ||
| 7 | version = "0.8.5" | ||
| 8 | dependencies = [ | ||
| 9 | "clap", | ||
| 10 | "clap_complete", | ||
| 11 | "cpal", | ||
| 12 | "ctrlc", | ||
| 13 | "directories", | ||
| 14 | "dirs", | ||
| 15 | "hex", | ||
| 16 | "libc", | ||
| 17 | "md-5", | ||
| 18 | "notify-rust", | ||
| 19 | "rand 0.10.1", | ||
| 20 | "reqwest", | ||
| 21 | "rusqlite", | ||
| 22 | "serde", | ||
| 23 | "serde_json", | ||
| 24 | "symphonia", | ||
| 25 | "toml", | ||
| 26 | ] | ||
| 27 | |||
| 28 | [[package]] | ||
| 6 | name = "alsa" | 29 | name = "alsa" |
| 7 | version = "0.11.0" | 30 | version = "0.11.0" |
| 8 | source = "registry+https://github.com/rust-lang/crates.io-index" | 31 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1947,29 +1970,6 @@ dependencies = [ | |||
| 1947 | ] | 1970 | ] |
| 1948 | 1971 | ||
| 1949 | [[package]] | 1972 | [[package]] |
| 1950 | name = "rsp" | ||
| 1951 | version = "0.8.5" | ||
| 1952 | dependencies = [ | ||
| 1953 | "clap", | ||
| 1954 | "clap_complete", | ||
| 1955 | "cpal", | ||
| 1956 | "ctrlc", | ||
| 1957 | "directories", | ||
| 1958 | "dirs", | ||
| 1959 | "hex", | ||
| 1960 | "libc", | ||
| 1961 | "md-5", | ||
| 1962 | "notify-rust", | ||
| 1963 | "rand 0.10.1", | ||
| 1964 | "reqwest", | ||
| 1965 | "rusqlite", | ||
| 1966 | "serde", | ||
| 1967 | "serde_json", | ||
| 1968 | "symphonia", | ||
| 1969 | "toml", | ||
| 1970 | ] | ||
| 1971 | |||
| 1972 | [[package]] | ||
| 1973 | name = "rsqlite-vfs" | 1973 | name = "rsqlite-vfs" |
| 1974 | version = "0.1.0" | 1974 | version = "0.1.0" |
| 1975 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1975 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1,5 +1,5 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "rsp" | 2 | name = "RSPlayer" |
| 3 | version = "0.8.5" | 3 | version = "0.8.5" |
| 4 | edition = "2024" | 4 | edition = "2024" |
| 5 | description = "Rust music player daemon with Unix socket IPC" | 5 | description = "Rust music player daemon with Unix socket IPC" |
| @@ -9,6 +9,7 @@ keywords = ["music", "player", "daemon", "audio"] | |||
| 9 | categories = ["multimedia", "command-line-utilities"] | 9 | categories = ["multimedia", "command-line-utilities"] |
| 10 | 10 | ||
| 11 | [lib] | 11 | [lib] |
| 12 | name = "rsp" | ||
| 12 | path = "src/lib.rs" | 13 | path = "src/lib.rs" |
| 13 | 14 | ||
| 14 | [[bin]] | 15 | [[bin]] |
diff --git a/src/daemon.rs b/src/daemon.rs index 0590f71..a0de698 100644 --- a/src/daemon.rs +++ b/src/daemon.rs | |||
| @@ -523,14 +523,21 @@ fn handle_lyrics_stream(stream: &mut UnixStream, audio: &Arc<AudioEngine>) { | |||
| 523 | return; | 523 | return; |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | let mut last_idx = None; | ||
| 527 | let mut prev_line_count = 0; | ||
| 526 | loop { | 528 | loop { |
| 527 | let pos = audio.position(); | 529 | let pos = audio.position(); |
| 528 | let current_idx = lyrics.iter().rposition(|l| l.time <= pos).unwrap_or(0); | 530 | let current_idx = lyrics.iter().rposition(|l| l.time <= pos).unwrap_or(0); |
| 531 | if last_idx == Some(current_idx) { | ||
| 532 | thread::sleep(Duration::from_millis(100)); | ||
| 533 | continue; | ||
| 534 | } | ||
| 535 | last_idx = Some(current_idx); | ||
| 536 | |||
| 529 | let start = current_idx.saturating_sub(1); | 537 | let start = current_idx.saturating_sub(1); |
| 530 | let end = (current_idx + 3).min(lyrics.len()); | 538 | let end = (current_idx + 3).min(lyrics.len()); |
| 531 | 539 | ||
| 532 | let mut output = String::new(); | 540 | let mut output = String::new(); |
| 533 | output.push_str("\x1b[2J\x1b[H"); | ||
| 534 | for (idx, l) in lyrics.iter().enumerate().take(end).skip(start) { | 541 | for (idx, l) in lyrics.iter().enumerate().take(end).skip(start) { |
| 535 | if idx == current_idx { | 542 | if idx == current_idx { |
| 536 | output.push_str(&format!(" > {}\n", l.text)); | 543 | output.push_str(&format!(" > {}\n", l.text)); |
| @@ -538,13 +545,22 @@ fn handle_lyrics_stream(stream: &mut UnixStream, audio: &Arc<AudioEngine>) { | |||
| 538 | output.push_str(&format!(" {}\n", l.text)); | 545 | output.push_str(&format!(" {}\n", l.text)); |
| 539 | } | 546 | } |
| 540 | } | 547 | } |
| 541 | if stream.write_all(output.as_bytes()).is_err() { | 548 | let line_count = output.lines().count(); |
| 549 | let mut frame = String::new(); | ||
| 550 | if prev_line_count > 0 { | ||
| 551 | frame.push_str(&format!("\x1b[{}A\x1b[1B", prev_line_count)); | ||
| 552 | } else { | ||
| 553 | frame.push_str(&format!("\x1b[2K")); | ||
| 554 | } | ||
| 555 | frame.push_str(&output); | ||
| 556 | if stream.write_all(frame.as_bytes()).is_err() { | ||
| 542 | break; | 557 | break; |
| 543 | } | 558 | } |
| 544 | if stream.flush().is_err() { | 559 | if stream.flush().is_err() { |
| 545 | break; | 560 | break; |
| 546 | } | 561 | } |
| 547 | thread::sleep(Duration::from_millis(200)); | 562 | prev_line_count = line_count; |
| 563 | thread::sleep(Duration::from_millis(100)); | ||
| 548 | } | 564 | } |
| 549 | } | 565 | } |
| 550 | 566 | ||
