mirror of
https://github.com/Dangoware/dmp-core.git
synced 2025-04-19 13:22:54 -05:00
Work in progress optimizations
This commit is contained in:
parent
2e0ce48506
commit
f00df67844
2 changed files with 110 additions and 103 deletions
10
Cargo.toml
10
Cargo.toml
|
@ -12,12 +12,12 @@ keywords = ["audio", "music"]
|
||||||
categories = ["multimedia::audio"]
|
categories = ["multimedia::audio"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
file-format = { version = "0.17.3", features = ["reader", "serde"] }
|
file-format = { version = "0.22.0", features = ["reader-asf", "reader-ebml", "reader-mp4", "reader-rm", "reader-txt", "reader-xml", "serde"] }
|
||||||
lofty = "0.16.1"
|
lofty = "0.16.1"
|
||||||
serde = { version = "1.0.164", features = ["derive"] }
|
serde = { version = "1.0.191", features = ["derive"] }
|
||||||
time = "0.3.22"
|
time = "0.3.22"
|
||||||
toml = "0.7.5"
|
toml = "0.7.5"
|
||||||
walkdir = "2.3.3"
|
walkdir = "2.4.0"
|
||||||
cpal = "0.15.2"
|
cpal = "0.15.2"
|
||||||
heapless = "0.7.16"
|
heapless = "0.7.16"
|
||||||
rb = "0.4.1"
|
rb = "0.4.1"
|
||||||
|
@ -37,8 +37,6 @@ unidecode = "0.3.0"
|
||||||
rayon = "1.8.0"
|
rayon = "1.8.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.4"
|
||||||
cue = "2.0.0"
|
|
||||||
base64 = "0.21.5"
|
base64 = "0.21.5"
|
||||||
zip = "0.6.6"
|
|
||||||
flate2 = "1.0.28"
|
|
||||||
snap = "1.1.0"
|
snap = "1.1.0"
|
||||||
|
rcue = "0.1.3"
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::error::Error;
|
||||||
use std::ops::ControlFlow::{Break, Continue};
|
use std::ops::ControlFlow::{Break, Continue};
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
use cue::cd::CD;
|
use rcue::parser::parse_from_file;
|
||||||
use file_format::{FileFormat, Kind};
|
use file_format::{FileFormat, Kind};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
use lofty::{AudioFile, ItemKey, ItemValue, Probe, TagType, TaggedFileExt};
|
use lofty::{AudioFile, ItemKey, ItemValue, Probe, TagType, TaggedFileExt};
|
||||||
|
@ -33,6 +33,15 @@ pub enum AlbumArt {
|
||||||
External(URI),
|
External(URI),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AlbumArt {
|
||||||
|
pub fn uri(&self) -> Option<&URI> {
|
||||||
|
match self {
|
||||||
|
Self::Embedded(_) => None,
|
||||||
|
Self::External(uri) => Some(uri),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum Tag {
|
pub enum Tag {
|
||||||
Title,
|
Title,
|
||||||
|
@ -490,21 +499,15 @@ impl MusicLibrary {
|
||||||
pub fn add_cuesheet(&mut self, cuesheet: &PathBuf) -> Result<usize, Box<dyn Error>> {
|
pub fn add_cuesheet(&mut self, cuesheet: &PathBuf) -> Result<usize, Box<dyn Error>> {
|
||||||
let mut tracks_added = 0;
|
let mut tracks_added = 0;
|
||||||
|
|
||||||
let cue_data = CD::parse_file(cuesheet.to_owned()).unwrap();
|
let cue_data = parse_from_file(&cuesheet.as_path().to_string_lossy(), false).unwrap();
|
||||||
|
|
||||||
// Get album level information
|
// Get album level information
|
||||||
let album_title = &cue_data
|
let album_title = &cue_data.title;
|
||||||
.get_cdtext()
|
let album_artist = &cue_data.performer;
|
||||||
.read(cue::cd_text::PTI::Title)
|
|
||||||
.unwrap_or(String::new());
|
|
||||||
let album_artist = &cue_data
|
|
||||||
.get_cdtext()
|
|
||||||
.read(cue::cd_text::PTI::Performer)
|
|
||||||
.unwrap_or(String::new());
|
|
||||||
|
|
||||||
let parent_dir = cuesheet.parent().expect("The file has no parent path??");
|
let parent_dir = cuesheet.parent().expect("The file has no parent path??");
|
||||||
for (i, track) in cue_data.tracks().iter().enumerate() {
|
for file in cue_data.files.iter() {
|
||||||
let audio_location = parent_dir.join(track.get_filename());
|
let audio_location = &parent_dir.join(file.file.clone());
|
||||||
|
|
||||||
if !audio_location.exists() {
|
if !audio_location.exists() {
|
||||||
continue;
|
continue;
|
||||||
|
@ -516,100 +519,106 @@ impl MusicLibrary {
|
||||||
Err(_) => ()
|
Err(_) => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the track timing information
|
let next_track = file.tracks.clone();
|
||||||
let pregap = match track.get_zero_pre() {
|
let mut next_track = next_track.iter().skip(1);
|
||||||
Some(pregap) => Duration::from_micros((pregap as f32 * 13333.333333) as u64),
|
for (i, track) in file.tracks.iter().enumerate() {
|
||||||
None => Duration::from_secs(0),
|
// Get the track timing information
|
||||||
};
|
let pregap = match track.pregap {
|
||||||
let postgap = match track.get_zero_post() {
|
Some(pregap) => pregap,
|
||||||
Some(postgap) => Duration::from_micros((postgap as f32 * 13333.333333) as u64),
|
None => Duration::from_secs(0),
|
||||||
None => Duration::from_secs(0),
|
};
|
||||||
};
|
let postgap = match track.postgap {
|
||||||
let mut start = Duration::from_micros((track.get_start() as f32 * 13333.333333) as u64);
|
Some(postgap) => postgap,
|
||||||
start -= pregap;
|
None => Duration::from_secs(0),
|
||||||
|
};
|
||||||
|
let mut start = track.indices[0].1;
|
||||||
|
start -= pregap;
|
||||||
|
|
||||||
let duration = match track.get_length() {
|
let duration = match next_track.next() {
|
||||||
Some(len) => Duration::from_micros((len as f32 * 13333.333333) as u64),
|
Some(future) => match future.indices.get(0) {
|
||||||
None => {
|
Some(val) => val.1 - start,
|
||||||
let tagged_file = match lofty::read_from_path(&audio_location) {
|
None => Duration::from_secs(0)
|
||||||
Ok(tagged_file) => tagged_file,
|
}
|
||||||
|
None => {
|
||||||
Err(_) => match Probe::open(&audio_location)?.read() {
|
let tagged_file = match lofty::read_from_path(&audio_location) {
|
||||||
Ok(tagged_file) => tagged_file,
|
Ok(tagged_file) => tagged_file,
|
||||||
|
|
||||||
Err(error) => return Err(error.into()),
|
Err(_) => match Probe::open(&audio_location)?.read() {
|
||||||
},
|
Ok(tagged_file) => tagged_file,
|
||||||
};
|
|
||||||
|
|
||||||
tagged_file.properties().duration() - start
|
Err(error) => return Err(error.into()),
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
let end = start + duration + postgap;
|
|
||||||
|
|
||||||
// Get the format as a string
|
tagged_file.properties().duration() - start
|
||||||
let format: Option<FileFormat> = match FileFormat::from_file(&audio_location) {
|
|
||||||
Ok(fmt) => Some(fmt),
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get some useful tags
|
|
||||||
let mut tags: BTreeMap<Tag, String> = BTreeMap::new();
|
|
||||||
tags.insert(Tag::Album, album_title.clone());
|
|
||||||
tags.insert(Tag::Key("AlbumArtist".to_string()), album_artist.clone());
|
|
||||||
tags.insert(Tag::Track, (i + 1).to_string());
|
|
||||||
match track.get_cdtext().read(cue::cd_text::PTI::Title) {
|
|
||||||
Some(title) => tags.insert(Tag::Title, title),
|
|
||||||
None => match track.get_cdtext().read(cue::cd_text::PTI::UPC_ISRC) {
|
|
||||||
Some(title) => tags.insert(Tag::Title, title),
|
|
||||||
None => {
|
|
||||||
let namestr = format!("{} - {}", i, track.get_filename());
|
|
||||||
tags.insert(Tag::Title, namestr)
|
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
};
|
let end = start + duration + postgap;
|
||||||
match track.get_cdtext().read(cue::cd_text::PTI::Performer) {
|
|
||||||
Some(artist) => tags.insert(Tag::Artist, artist),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
match track.get_cdtext().read(cue::cd_text::PTI::Genre) {
|
|
||||||
Some(genre) => tags.insert(Tag::Genre, genre),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
match track.get_cdtext().read(cue::cd_text::PTI::Message) {
|
|
||||||
Some(comment) => tags.insert(Tag::Comment, comment),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let album_art = Vec::new();
|
// Get the format as a string
|
||||||
|
let format: Option<FileFormat> = match FileFormat::from_file(&audio_location) {
|
||||||
|
Ok(fmt) => Some(fmt),
|
||||||
|
Err(_) => None,
|
||||||
|
};
|
||||||
|
|
||||||
let new_song = Song {
|
// Get some useful tags
|
||||||
location: URI::Cue {
|
let mut tags: BTreeMap<Tag, String> = BTreeMap::new();
|
||||||
location: audio_location,
|
match album_title {
|
||||||
index: i,
|
Some(title) => {tags.insert(Tag::Album, title.clone());},
|
||||||
start,
|
None => (),
|
||||||
end,
|
|
||||||
},
|
|
||||||
plays: 0,
|
|
||||||
skips: 0,
|
|
||||||
favorited: false,
|
|
||||||
rating: None,
|
|
||||||
format,
|
|
||||||
duration,
|
|
||||||
play_time: Duration::from_secs(0),
|
|
||||||
last_played: None,
|
|
||||||
date_added: Some(chrono::offset::Utc::now()),
|
|
||||||
date_modified: Some(chrono::offset::Utc::now()),
|
|
||||||
tags,
|
|
||||||
album_art,
|
|
||||||
};
|
|
||||||
|
|
||||||
match self.add_song(new_song) {
|
|
||||||
Ok(_) => tracks_added += 1,
|
|
||||||
Err(_error) => {
|
|
||||||
//println!("{}", _error);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
};
|
match album_artist {
|
||||||
|
Some(artist) => {tags.insert(Tag::Album, artist.clone());},
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
tags.insert(Tag::Track, track.no.parse().unwrap_or((i + 1).to_string()));
|
||||||
|
match track.title.clone() {
|
||||||
|
Some(title) => tags.insert(Tag::Title, title),
|
||||||
|
None => match track.isrc.clone() {
|
||||||
|
Some(title) => tags.insert(Tag::Title, title),
|
||||||
|
None => {
|
||||||
|
let namestr = format!("{} - {}", i, file.file.clone());
|
||||||
|
tags.insert(Tag::Title, namestr)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
match track.performer.clone() {
|
||||||
|
Some(artist) => tags.insert(Tag::Artist, artist),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find images around the music file that can be used
|
||||||
|
let album_art = find_images(&audio_location.to_path_buf()).unwrap();
|
||||||
|
|
||||||
|
let new_song = Song {
|
||||||
|
location: URI::Cue {
|
||||||
|
location: audio_location.clone(),
|
||||||
|
index: i,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
plays: 0,
|
||||||
|
skips: 0,
|
||||||
|
favorited: false,
|
||||||
|
rating: None,
|
||||||
|
format,
|
||||||
|
duration,
|
||||||
|
play_time: Duration::from_secs(0),
|
||||||
|
last_played: None,
|
||||||
|
date_added: Some(chrono::offset::Utc::now()),
|
||||||
|
date_modified: Some(chrono::offset::Utc::now()),
|
||||||
|
tags,
|
||||||
|
album_art,
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.add_song(new_song) {
|
||||||
|
Ok(_) => tracks_added += 1,
|
||||||
|
Err(_error) => {
|
||||||
|
//println!("{}", _error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tracks_added)
|
Ok(tracks_added)
|
||||||
|
|
Loading…
Reference in a new issue