Skip to main content

n_audio/
queue.rs

1use std::error::Error;
2use std::ffi::OsStr;
3use std::ops::{Deref, DerefMut};
4use std::path::Path;
5use std::sync::{Arc, Mutex};
6
7use rand::seq::SliceRandom;
8use rand::thread_rng;
9use symphonia::core::formats::FormatReader;
10
11use crate::music_track::MusicTrack;
12use crate::player::Player;
13use crate::{NError, TrackTime};
14
15pub struct QueueTrack {
16    format: Arc<Mutex<Box<dyn FormatReader>>>,
17    name: String,
18}
19
20impl QueueTrack {
21    pub fn new(format: Arc<Mutex<Box<dyn FormatReader>>>, name: String) -> Self {
22        Self { format, name }
23    }
24
25    pub fn name(&self) -> &str {
26        &self.name
27    }
28}
29
30pub struct QueuePlayer {
31    queue: Vec<QueueTrack>,
32    player: Player,
33    index: usize,
34}
35
36impl QueuePlayer {
37    pub fn new() -> Self {
38        let player = Player::new(1.0, 1.0);
39
40        QueuePlayer {
41            queue: vec![],
42            player,
43            index: usize::MAX - 1,
44        }
45    }
46
47    #[inline]
48    pub fn add_queue_track(&mut self, track: QueueTrack) {
49        self.queue.push(track);
50    }
51
52    #[inline]
53    pub fn add_format(&mut self, format: Arc<Mutex<Box<dyn FormatReader>>>, name: String) {
54        self.add_queue_track(QueueTrack { format, name });
55    }
56
57    #[inline]
58    pub fn add_track(&mut self, track: MusicTrack) {
59        let format = Arc::new(Mutex::new(track.get_format()));
60        let name = track.name().to_string();
61        self.add_format(format, name);
62    }
63
64    #[inline]
65    pub fn add<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Box<dyn Error>>
66    where
67        P: AsRef<OsStr>,
68    {
69        let track = MusicTrack::new(path)?;
70
71        self.add_track(track);
72
73        Ok(())
74    }
75
76    #[inline]
77    pub fn remove(&mut self, index: usize) {
78        self.queue.remove(index);
79    }
80
81    #[inline]
82    pub fn clear(&mut self) {
83        self.queue.clear();
84        self.index = usize::MAX - 1;
85    }
86
87    #[inline]
88    pub fn shuffle(&mut self) {
89        self.queue.shuffle(&mut thread_rng());
90    }
91
92    pub fn current_track_name(&self) -> &str {
93        if self.index == usize::MAX - 1 {
94            return &self.queue.get(0).unwrap().name;
95        }
96
97        &self.queue.get(self.index).unwrap().name
98    }
99
100    pub fn play(&mut self, index: usize) {
101        self.index = index;
102
103        self.player.play(self.queue[self.index].format.clone());
104    }
105
106    pub fn play_next(&mut self) {
107        self.index += 1;
108
109        if self.index >= self.queue.len() {
110            self.index = 0;
111        }
112
113        self.player.play(self.queue[self.index].format.clone());
114    }
115
116    pub fn play_previous(&mut self) {
117        if self.index == 0 {
118            self.index = self.queue.len();
119        }
120
121        self.index -= 1;
122
123        self.player.play(self.queue[self.index].format.clone());
124    }
125
126    pub fn get_index_from_track_name(&self, name: &str) -> Result<usize, NError> {
127        for (index, track) in self.queue.iter().enumerate() {
128            if track.name == name {
129                return Ok(index);
130            }
131        }
132
133        Err(NError::NoTrack)
134    }
135
136    pub fn get_duration_for_track(&self, index: usize) -> TrackTime {
137        let tmp = self.queue.get(index).unwrap().format.clone();
138        let format = tmp.lock().unwrap();
139
140        let track = format.default_track().expect("Can't load tracks");
141        let time_base = track.codec_params.time_base.unwrap();
142
143        let duration = track
144            .codec_params
145            .n_frames
146            .map(|frames| track.codec_params.start_ts + frames)
147            .unwrap();
148        let time = time_base.calc_time(duration);
149
150        TrackTime {
151            ts_secs: 0,
152            ts_frac: 0.0,
153            dur_secs: time.seconds,
154            dur_frac: time.frac,
155        }
156    }
157}
158
159impl Deref for QueuePlayer {
160    type Target = Player;
161
162    fn deref(&self) -> &Self::Target {
163        &self.player
164    }
165}
166
167impl DerefMut for QueuePlayer {
168    fn deref_mut(&mut self) -> &mut Self::Target {
169        &mut self.player
170    }
171}