Fini le proto du player + fix la validation d'index dans la playlist

This commit is contained in:
Justine 2024-08-11 18:38:48 +02:00
parent 1477471196
commit 283d0b2065
3 changed files with 106 additions and 27 deletions

View File

@ -5,14 +5,19 @@ pub mod playlist;
use crate::playlist::playlist::*; use crate::playlist::playlist::*;
fn main() { fn main() {
let mysong = SongMeta::frompath(&String::from("/home/justine/NAS/Musique/A_classer/Bleach/12 Big Cheese.mp3")); let mysong = SongMeta::frompath(&String::from("/home/justine/NAS/Musique/A_classer/Bleach/12 Big Cheese.mp3")).unwrap();
let mysong2 = SongMeta::frompath(&String::from("/home/justine/NAS/Musique/Folk/Galaverna - Dodsdans/Galaverna - Dodsdans - 01 Dods....flac")); let mysong2 = SongMeta::frompath(&String::from("/home/justine/NAS/Musique/Folk/Galaverna - Dodsdans/Galaverna - Dodsdans - 01 Dods....flac")).unwrap();
//let playlist = Playlist::from_file(&String::from("./cool.yml"));
//playlist.remove(0).unwrap(); let playlist = Playlist {
let playlist = Playlist::from_file(&String::from("./cool.yml")); songs: vec![mysong, mysong2],
};
dbg!(playlist); assert_eq!(false, playlist.check_index(2));
let playlist = Playlist::new();
assert_eq!(false, playlist.check_index(0));
assert_eq!(false, playlist.check_index(10));
} }

View File

@ -99,7 +99,10 @@ pub mod playlist {
///Checks if a number is a valid index in this playlist. ///Checks if a number is a valid index in this playlist.
pub fn check_index(&self, index: usize) -> bool { pub fn check_index(&self, index: usize) -> bool {
if index > self.songs.len() { if self.songs.len() == 0 {
return false;
}
if index > (self.songs.len() - 1) {
return false; return false;
} }
return true; return true;

View File

@ -7,12 +7,37 @@ use rodio::{Decoder, OutputStream, Sink, Source};
//-----------------------------------------Structs //-----------------------------------------Structs
//Gère tout ce qui est lecture. C'est le lui le "lecteur cd" dans l'histoire.
//Features : play / pause / précédent / suivant / shuffle on/off / mode repeat
//Vidage playlist sans interruption de la chanson en cours
//Poignée de lecture (seek)
//Le "lecteur cd" affiche : volume, poignée de lecture, metadonnées de la chanson, index de la chanson dans la playlist
// Il est entièrement détaché de l'interface et doit pouvoir exister en mode headless
// Ne pas mélanger les fonctionnalités entre les objets : la playlist doit pouvoir se shuffle, ce n'est pas le player qui le fait
// Ne pas oublier qu'on est pas obligé de faire des builder, je peux très bien créer un player en lui filant des valeurs
// Je n'ai pas besoin de faire une boucle dans une fonction de mon player puisque rodio lance un thread et que je garde le sink !
struct AudioPlayer { struct AudioPlayer {
sink: Sink, sink: Sink,
playlist: Vec<SongMeta>, playlist: Vec<SongMeta>,
//true si mode repeat
repeating: bool,
//false si mode repeat
shuffled: bool,
//Etat actuel du player
state: PlayerState,
//Index de la chanson actuelle dans la playlist
index: usize,
}
//-----------------------------------Enums
enum PlayerState {
Playing,
Paused,
Stopped,
} }
@ -39,38 +64,84 @@ impl AudioPlayer {
Self { Self {
sink: sink, sink: sink,
playlist: playlist, playlist: playlist,
} repeating: false,
} //false si mode repeat
shuffled: false,
///Creates a new player from an existing playlist. //Etat actuel du player
///Does not consume the playlist. state: PlayerState::Stopped,
fn from_playlist(playlist: &Playlist) -> Self { index: 0,
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let sink = Sink::try_new(&stream_handle).unwrap();
Self {
sink: sink,
playlist: playlist.clone(),
} }
} }
///Appends a playlist to the current one, consuming it. //-----------------------FONCTIONNALITES A IMPLEMENTER
fn add_playlist(&mut self, playlist: Vec<SongMeta>) { //Ce sont toutes les fonctionnalités de mon player
self.playlist.append(&mut playlist); //Ne pas oublier de bien mettre à jour les variables du player (State, shuffled, random)
}
//renvoie un result, avance d'une chanson
//Charge toutes les chansons de la playlist à partir de l'index donné
//Puis lance la lecture dans le sink
//Pas besoin de valider l'index on se contente de remonter les erreurs
//Renvoie un result
fn play_at(&mut self, index: usize);
//Renvoie une option contenant le clone de la chanson en cours de lecture
//Ainsi que son index dans la playlist
//Ou None si pas en cours de lecture
//Pour ça, utiliser sink.len() qui donne le nombre de chanson dans la file d'attente du sink
//L'index de la chanson en cours dans la playlist correspond à la longueur de la playlist
//moins (sink.len() + 1)
//Schéma:
// chanson en cours
// V
//playlist : [0, 1, 2, 3, 4, 5] = longueur 6
//sink.len: | | = sink.len() = 2
// index dans la playlist de la chanson en cours = (playlist.songs.len()) - (sink.len() + 1)
//
//Ca marche sauf si la playlist est vide auquel cas on se retrouve à -1 sur un usize... Puisque y'a pas de chanson
// à récupérer dans la playlist vu qu'elle est vide ! Donc renvoyer None au préalable si la playlist est vide
fn get_current_song(&self);
//renvoie un result, avance d'une chanson avec sink.skip_one
fn skip_forward(&mut self); fn skip_forward(&mut self);
//renvoie un result, recule d'une chanson
//renvoie un result, recule d'une chanson en pétant le sink et en le refaisant
fn skip_backwards(&mut self); fn skip_backwards(&mut self);
//met en pause renvoie un result //met en pause renvoie un result
fn pause(&mut self); fn pause(&mut self);
//Enleve la pause ou lit la première chanson de la playlist renvoie un result
fn play(&mut self); //enlève la pause renvoie un result
fn unpause(&mut self);
//Renvoie la position (une Duration) dans la chanson actuelle avec sink.get_pos renvoie rien
fn get_pos(&self);
//Change le volume envoie un result //Change le volume envoie un result
fn set_vol(&mut self, vol: f32); fn set_vol(&mut self, vol: f32);
//Renvoie le volume
fn get_vol(&mut self);
//Saute à la chanson donnée renvoie un result //Saute à la chanson donnée renvoie un result
fn goto(&mut self, index: usize) -> Result<(), PlayerError>; fn goto(&mut self, index: usize);
//Active ou désactive le mode shuffle, mélange ou trie la playlist au besoin renvoie rien
//Correspond à un appui sur le bouton shuffle du lecteur cd
fn press_shuffle(&mut self);
//Active ou désactive le mode repeat
//Correspond à un appui sur le bouton repeat
//Renvoie rien
fn press_repeat(&mut self);
//Utilise try_seek sur le sink pour mettre la tête de lecture à une Duration donnée
//renvoie un result
fn seek(&mut self, goto: Duration);
//Stoppe la lecture en cours et vide le sink renvoie rien
fn stop(&mut self);
} }