mirror of
https://github.com/librespot-org/librespot.git
synced 2024-11-08 16:45:43 +00:00
metadata: add lyrics
Save users from doing all the parsing themselves.
This commit is contained in:
parent
edf646d4bb
commit
f72048e5e1
5 changed files with 84 additions and 0 deletions
|
@ -94,6 +94,7 @@ https://github.com/librespot-org/librespot
|
||||||
Connect should use the 'filter-explicit-content' user attribute in the session.
|
Connect should use the 'filter-explicit-content' user attribute in the session.
|
||||||
- [playback] Add metadata support via a `TrackChanged` event
|
- [playback] Add metadata support via a `TrackChanged` event
|
||||||
- [connect] Add `activate` and `load` functions to `Spirc`, allowing control over local connect sessions
|
- [connect] Add `activate` and `load` functions to `Spirc`, allowing control over local connect sessions
|
||||||
|
- [metadata] Add `Lyrics`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1500,6 +1500,8 @@ dependencies = [
|
||||||
"librespot-protocol",
|
"librespot-protocol",
|
||||||
"log",
|
"log",
|
||||||
"protobuf",
|
"protobuf",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,6 +16,8 @@ log = "0.4"
|
||||||
protobuf = "2"
|
protobuf = "2"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
uuid = { version = "1", default-features = false }
|
uuid = { version = "1", default-features = false }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[dependencies.librespot-core]
|
[dependencies.librespot-core]
|
||||||
path = "../core"
|
path = "../core"
|
||||||
|
|
|
@ -18,6 +18,7 @@ pub mod episode;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod external_id;
|
pub mod external_id;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
|
pub mod lyrics;
|
||||||
pub mod playlist;
|
pub mod playlist;
|
||||||
mod request;
|
mod request;
|
||||||
pub mod restriction;
|
pub mod restriction;
|
||||||
|
@ -33,6 +34,7 @@ use request::RequestResult;
|
||||||
pub use album::Album;
|
pub use album::Album;
|
||||||
pub use artist::Artist;
|
pub use artist::Artist;
|
||||||
pub use episode::Episode;
|
pub use episode::Episode;
|
||||||
|
pub use lyrics::Lyrics;
|
||||||
pub use playlist::Playlist;
|
pub use playlist::Playlist;
|
||||||
pub use show::Show;
|
pub use show::Show;
|
||||||
pub use track::Track;
|
pub use track::Track;
|
||||||
|
|
77
metadata/src/lyrics.rs
Normal file
77
metadata/src/lyrics.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
use bytes::Bytes;
|
||||||
|
|
||||||
|
use librespot_core::{Error, FileId, Session, SpotifyId};
|
||||||
|
|
||||||
|
impl Lyrics {
|
||||||
|
pub async fn get(session: &Session, id: &SpotifyId) -> Result<Self, Error> {
|
||||||
|
let spclient = session.spclient();
|
||||||
|
let lyrics = spclient.get_lyrics(id).await?;
|
||||||
|
Self::try_from(&lyrics)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_for_image(
|
||||||
|
session: &Session,
|
||||||
|
id: &SpotifyId,
|
||||||
|
image_id: &FileId,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let spclient = session.spclient();
|
||||||
|
let lyrics = spclient.get_lyrics_for_image(id, image_id).await?;
|
||||||
|
Self::try_from(&lyrics)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&Bytes> for Lyrics {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(lyrics: &Bytes) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(lyrics).map_err(|err| err.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Lyrics {
|
||||||
|
pub colors: Colors,
|
||||||
|
pub has_vocal_removal: bool,
|
||||||
|
pub lyrics: LyricsInner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Colors {
|
||||||
|
pub background: i32,
|
||||||
|
pub highlight_text: i32,
|
||||||
|
pub text: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LyricsInner {
|
||||||
|
// TODO: 'alternatives' field as an array but I don't know what it's meant for
|
||||||
|
pub fullscreen_action: String,
|
||||||
|
pub is_dense_typeface: bool,
|
||||||
|
pub is_rtl_language: bool,
|
||||||
|
pub language: String,
|
||||||
|
pub lines: Vec<Line>,
|
||||||
|
pub provider: String,
|
||||||
|
pub provider_display_name: String,
|
||||||
|
pub provider_lyrics_id: String,
|
||||||
|
pub sync_lyrics_uri: String,
|
||||||
|
pub sync_type: SyncType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
pub enum SyncType {
|
||||||
|
Unsynced,
|
||||||
|
LineSynced,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Line {
|
||||||
|
pub start_time_ms: String,
|
||||||
|
pub end_time_ms: String,
|
||||||
|
pub words: String,
|
||||||
|
// TODO: 'syllables' array
|
||||||
|
}
|
Loading…
Reference in a new issue