mirror of
https://github.com/Dangoware/dmp-core.git
synced 2025-04-19 09:42:56 -05:00
added m3u8 to playlist function and fixed playlist to m3u8 function
This commit is contained in:
parent
7da0b1a1db
commit
a75081d4fc
3 changed files with 142 additions and 74 deletions
|
@ -69,10 +69,10 @@ impl ConfigLibraries {
|
|||
}
|
||||
|
||||
pub fn get_library(&self, uuid: &Uuid) -> Result<ConfigLibrary, ConfigError> {
|
||||
dbg!(&uuid);
|
||||
|
||||
for library in &self.libraries {
|
||||
// dbg!(&library.uuid, &uuid);
|
||||
if &library.uuid == uuid {
|
||||
dbg!(&library.uuid);
|
||||
return Ok(library.to_owned())
|
||||
}
|
||||
}
|
||||
|
@ -148,6 +148,13 @@ impl Config {
|
|||
let config: Config = serde_json::from_str::<Config>(&bun)?;
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub fn push_library(&mut self, lib: ConfigLibrary) {
|
||||
if self.libraries.libraries.is_empty() {
|
||||
self.libraries.default_library = lib.uuid;
|
||||
}
|
||||
self.libraries.libraries.push(lib);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
@ -165,45 +172,42 @@ pub enum ConfigError {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
pub mod tests {
|
||||
use std::{path::PathBuf, sync::{Arc, RwLock}};
|
||||
use crate::music_storage::library::MusicLibrary;
|
||||
use super::{Config, ConfigLibraries, ConfigLibrary};
|
||||
|
||||
#[test]
|
||||
fn config_test() {
|
||||
let lib_a = ConfigLibrary::new(PathBuf::from("test-config/library1"), String::from("library1"), None);
|
||||
let lib_b = ConfigLibrary::new(PathBuf::from("test-config/library2"), String::from("library2"), None);
|
||||
let lib_c = ConfigLibrary::new(PathBuf::from("test-config/library3"), String::from("library3"), None);
|
||||
let config = Config {
|
||||
pub fn new_config_lib() -> (Config, MusicLibrary) {
|
||||
let lib = ConfigLibrary::new(PathBuf::from("test-config/library"), String::from("library"), None);
|
||||
let mut config = Config {
|
||||
path: PathBuf::from("test-config/config_test.json"),
|
||||
libraries: ConfigLibraries {
|
||||
libraries: vec![
|
||||
lib_a.clone(),
|
||||
lib_b.clone(),
|
||||
lib_c.clone(),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
config.write_file();
|
||||
let arc = Arc::new(RwLock::from(config));
|
||||
MusicLibrary::init(arc.clone(), lib_a.uuid).unwrap();
|
||||
MusicLibrary::init(arc.clone(), lib_b.uuid).unwrap();
|
||||
MusicLibrary::init(arc.clone(), lib_c.uuid).unwrap();
|
||||
|
||||
}
|
||||
config.push_library(lib);
|
||||
config.write_file().unwrap();
|
||||
|
||||
#[test]
|
||||
fn test2() {
|
||||
let config = Config::read_file(PathBuf::from("test-config/config_test.json")).unwrap();
|
||||
let uuid = config.libraries.get_default().unwrap().uuid;
|
||||
let mut lib = MusicLibrary::init(Arc::new(RwLock::from(config.clone())), uuid).unwrap();
|
||||
let mut lib = MusicLibrary::init(Arc::new(RwLock::from(config.clone())), dbg!(config.libraries.default_library)).unwrap();
|
||||
lib.scan_folder("test-config/music/").unwrap();
|
||||
lib.save(config.clone()).unwrap();
|
||||
dbg!(&lib);
|
||||
dbg!(&config);
|
||||
|
||||
(config, lib)
|
||||
}
|
||||
|
||||
pub fn read_config_lib() -> (Config, MusicLibrary) {
|
||||
let config = Config::read_file(PathBuf::from("test-config/config_test.json")).unwrap();
|
||||
|
||||
// dbg!(&config);
|
||||
|
||||
let mut lib = MusicLibrary::init(Arc::new(RwLock::from(config.clone())), config.libraries.get_default().unwrap().uuid).unwrap();
|
||||
|
||||
|
||||
lib.scan_folder("test-config/music/").unwrap();
|
||||
|
||||
lib.save(config.clone()).unwrap();
|
||||
|
||||
|
||||
(config, lib)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -686,6 +686,7 @@ impl MusicLibrary {
|
|||
false => {
|
||||
// If the library does not exist, re-create it
|
||||
let lib = MusicLibrary::new(String::new(), uuid);
|
||||
|
||||
write_file(&lib, path)?;
|
||||
lib
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use std::{fs::File, io::{Read, Error}};
|
||||
use std::{fs::File, io::Read, path:: PathBuf, sync::{Arc, RwLock}};
|
||||
use std::error::Error;
|
||||
|
||||
use chrono::Duration;
|
||||
use uuid::Uuid;
|
||||
use super::library::{AlbumArt, Song, Tag};
|
||||
use super::library::{AlbumArt, MusicLibrary, Song, Tag, URI};
|
||||
|
||||
use m3u8_rs::{MediaPlaylist, MediaPlaylistType, MediaSegment, Playlist as List2};
|
||||
|
||||
|
@ -34,16 +35,14 @@ impl Playlist {
|
|||
pub fn set_tracks(&mut self, tracks: Vec<Uuid>) {
|
||||
self.tracks = tracks;
|
||||
}
|
||||
pub fn add_track(&mut self, track: Uuid) -> Result<(), Error> {
|
||||
pub fn add_track(&mut self, track: Uuid) {
|
||||
self.tracks.push(track);
|
||||
Ok(())
|
||||
}
|
||||
pub fn remove_track(&mut self, index: i32) -> Result<(), Error> {
|
||||
pub fn remove_track(&mut self, index: i32) {
|
||||
let index = index as usize;
|
||||
if (self.tracks.len() - 1) >= index {
|
||||
self.tracks.remove(index);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
// pub fn get_index(&self, song_name: &str) -> Option<usize> {
|
||||
// let mut index = 0;
|
||||
|
@ -58,26 +57,41 @@ impl Playlist {
|
|||
// }
|
||||
// None
|
||||
// }
|
||||
pub fn contains_value(&self, tag: &Tag, value: &str) -> bool {
|
||||
&self.tracks.iter().for_each(|track| {
|
||||
pub fn contains_value(&self, tag: &Tag, value: &String, lib: Arc<RwLock<MusicLibrary>>) -> bool {
|
||||
let lib = lib.read().unwrap();
|
||||
let items = match lib.query_tracks(value, &vec![tag.to_owned()], &vec![tag.to_owned()]) {
|
||||
Some(e) => e,
|
||||
None => return false
|
||||
};
|
||||
|
||||
for item in items {
|
||||
for uuid in &self.tracks {
|
||||
if uuid == &item.uuid {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
false
|
||||
}
|
||||
pub fn to_m3u8(&mut self, tracks: Vec<Song>) {
|
||||
let seg = tracks
|
||||
.iter()
|
||||
.map({
|
||||
|track| {
|
||||
|
||||
MediaSegment {
|
||||
uri: track.location.to_string().into(),
|
||||
duration: track.duration.as_millis() as f32,
|
||||
title: Some(track.tags.get_key_value(&Tag::Title).unwrap().1.into()),
|
||||
..Default::default()
|
||||
}
|
||||
pub fn to_m3u8(&mut self, lib: Arc<RwLock<MusicLibrary>>, location: &str) -> Result<(), Box<dyn Error>> {
|
||||
let lib = lib.read().unwrap();
|
||||
let seg = self.tracks
|
||||
.iter()
|
||||
.filter_map( |uuid| {
|
||||
if let Some((track, _)) = lib.query_uuid(uuid) {
|
||||
if let URI::Local(_) = track.location {
|
||||
Some(MediaSegment {
|
||||
uri: track.location.to_string(),
|
||||
duration: track.duration.as_millis() as f32,
|
||||
title: track.tags.get_key_value(&Tag::Title).map(|tag| tag.1.into()),
|
||||
..Default::default()
|
||||
})
|
||||
}else { None }
|
||||
}else { None }
|
||||
}
|
||||
})
|
||||
)
|
||||
.collect::<Vec<MediaSegment>>();
|
||||
|
||||
let m3u8 = MediaPlaylist {
|
||||
|
@ -90,19 +104,21 @@ impl Playlist {
|
|||
segments: seg.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
//TODO: change this to put in a real file path
|
||||
|
||||
let mut file = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.write(true)
|
||||
.open("F:\\Dango Music Player\\playlist.m3u8")
|
||||
.unwrap();
|
||||
m3u8.write_to(&mut file).unwrap();
|
||||
.open(location)?;
|
||||
m3u8.write_to(&mut file)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn from_m3u8(path: &str) -> Result<Playlist, Error> {
|
||||
|
||||
pub fn from_m3u8(path: &str, lib: Arc<RwLock<MusicLibrary>>) -> Result<Playlist, Box<dyn Error>> {
|
||||
let mut file = match File::open(path) {
|
||||
Ok(file) => file,
|
||||
Err(e) => return Err(e),
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
let mut bytes = Vec::new();
|
||||
file.read_to_end(&mut bytes).unwrap();
|
||||
|
@ -110,18 +126,53 @@ impl Playlist {
|
|||
let parsed = m3u8_rs::parse_playlist(&bytes);
|
||||
|
||||
let playlist = match parsed {
|
||||
Result::Ok((i, playlist)) => playlist,
|
||||
Result::Ok((_, playlist)) => playlist,
|
||||
Result::Err(e) => panic!("Parsing error: \n{}", e),
|
||||
};
|
||||
|
||||
match playlist {
|
||||
List2::MasterPlaylist(_) => panic!(),
|
||||
List2::MediaPlaylist(pl) => {
|
||||
let values = pl.segments.iter().map(|seg| seg.uri.to_owned() ).collect::<Vec<String>>();
|
||||
List2::MasterPlaylist(_) => Err("This is a Master Playlist!\nPlase input a Media Playlist".into()),
|
||||
List2::MediaPlaylist(playlist_) => {
|
||||
let mut uuids = Vec::new();
|
||||
for seg in playlist_.segments {
|
||||
let path_ = PathBuf::from(seg.uri.to_owned());
|
||||
let mut lib = lib.write().unwrap();
|
||||
|
||||
let uuid = if let Some((song, _)) = lib.query_uri(&URI::Local(path_.clone())) {
|
||||
song.uuid
|
||||
}else {
|
||||
let song_ = Song::from_file(&path_)?;
|
||||
let uuid = song_.uuid.to_owned();
|
||||
lib.add_song(song_)?;
|
||||
uuid
|
||||
};
|
||||
uuids.push(uuid);
|
||||
}
|
||||
let mut playlist = Playlist::new();
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
{
|
||||
playlist.title = path.split("\\")
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
.strip_suffix(".m3u8")
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
}
|
||||
#[cfg(target_family = "unix")]
|
||||
{
|
||||
playlist.title = path.split("/")
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
.strip_suffix(".m3u8")
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
}
|
||||
|
||||
playlist.set_tracks(uuids);
|
||||
Ok(playlist)
|
||||
}
|
||||
}
|
||||
|
||||
todo!()
|
||||
}
|
||||
fn title(&self) -> &String {
|
||||
&self.title
|
||||
|
@ -153,14 +204,26 @@ impl Default for Playlist {
|
|||
}
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn list_to_m3u8() {
|
||||
// let lib = ITunesLibrary::from_file(Path::new(
|
||||
// "F:\\Music\\Mp3\\Music Main\\iTunes Music Library.xml",
|
||||
// ));
|
||||
// let mut a = Playlist::new();
|
||||
// let c = lib.to_songs();
|
||||
// let mut b = c.iter().map(|song| song.to_owned()).collect::<Vec<Song>>();
|
||||
// a.tracks.append(&mut b);
|
||||
// a.to_m3u8()
|
||||
// }
|
||||
#[cfg(test)]
|
||||
mod test_super {
|
||||
use super::*;
|
||||
use crate::config::config::tests::read_config_lib;
|
||||
|
||||
#[test]
|
||||
fn list_to_m3u8() {
|
||||
let (_, lib) = read_config_lib();
|
||||
let mut playlist = Playlist::new();
|
||||
let tracks = lib.library.iter().map(|track| track.uuid ).collect();
|
||||
playlist.set_tracks(tracks);
|
||||
|
||||
_ = playlist.to_m3u8(Arc::new(RwLock::from(lib)), ".\\test-config\\playlists\\playlist.m3u8");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn m3u8_to_list() {
|
||||
let (_, lib) = read_config_lib();
|
||||
let arc = Arc::new(RwLock::from(lib));
|
||||
let playlist = Playlist::from_m3u8(".\\test-config\\playlists\\playlist.m3u8", arc).unwrap();
|
||||
dbg!(playlist);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue