Skip to content

Commit

Permalink
Add support for getting lyrics from spotify
Browse files Browse the repository at this point in the history
  • Loading branch information
Moeweb647252 committed Oct 5, 2024
1 parent 64163dd commit 91d5345
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ font-loader = "0.11.0"
log = "0.4.22"
mpris = "2.0.1"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
serde_yaml = "0.9.34"
simsearch = "0.2.5"
ureq = "2.10.1"

[profile.release]
strip = true
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ pub struct Config {
pub player_name: String,
pub fuzzy: bool,
pub auto_resize: bool,
pub spotify_access_token: Option<String>,
pub spotify_client_token: Option<String>,
}

impl Config {
Expand Down
53 changes: 53 additions & 0 deletions src/fetch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use serde_json::Value;

use crate::lyric::{Lyric, LyricLine};

pub fn fetch_spotify_lyric(token: &str, client_token: &str) -> Option<Lyric> {
if let Value::Object(obj) = serde_json::from_str(
&ureq::get("https://api.spotify.com/v1/me/player/currently-playing")
.set("authorization", token)
.call()
.ok()?
.into_string()
.ok()?,
)
.ok()?
{
if let Value::Object(item) = obj.get("item")? {
if let Value::String(id) = item.get("id")? {
if let Value::Object(obj) = serde_json::from_str(ureq::get(
format!("https://spclient.wg.spotify.com/color-lyrics/v2/track/{}?format=json&vocalRemoval=false&market=from_token", id)
.as_str())
.set("authorization", token)
.set("client-token",client_token)
.set("app-platform", "WebPlayer").call().ok()?.into_string().ok()?.as_str()).ok()? {
if let Value::Array(lines) = obj.get("lyrics")?.as_object()?.get("lines")? {
return Some(Lyric{
lines: lines.iter().map(|v| {
LyricLine{
content: v.get("words").unwrap().as_str().unwrap().to_string(),
begin: v.get("startTimeMs").unwrap().as_str().unwrap().parse().unwrap(),
end: v.get("endTimeMs").unwrap().as_str().unwrap().parse().unwrap(),
}
}).collect()
}) ;
}
}
}
}
}

None
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fetch_spotify_lyric() {
let token = "Bearer BQCLZPuRBUCJ2iexfHHwWVDwiegJB2dJrJ81mI5IJ8O6krLKWpLrzPdcO3-5omlmpcQmKZLBUCr3EDnkyqKbIf9G9Y7CZX9DU9NbjBaOmSAZ_-pT1rjc5GzgUa2tsRb3JDwDmNpigMxrOwQPKd1yjBgnVSamsxcOvWoISH1F4htIzRkIrP3wxDVar6JOV3ouR2CdOb2M1s6c6Eln21OdU5eCseKD8IyeDLE4T7GTeAen-Hs8wgJVWGutNBtLsxOtjVg6MXnU8EGg77tQqYhk3BmEvUp2bevFg-h7sL4GwDGPI8ouxkmcADMZl-wbk251ZEUGOP8ScORx9BLrU0C8upUp-j5a_6tzLP343ug";
let client_token = "AABN2xRCJyE/dFUZATsFD8vNSUxxVcREklxUyfw2Whw9cGwEszAmQdT7y5cWNvsbHJqcnMzrxCrQFqKRX9QvyYT0SexOtOepLsbsjUYjB+EIhBwREeiHO4EDKjqO/BnHj+e12imTxwN+stQEo5nsIkIGSoaacMpJyHjwl2mlohAPKNbdEPGI8uSXRUYGDndH1ppJ9aveTYbjx82SdJucqIyeBOX4t1kWCJh7/dOz4RskAz2fqew49AErQdQZeP1F1EeXLUoPZgQTpnfzK88IrE3EuKfP2MC9ixnbRogs/EHP";
let lyric = fetch_spotify_lyric(token, client_token);
println!("{:?}", lyric);
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use log::info;
use ui::DesktopLyricApp;

mod config;
mod fetch;
mod font;
mod fuo;
mod lyric;
Expand Down
11 changes: 11 additions & 0 deletions src/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::path::PathBuf;
use std::sync::mpsc::Receiver;
use std::{sync::Arc, thread};

use crate::fetch::fetch_spotify_lyric;
use crate::fuo::FuoClient;
use crate::lyric::Lyric;
use crate::Config;
Expand Down Expand Up @@ -81,12 +82,22 @@ pub fn serve(
"Playing song: {}",
unwarp_or_continue!(metadata.title().ok_or("Song doesn't have a title"), 'player)
);
error!("{}", config.player_name);
let lrc = if config.player_name == "feeluown" {
if let Some(content) = FuoClient.lyric() {
Lyric::from_str(&content)
} else {
Lyric::from_str("")
}
} else if config.player_name == "spotify"
&& config.spotify_access_token.is_some()
&& config.spotify_client_token.is_some()
{
fetch_spotify_lyric(
config.spotify_access_token.as_ref().unwrap(),
config.spotify_client_token.as_ref().unwrap(),
)
.unwrap_or(Lyric::from_str(""))
} else {
find_lyric(&metadata, &config.lyric_dir, config.fuzzy)
};
Expand Down
20 changes: 20 additions & 0 deletions src/ui/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ impl DesktopLyricApp {
ui.label("Auto resize");
ui.checkbox(&mut self.config.auto_resize, "")
});
ui.horizontal(|ui| {
ui.label("Spotify access token");
let mut buf = self
.config
.spotify_access_token
.clone()
.unwrap_or("".to_string());
ui.text_edit_singleline(&mut buf);
self.config.spotify_access_token = Some(buf);
});
ui.horizontal(|ui| {
ui.label("Spotify client token");
let mut buf = self
.config
.spotify_client_token
.clone()
.unwrap_or("".to_string());
ui.text_edit_singleline(&mut buf);
self.config.spotify_client_token = Some(buf);
});
if ui.button("Save").clicked() {
if let Ok(data) = serde_yaml::to_string(&self.config) {
write(&self.config_path, data.as_bytes()).ok();
Expand Down

0 comments on commit 91d5345

Please sign in to comment.