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}