Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

cli: add 'service' subcommand for managing Rockbox Service

+156 -15
+24 -14
README.md
··· 3 3 <img src="https://ziglang.org/ziggy.svg" height="150"/> 4 4 </div> 5 5 6 - 7 6 # Rockbox Zig 🎵 ⚡ 8 7 9 8 [![GPL-2.0 licensed](https://img.shields.io/badge/License-GPL-blue.svg)](./LICENSE) ··· 13 12 [![discord](https://img.shields.io/discord/1292855167921815715?label=discord&logo=discord&color=5865F2)](https://discord.gg/tXPrgcPKSt) 14 13 [![storybook](https://raw.githubusercontent.com/storybooks/brand/master/badge/badge-storybook.svg)](https://master--670ceec25af685dcdc87c0df.chromatic.com/?path=/story/components-albums--default) 15 14 16 - 17 15 ![Rockbox UI](./gtk/data/screenshots/1.png) 18 16 19 - A modern take on the [Rockbox](https://www.rockbox.org) open-source firmware with enhancements in Zig and Rust. This project offers: 17 + A modern take on the [Rockbox](https://www.rockbox.org) open-source firmware 18 + with enhancements in Zig and Rust. This project offers: 20 19 21 20 - gRPC & GraphQL APIs for seamless interaction and control 22 21 - Chromecast support for streaming to your TV 23 - - [MPD](https://mpd.readthedocs.io/en/stable/protocol.html) server for compatibility with existing clients 24 - - [MPRIS](https://specifications.freedesktop.org/mpris-spec/) support for desktop integration 22 + - [MPD](https://mpd.readthedocs.io/en/stable/protocol.html) server for 23 + compatibility with existing clients 24 + - [MPRIS](https://specifications.freedesktop.org/mpris-spec/) support for 25 + desktop integration 25 26 - TypeScript support for building powerful extensions 26 27 27 - Take advantage of modern tooling while preserving the core functionality of Rockbox. 28 + Take advantage of modern tooling while preserving the core functionality of 29 + Rockbox. 28 30 29 - > [!NOTE] 30 - **🐲 It is a work in progress and is not yet ready for use. 🏗️🚧** 31 + > [!NOTE] **🐲 It is a work in progress and is not yet ready for use. 🏗️🚧** 31 32 32 33 ![Preview](./docs/preview.png) 33 34 34 35 ## 🚀 Quickstart 35 36 36 37 To quickly get started, you can run the following docker command: 38 + 37 39 ```sh 38 40 docker run \ 39 41 --device /dev/snd \ ··· 48 50 49 51 ## Requirements 50 52 51 - Run the following commands to build the project: 52 - Before building the project, you need to install the necessary dependencies for your operating system. 53 + Run the following commands to build the project: Before building the project, 54 + you need to install the necessary dependencies for your operating system. 53 55 54 56 ### On Ubuntu/Debian 55 57 ··· 80 82 ``` 81 83 82 84 3. Build the webui 85 + 83 86 ```sh 84 87 cd webui/rockbox 85 88 deno install ··· 121 124 122 125 ## 📦 Downloads 123 126 124 - - `Linux`: intel: [rockbox_2025.01.17_x86_64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.17/rockbox_2025.01.17_x86_64-linux.tar.gz) arm64: [rockbox_2025.01.17_aarch64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.17/rockbox_2025.01.17_aarch64-linux.tar.gz) 127 + - `Linux`: intel: 128 + [rockbox_2025.01.17_x86_64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.17/rockbox_2025.01.17_x86_64-linux.tar.gz) 129 + arm64: 130 + [rockbox_2025.01.17_aarch64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.17/rockbox_2025.01.17_aarch64-linux.tar.gz) 125 131 126 132 ## ✨ Features 127 133 ··· 131 137 - [x] GraphQL API 132 138 - [x] HTTP API 133 139 - [x] Web Client (React) 134 - - [x] Fast search engine, built with [Tantivy](https://github.com/quickwit-oss/tantivy) 140 + - [x] Fast search engine, built with 141 + [Tantivy](https://github.com/quickwit-oss/tantivy) 135 142 - [x] Desktop Client (Electron/Gtk) 136 143 - [x] Rockbox REPL 137 144 - [x] Terminal Client (TUI) 145 + - [x] Systemd service 138 146 - [ ] Android Library 139 147 - [ ] Mobile version (React Native) 140 148 - [ ] Stream from Youtube (audio only) ··· 156 164 157 165 ## 📚 GraphQL API 158 166 159 - Open [http://localhost:6062/graphiql](http://localhost:6062/graphiql) in your browser. 167 + Open [http://localhost:6062/graphiql](http://localhost:6062/graphiql) in your 168 + browser. 160 169 161 170 <p style="margin-top: 20px; margin-bottom: 20px;"> 162 171 <img src="./docs/graphql.png" width="100%" /> ··· 174 183 175 184 [https://buf.build/tsiry/rockboxapis/docs/main:rockbox.v1alpha1](https://buf.build/tsiry/rockboxapis/docs/main:rockbox.v1alpha1) 176 185 177 - Try Rockbox gRPC API using [Buf Studio](https://buf.build/studio/tsiry/rockboxapis/rockbox.v1alpha1.LibraryService/GetAlbums?target=http%3A%2F%2Flocalhost%3A6061&selectedProtocol=grpc-web). 186 + Try Rockbox gRPC API using 187 + [Buf Studio](https://buf.build/studio/tsiry/rockboxapis/rockbox.v1alpha1.LibraryService/GetAlbums?target=http%3A%2F%2Flocalhost%3A6061&selectedProtocol=grpc-web). 178 188 179 189 <p style="margin-top: 20px; margin-bottom: 20px;"> 180 190 <img src="./docs/grpc.png" width="100%" />
+1
cli/src/cmd/mod.rs
··· 2 2 pub mod repl; 3 3 pub mod run; 4 4 pub mod scan; 5 + pub mod service; 5 6 pub mod start; 6 7 pub mod webui;
+89
cli/src/cmd/service.rs
··· 1 + use anyhow::Error; 2 + use std::path::Path; 3 + use std::process::Command; 4 + 5 + const SERVICE_TEMPLATE: &str = include_str!("../../systemd/rockbox.service"); 6 + 7 + pub fn install() -> Result<(), Error> { 8 + let home = std::env::var("HOME")?; 9 + let service_path: &str = &format!("{}/.config/systemd/user/rockbox.service", home); 10 + std::fs::create_dir_all(format!("{}/.config/systemd/user", home)) 11 + .expect("Failed to create systemd user directory"); 12 + 13 + if Path::new(service_path).exists() { 14 + println!("Service file already exists. Nothing to install."); 15 + return Ok(()); 16 + } 17 + 18 + std::fs::write(service_path, SERVICE_TEMPLATE).expect("Failed to write service file"); 19 + 20 + Command::new("systemctl") 21 + .arg("--user") 22 + .arg("daemon-reload") 23 + .status()?; 24 + 25 + Command::new("systemctl") 26 + .arg("--user") 27 + .arg("enable") 28 + .arg("rockbox") 29 + .status()?; 30 + 31 + Command::new("systemctl") 32 + .arg("--user") 33 + .arg("start") 34 + .arg("rockbox") 35 + .status()?; 36 + 37 + println!("✅ Rockbox service installed successfully!"); 38 + 39 + Ok(()) 40 + } 41 + 42 + pub fn uninstall() -> Result<(), Error> { 43 + let home = std::env::var("HOME")?; 44 + let service_path: &str = &format!("{}/.config/systemd/user/rockbox.service", home); 45 + 46 + if Path::new(service_path).exists() { 47 + Command::new("systemctl") 48 + .arg("--user") 49 + .arg("stop") 50 + .arg("rockbox") 51 + .status()?; 52 + 53 + Command::new("systemctl") 54 + .arg("--user") 55 + .arg("disable") 56 + .arg("rockbox") 57 + .status()?; 58 + 59 + std::fs::remove_file(service_path).expect("Failed to remove service file"); 60 + 61 + Command::new("systemctl") 62 + .arg("--user") 63 + .arg("daemon-reload") 64 + .status()?; 65 + 66 + println!("✅ Rockbox service uninstalled successfully!"); 67 + } else { 68 + println!("Service file does not exist. Nothing to uninstall."); 69 + } 70 + 71 + Ok(()) 72 + } 73 + 74 + pub fn status() -> Result<(), Error> { 75 + let home = std::env::var("HOME")?; 76 + let service_path: &str = &format!("{}/.config/systemd/user/rockbox.service", home); 77 + 78 + if Path::new(service_path).exists() { 79 + Command::new("systemctl") 80 + .arg("--user") 81 + .arg("status") 82 + .arg("rockbox") 83 + .status()?; 84 + } else { 85 + println!("Service file does not exist. Rockbox service is not installed."); 86 + } 87 + 88 + Ok(()) 89 + }
+31 -1
cli/src/main.rs
··· 4 4 use clap::{arg, Command}; 5 5 use owo_colors::OwoColorize; 6 6 7 - use cmd::{community::*, repl::*, run::*, scan::*, start::*, webui::*}; 7 + use cmd::{community::*, repl::*, run::*, scan::*, start::*, webui::*, service}; 8 8 9 9 pub mod cmd; 10 10 ··· 54 54 .about("Run a JavaScript or TypeScript program") 55 55 .visible_alias("x"), 56 56 ) 57 + .subcommand( 58 + Command::new("service") 59 + .about("Manage systemd service for Rockbox") 60 + .subcommand( 61 + Command::new("install") 62 + .about("Install systemd service for Rockbox") 63 + ) 64 + .subcommand( 65 + Command::new("uninstall") 66 + .about("Uninstall systemd service for Rockbox") 67 + ) 68 + .subcommand( 69 + Command::new("status") 70 + .about("Check status of systemd service for Rockbox") 71 + ) 72 + ) 57 73 } 58 74 59 75 #[tokio::main] ··· 94 110 Some(("tui", _)) => { 95 111 rmpc::main_tui()?; 96 112 } 113 + Some(("service", sub_m)) => match sub_m.subcommand() { 114 + Some(("install", _)) => { 115 + service::install()?; 116 + } 117 + Some(("uninstall", _)) => { 118 + service::uninstall()?; 119 + } 120 + Some(("status", _)) => { 121 + service::status()?; 122 + } 123 + _ => { 124 + println!("Invalid subcommand. Use `rockbox service --help` for more information."); 125 + } 126 + }, 97 127 _ => { 98 128 start(true)?; 99 129 }
+11
cli/systemd/rockbox.service
··· 1 + [Unit] 2 + Description=Rockbox Music Server 3 + After=network.target 4 + 5 + [Service] 6 + ExecStart=/usr/local/bin/rockboxd 7 + Restart=always 8 + Environment="SDL_VIDEODRIVER=dummy" 9 + 10 + [Install] 11 + WantedBy=default.target