@@ -24,9 +24,13 @@ mod term;
2424
2525use mimalloc:: MiMalloc ;
2626
27+ // Changes the allocator to improve performance especially on Windows
2728#[ global_allocator]
2829static GLOBAL : MiMalloc = MiMalloc ;
2930
31+ /**
32+ * Actions that can be sent to the player from other services
33+ */
3034#[ derive( Debug , Clone ) ]
3135pub enum SoundAction {
3236 Cleanup ,
@@ -44,8 +48,12 @@ pub enum SoundAction {
4448 PlayVideoUnary ( Video ) ,
4549}
4650
51+ // A global variable to store the current musical Database
4752pub static DATABASE : Lazy < RwLock < Vec < Video > > > = Lazy :: new ( || RwLock :: new ( Vec :: new ( ) ) ) ;
4853
54+ /**
55+ * Writes the database to the disk
56+ */
4957fn write ( ) {
5058 let db = DATABASE . read ( ) . unwrap ( ) ;
5159 let mut file = OpenOptions :: new ( )
@@ -58,6 +66,9 @@ fn write() {
5866 write_video ( & mut file, video)
5967 }
6068}
69+ /**
70+ * append a video to the database
71+ */
6172pub fn append ( video : Video ) {
6273 let mut file = OpenOptions :: new ( )
6374 . write ( true )
@@ -70,6 +81,9 @@ pub fn append(video: Video) {
7081 DATABASE . write ( ) . unwrap ( ) . push ( video) ;
7182}
7283
84+ /**
85+ * Writes a video to a file
86+ */
7387fn write_video ( buffer : & mut impl Write , video : & Video ) {
7488 write_str ( buffer, & video. title ) ;
7589 write_str ( buffer, & video. author ) ;
@@ -78,6 +92,9 @@ fn write_video(buffer: &mut impl Write, video: &Video) {
7892 write_str ( buffer, & video. duration ) ;
7993}
8094
95+ /**
96+ * Reads the database
97+ */
8198fn read ( ) -> Option < Vec < Video > > {
8299 let mut buffer = Cursor :: new ( std:: fs:: read ( "data/db.bin" ) . ok ( ) ?) ;
83100 let mut videos = HashSet :: new ( ) ;
@@ -87,6 +104,9 @@ fn read() -> Option<Vec<Video>> {
87104 Some ( videos. into_iter ( ) . collect :: < Vec < _ > > ( ) )
88105}
89106
107+ /**
108+ * Reads a video from the cursor
109+ */
90110fn read_video ( buffer : & mut Cursor < Vec < u8 > > ) -> Option < Video > {
91111 Some ( Video {
92112 title : read_str ( buffer) ?,
@@ -97,21 +117,33 @@ fn read_video(buffer: &mut Cursor<Vec<u8>>) -> Option<Video> {
97117 } )
98118}
99119
120+ /**
121+ * Writes a string from the cursor
122+ */
100123fn write_str ( cursor : & mut impl Write , value : & str ) {
101124 write_u32 ( cursor, value. len ( ) as u32 ) ;
102125 cursor. write_all ( value. as_bytes ( ) ) . unwrap ( ) ;
103126}
104127
128+ /**
129+ * Reads a string from the cursor
130+ */
105131fn read_str ( cursor : & mut Cursor < Vec < u8 > > ) -> Option < String > {
106132 let mut buf = vec ! [ 0u8 ; read_u32( cursor) ? as usize ] ;
107133 cursor. read_exact ( & mut buf) . ok ( ) ?;
108134 String :: from_utf8 ( buf) . ok ( )
109135}
110136
137+ /**
138+ * Writes a u32 from the cursor
139+ */
111140fn write_u32 ( cursor : & mut impl Write , value : u32 ) {
112141 cursor. write_varint ( value) . unwrap ( ) ;
113142}
114143
144+ /**
145+ * Reads a u32 from the cursor
146+ */
115147fn read_u32 ( cursor : & mut Cursor < Vec < u8 > > ) -> Option < u32 > {
116148 ReadVarint :: < u32 > :: read_varint ( cursor) . ok ( )
117149}
@@ -121,18 +153,44 @@ async fn main() -> Result<(), Error> {
121153 std:: fs:: create_dir_all ( "data/downloads" ) . unwrap ( ) ;
122154 if !PathBuf :: from_str ( "headers.txt" ) . unwrap ( ) . exists ( ) {
123155 println ! ( "The `headers.txt` file is not present in the root directory." ) ;
124- println ! ( "This file should contain your headers separated by `: `." ) ;
156+ println ! ( "To configure the YTerMusic:" ) ;
157+ println ! ( "1. Open the YouTube Music website in your browser" ) ;
158+ println ! ( "2. Open the developer tools (F12)" ) ;
159+ println ! ( "3. Go to the Network tab" ) ;
160+ println ! ( "4. Go to https://music.youtube.com" ) ;
161+ println ! ( "5. Copy the `cookie` header from the associated request" ) ;
162+ println ! ( "6. Paste it in the `headers.txt` file as `Cookie: <cookie>`" ) ;
163+ println ! ( "7. Restart YterMusic" ) ;
125164 return Ok ( ( ) ) ;
126165 }
166+ if !std:: fs:: read_to_string ( "headers.txt" )
167+ . unwrap ( )
168+ . contains ( "Cookie: " )
169+ {
170+ println ! ( "The `headers.txt` file is not configured correctly." ) ;
171+ println ! ( "To configure the YTerMusic:" ) ;
172+ println ! ( "1. Open the YouTube Music website in your browser" ) ;
173+ println ! ( "2. Open the developer tools (F12)" ) ;
174+ println ! ( "3. Go to the Network tab" ) ;
175+ println ! ( "4. Go to https://music.youtube.com" ) ;
176+ println ! ( "5. Copy the `cookie` header from the associated request" ) ;
177+ println ! ( "6. Paste it in the `headers.txt` file as `Cookie: <cookie>`" ) ;
178+ println ! ( "7. Restart YterMusic" ) ;
179+ return Ok ( ( ) ) ;
180+ }
181+ // Spawn the clean task
127182 let ( updater_s, updater_r) = flume:: unbounded :: < ManagerMessage > ( ) ;
128183 tokio:: task:: spawn ( async {
129184 clean ( ) ;
130185 } ) ;
131186 let updater_s = Arc :: new ( updater_s) ;
187+ // Spawn the player task
132188 let ( sa, player) = player_system ( updater_s. clone ( ) ) ;
189+ // Spawn the downloader task
133190 downloader ( sa. clone ( ) ) ;
134191 {
135192 let updater_s = updater_s. clone ( ) ;
193+ // Spawn playlist updater task
136194 tokio:: task:: spawn ( async move {
137195 let playlist = std:: fs:: read_to_string ( "data/last-playlist.json" ) . ok ( ) ?;
138196 let mut playlist: ( String , Vec < Video > ) = serde_json:: from_str ( & playlist) . ok ( ) ?;
@@ -147,6 +205,7 @@ async fn main() -> Result<(), Error> {
147205 }
148206 {
149207 let updater_s = updater_s. clone ( ) ;
208+ // Spawn the API task
150209 tokio:: task:: spawn ( async move {
151210 match YTApi :: from_header_file ( PathBuf :: from_str ( "headers.txt" ) . unwrap ( ) . as_path ( ) ) . await
152211 {
@@ -187,6 +246,7 @@ async fn main() -> Result<(), Error> {
187246 }
188247 {
189248 let updater_s = updater_s. clone ( ) ;
249+ // Spawn the database getter task
190250 tokio:: task:: spawn ( async move {
191251 if let Some ( e) = read ( ) {
192252 * DATABASE . write ( ) . unwrap ( ) = e. clone ( ) ;
@@ -228,6 +288,9 @@ async fn main() -> Result<(), Error> {
228288 Ok ( ( ) )
229289}
230290
291+ /**
292+ * This function is called on strat to clean the database and the files that are incompletly downloaded due to a crash.
293+ */
231294fn clean ( ) {
232295 for i in std:: fs:: read_dir ( "data/downloads" ) . unwrap ( ) {
233296 let path = i. unwrap ( ) . path ( ) ;
0 commit comments