mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-04-19 10:02:53 -05:00
Optimised the album art display
This commit is contained in:
parent
280a17788b
commit
e1a0ffbd05
5 changed files with 949 additions and 1015 deletions
|
@ -9,7 +9,6 @@ pub mod music_storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod music_controller {
|
pub mod music_controller {
|
||||||
pub mod connections;
|
|
||||||
pub mod controller;
|
pub mod controller;
|
||||||
pub mod controller_handle;
|
pub mod controller_handle;
|
||||||
pub mod queue;
|
pub mod queue;
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
// use std::{
|
|
||||||
// sync::{Arc, RwLock},
|
|
||||||
// error::Error,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// use discord_rpc_client::Client;
|
|
||||||
// use listenbrainz::ListenBrainz;
|
|
||||||
// use uuid::Uuid;
|
|
||||||
|
|
||||||
// use crate::{
|
|
||||||
// config::config::Config, music_controller::controller::{Controller, QueueCmd, QueueResponse}, music_storage::library::{MusicLibrary, Song, Tag}
|
|
||||||
// };
|
|
||||||
|
|
||||||
// use super::controller::DatabaseResponse;
|
|
||||||
|
|
||||||
// impl Controller {
|
|
||||||
// pub fn listenbrainz_authenticate(&mut self) -> Result<ListenBrainz, Box<dyn Error>> {
|
|
||||||
// let config = &self.config.read().unwrap();
|
|
||||||
// let mut client = ListenBrainz::new();
|
|
||||||
|
|
||||||
// let lbz_token = match &config.connections.listenbrainz_token {
|
|
||||||
// Some(token) => token,
|
|
||||||
// None => todo!("No ListenBrainz token in config")
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if !client.is_authenticated() {
|
|
||||||
// client.authenticate(lbz_token)?;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Ok(client)
|
|
||||||
// }
|
|
||||||
// pub fn lbz_scrobble(&self, client: ListenBrainz, uuid: Uuid) -> Result<(), Box<dyn Error>> {
|
|
||||||
// let config = &self.config.read().unwrap();
|
|
||||||
|
|
||||||
// &self.db_mail.send(super::controller::DatabaseCmd::QueryUuid(uuid));
|
|
||||||
// let res = &self.db_mail.recv()?;
|
|
||||||
// let song = match res {
|
|
||||||
// DatabaseResponse::Song(song) => song,
|
|
||||||
// _ => todo!()
|
|
||||||
// };
|
|
||||||
// let unknown = &"unknown".to_string();
|
|
||||||
// let artist = song.get_tag(&Tag::Artist).unwrap_or(unknown);
|
|
||||||
// let track = song.get_tag(&Tag::Title).unwrap_or(unknown);
|
|
||||||
// let release = song.get_tag(&Tag::Album).map(|rel| rel.as_str());
|
|
||||||
|
|
||||||
// client.listen(artist, track, release)?;
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn lbz_now_playing(&self, client: ListenBrainz, uuid: Uuid) -> Result<(), Box<dyn Error>> {
|
|
||||||
// let config = &self.config.read().unwrap();
|
|
||||||
|
|
||||||
// &self.db_mail.send(super::controller::DatabaseCmd::QueryUuid(uuid));
|
|
||||||
// let res = &self.db_mail.recv()?;
|
|
||||||
// let song = match res {
|
|
||||||
// DatabaseResponse::Song(song) => song,
|
|
||||||
// _ => todo!()
|
|
||||||
// };
|
|
||||||
// let unknown = &"unknown".to_string();
|
|
||||||
// let artist = song.get_tag(&Tag::Artist).unwrap_or(unknown);
|
|
||||||
// let track = song.get_tag(&Tag::Title).unwrap_or(unknown);
|
|
||||||
// let release = song.get_tag(&Tag::Album).map(|rel| rel.as_str());
|
|
||||||
|
|
||||||
// client.listen(artist, track, release)?;
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn discord_song_change(client: &mut Client,song: Song) {
|
|
||||||
// client.set_activity(|a| {
|
|
||||||
// a.state(format!("Listening to {}", song.get_tag(&Tag::Title).unwrap()))
|
|
||||||
// .into()
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[cfg(test)]
|
|
||||||
// mod test_super {
|
|
||||||
// use std::{thread::sleep, time::Duration};
|
|
||||||
|
|
||||||
// use super::*;
|
|
||||||
// use crate::config::config::tests::read_config_lib;
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn listenbrainz() {
|
|
||||||
// let mut c = Controller::start(".\\test-config\\config_test.json").unwrap();
|
|
||||||
|
|
||||||
// let client = c.listenbrainz_authenticate().unwrap();
|
|
||||||
|
|
||||||
// c.q_new().unwrap();
|
|
||||||
// c.queue_mail[0].send(QueueCmd::SetVolume(0.04)).unwrap();
|
|
||||||
|
|
||||||
// let songs = c.lib_get_songs();
|
|
||||||
|
|
||||||
// c.q_enqueue(0, songs[1].location.to_owned()).unwrap();
|
|
||||||
// c.q_play(0).unwrap();
|
|
||||||
|
|
||||||
// sleep(Duration::from_secs(100));
|
|
||||||
// c.lbz_scrobble(client, songs[1].uuid).unwrap();
|
|
||||||
// }
|
|
||||||
// }
|
|
|
@ -3,6 +3,7 @@
|
||||||
//! other functions
|
//! other functions
|
||||||
#![allow(while_true)]
|
#![allow(while_true)]
|
||||||
|
|
||||||
|
use chrono::TimeDelta;
|
||||||
use kushi::{Queue, QueueItemType};
|
use kushi::{Queue, QueueItemType};
|
||||||
use kushi::{QueueError, QueueItem};
|
use kushi::{QueueError, QueueItem};
|
||||||
use prismriver::{Prismriver, Volume, Error as PrismError};
|
use prismriver::{Prismriver, Volume, Error as PrismError};
|
||||||
|
@ -14,6 +15,7 @@ use std::fs::OpenOptions;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
use std::time::Duration;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -156,6 +158,7 @@ pub struct ControllerInput {
|
||||||
),
|
),
|
||||||
library: MusicLibrary,
|
library: MusicLibrary,
|
||||||
config: Arc<RwLock<Config>>,
|
config: Arc<RwLock<Config>>,
|
||||||
|
playback_info: crossbeam::channel::Sender<PlaybackInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ControllerHandle {
|
pub struct ControllerHandle {
|
||||||
|
@ -165,11 +168,11 @@ pub struct ControllerHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControllerHandle {
|
impl ControllerHandle {
|
||||||
pub fn new(library: MusicLibrary, config: Arc<RwLock<Config>>) -> (Self, ControllerInput) {
|
pub fn new(library: MusicLibrary, config: Arc<RwLock<Config>>) -> (Self, ControllerInput, crossbeam::channel::Receiver<PlaybackInfo>) {
|
||||||
let lib_mail = MailMan::double();
|
let lib_mail = MailMan::double();
|
||||||
let player_mail = MailMan::double();
|
let player_mail = MailMan::double();
|
||||||
let queue_mail = MailMan::double();
|
let queue_mail = MailMan::double();
|
||||||
|
let (playback_info_rx, playback_info_tx) = crossbeam::channel::bounded(1);
|
||||||
(
|
(
|
||||||
ControllerHandle {
|
ControllerHandle {
|
||||||
lib_mail: lib_mail.0.clone(),
|
lib_mail: lib_mail.0.clone(),
|
||||||
|
@ -181,8 +184,10 @@ impl ControllerHandle {
|
||||||
lib_mail,
|
lib_mail,
|
||||||
queue_mail,
|
queue_mail,
|
||||||
library,
|
library,
|
||||||
config
|
config,
|
||||||
}
|
playback_info: playback_info_rx,
|
||||||
|
},
|
||||||
|
playback_info_tx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +233,8 @@ impl Controller {
|
||||||
lib_mail,
|
lib_mail,
|
||||||
queue_mail,
|
queue_mail,
|
||||||
mut library,
|
mut library,
|
||||||
config
|
config,
|
||||||
|
playback_info,
|
||||||
}: ControllerInput
|
}: ControllerInput
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let queue: Queue<QueueSong, QueueAlbum> = Queue {
|
let queue: Queue<QueueSong, QueueAlbum> = Queue {
|
||||||
|
@ -257,12 +263,13 @@ impl Controller {
|
||||||
|
|
||||||
let _player = player.clone();
|
let _player = player.clone();
|
||||||
let _lib_mail = lib_mail.0.clone();
|
let _lib_mail = lib_mail.0.clone();
|
||||||
|
let _queue_mail = queue_mail.0.clone();
|
||||||
scope
|
scope
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
Controller::player_command_loop(
|
Controller::player_command_loop(
|
||||||
_player,
|
_player,
|
||||||
player_mail.1,
|
player_mail.1,
|
||||||
queue_mail.0,
|
_queue_mail,
|
||||||
_lib_mail,
|
_lib_mail,
|
||||||
state,
|
state,
|
||||||
)
|
)
|
||||||
|
@ -271,9 +278,11 @@ impl Controller {
|
||||||
});
|
});
|
||||||
scope
|
scope
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
Controller::player_event_loop(
|
Controller::player_monitor_loop(
|
||||||
player,
|
player,
|
||||||
player_mail.0
|
player_mail.0,
|
||||||
|
queue_mail.0,
|
||||||
|
playback_info,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -523,6 +532,23 @@ impl Controller {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn player_monitor_loop(
|
||||||
|
player: Arc<RwLock<Prismriver>>,
|
||||||
|
player_mail: MailMan<PlayerCommand, PlayerResponse>,
|
||||||
|
queue_mail: MailMan<QueueCommand, QueueResponse>,
|
||||||
|
player_info: crossbeam_channel::Sender<PlaybackInfo>
|
||||||
|
) -> Result<(), ()> {
|
||||||
|
Ok(())
|
||||||
|
// std::thread::scope(|s| {
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Check for duration and spit it out
|
||||||
|
// // Check for end of song to get the next
|
||||||
|
|
||||||
|
// Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn library_loop(
|
async fn library_loop(
|
||||||
lib_mail: MailMan<LibraryResponse, LibraryCommand>,
|
lib_mail: MailMan<LibraryResponse, LibraryCommand>,
|
||||||
library: &mut MusicLibrary,
|
library: &mut MusicLibrary,
|
||||||
|
@ -564,15 +590,6 @@ impl Controller {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn player_event_loop(
|
|
||||||
player: Arc<RwLock<Prismriver>>,
|
|
||||||
player_mail: MailMan<PlayerCommand, PlayerResponse>,
|
|
||||||
) -> Result<(), ()> {
|
|
||||||
// just pretend this does something
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn queue_loop(
|
async fn queue_loop(
|
||||||
mut queue: Queue<QueueSong, QueueAlbum>,
|
mut queue: Queue<QueueSong, QueueAlbum>,
|
||||||
queue_mail: MailMan<QueueResponse, QueueCommand>,
|
queue_mail: MailMan<QueueResponse, QueueCommand>,
|
||||||
|
@ -628,3 +645,9 @@ impl Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PlaybackInfo {
|
||||||
|
pub duration: TimeDelta,
|
||||||
|
pub position: TimeDelta
|
||||||
|
}
|
|
@ -40,15 +40,17 @@ pub async fn display_album_art(ctrl_handle: State<'_, ControllerHandle>, temp_di
|
||||||
Ok(art) => {
|
Ok(art) => {
|
||||||
let mut art = art.unwrap();
|
let mut art = art.unwrap();
|
||||||
let path = temp_dir.path().join(format!("CoverArt_{uuid}.{}", file_format::FileFormat::from_bytes(&art).extension()));
|
let path = temp_dir.path().join(format!("CoverArt_{uuid}.{}", file_format::FileFormat::from_bytes(&art).extension()));
|
||||||
// TODO: This can be optimised later
|
if !path.exists() {
|
||||||
let mut file = OpenOptions::new()
|
// TODO: This can be optimised later
|
||||||
.create(true)
|
let mut file = OpenOptions::new()
|
||||||
.truncate(true)
|
.create(true)
|
||||||
.write(true)
|
.truncate(true)
|
||||||
.read(true)
|
.write(true)
|
||||||
.open(path.clone())
|
.read(true)
|
||||||
.unwrap();
|
.open(path.clone())
|
||||||
file.write_all(&mut art).unwrap();
|
.unwrap();
|
||||||
|
file.write_all(&mut art).unwrap();
|
||||||
|
}
|
||||||
opener::open(path).unwrap();
|
opener::open(path).unwrap();
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e.to_string())
|
Err(e) => return Err(e.to_string())
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{fs, path::PathBuf, str::FromStr, thread::spawn};
|
use std::{fs, path::PathBuf, str::FromStr, thread::{scope, spawn}};
|
||||||
|
|
||||||
use crossbeam::channel::{unbounded, Receiver, Sender};
|
use crossbeam::channel::{unbounded, Receiver, Sender};
|
||||||
use dmp_core::{config::{Config, ConfigLibrary}, music_controller::controller::{Controller, ControllerHandle, LibraryResponse}, music_storage::library::MusicLibrary};
|
use dmp_core::{config::{Config, ConfigLibrary}, music_controller::controller::{Controller, ControllerHandle, LibraryResponse, PlaybackInfo}, music_storage::library::MusicLibrary};
|
||||||
use rfd::FileHandle;
|
use rfd::FileHandle;
|
||||||
use tauri::{http::Response, Emitter, Manager, State, WebviewWindowBuilder, Wry};
|
use tauri::{http::Response, Emitter, Manager, State, WebviewWindowBuilder, Wry};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -20,6 +20,7 @@ pub fn run() {
|
||||||
let (rx, tx) = unbounded::<Config>();
|
let (rx, tx) = unbounded::<Config>();
|
||||||
let (lib_rx, lib_tx) = unbounded::<Option<PathBuf>>();
|
let (lib_rx, lib_tx) = unbounded::<Option<PathBuf>>();
|
||||||
let (handle_rx, handle_tx) = unbounded::<ControllerHandle>();
|
let (handle_rx, handle_tx) = unbounded::<ControllerHandle>();
|
||||||
|
let (playback_handle_rx, playback_handle_tx) = unbounded::<crossbeam::channel::Receiver<PlaybackInfo>>();
|
||||||
|
|
||||||
let controller_thread = spawn(move || {
|
let controller_thread = spawn(move || {
|
||||||
let mut config = { tx.recv().unwrap() } ;
|
let mut config = { tx.recv().unwrap() } ;
|
||||||
|
@ -54,14 +55,23 @@ pub fn run() {
|
||||||
|
|
||||||
library.save(save_path).unwrap();
|
library.save(save_path).unwrap();
|
||||||
|
|
||||||
let (handle, input) = ControllerHandle::new(
|
let (handle, input, playback_tx) = ControllerHandle::new(
|
||||||
library,
|
library,
|
||||||
std::sync::Arc::new(std::sync::RwLock::new(config))
|
std::sync::Arc::new(std::sync::RwLock::new(config))
|
||||||
);
|
);
|
||||||
|
|
||||||
handle_rx.send(handle).unwrap();
|
handle_rx.send(handle).unwrap();
|
||||||
|
|
||||||
let _controller = futures::executor::block_on(Controller::start(input)).unwrap();
|
scope(|s| {
|
||||||
|
s.spawn(|| {
|
||||||
|
let _controller = futures::executor::block_on(Controller::start(input)).unwrap();
|
||||||
|
});
|
||||||
|
s.spawn(|| {
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
let app = tauri::Builder::default()
|
let app = tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
|
|
Loading…
Reference in a new issue