A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1use anyhow::Error;
2use async_graphql::Schema;
3use futures::{future::BoxFuture, stream::FuturesUnordered, StreamExt};
4use schema::{Mutation, Query, Subscription};
5use tokio::fs;
6
7pub mod schema;
8pub mod server;
9pub mod simplebroker;
10pub mod types;
11
12pub type RockboxSchema = Schema<Query, Mutation, Subscription>;
13
14pub const AUDIO_EXTENSIONS: [&str; 17] = [
15 "mp3", "ogg", "flac", "m4a", "aac", "mp4", "alac", "wav", "wv", "mpc", "aiff", "ac3", "opus",
16 "spx", "sid", "ape", "wma",
17];
18
19pub fn rockbox_url() -> String {
20 let port = std::env::var("ROCKBOX_TCP_PORT").unwrap_or_else(|_| "6063".to_string());
21 format!("http://127.0.0.1:{}", port)
22}
23
24pub fn read_files(path: String) -> BoxFuture<'static, Result<Vec<String>, Error>> {
25 Box::pin(async move {
26 let mut result = Vec::new();
27 let mut dir = fs::read_dir(path).await?;
28 let mut futures = FuturesUnordered::new();
29 while let Some(entry) = dir.next_entry().await? {
30 let path = entry.path();
31 if path.is_dir() {
32 let dir_path = path.clone();
33 futures.push(tokio::spawn(async move {
34 read_files(dir_path.to_str().unwrap().to_string()).await
35 }));
36 } else if path.is_file() {
37 if !AUDIO_EXTENSIONS
38 .into_iter()
39 .any(|ext| path.to_str().unwrap().ends_with(&format!(".{}", ext)))
40 {
41 continue;
42 }
43 result.push(path.to_str().unwrap().to_string());
44 }
45 }
46 while let Some(Ok(future)) = futures.next().await {
47 result.extend(future?);
48 }
49 Ok(result)
50 })
51}