···33 <img src="https://ziglang.org/ziggy.svg" height="150"/>
44</div>
5566-76# Rockbox Zig 🎵 ⚡
8798[](./LICENSE)
···1312[](https://discord.gg/tXPrgcPKSt)
1413[](https://master--670ceec25af685dcdc87c0df.chromatic.com/?path=/story/components-albums--default)
15141616-1715
18161919-A modern take on the [Rockbox](https://www.rockbox.org) open-source firmware with enhancements in Zig and Rust. This project offers:
1717+A modern take on the [Rockbox](https://www.rockbox.org) open-source firmware
1818+with enhancements in Zig and Rust. This project offers:
20192120- gRPC & GraphQL APIs for seamless interaction and control
2221- Chromecast support for streaming to your TV
2323-- [MPD](https://mpd.readthedocs.io/en/stable/protocol.html) server for compatibility with existing clients
2424-- [MPRIS](https://specifications.freedesktop.org/mpris-spec/) support for desktop integration
2222+- [MPD](https://mpd.readthedocs.io/en/stable/protocol.html) server for
2323+ compatibility with existing clients
2424+- [MPRIS](https://specifications.freedesktop.org/mpris-spec/) support for
2525+ desktop integration
2526- TypeScript support for building powerful extensions
26272727-Take advantage of modern tooling while preserving the core functionality of Rockbox.
2828+Take advantage of modern tooling while preserving the core functionality of
2929+Rockbox.
28302929-> [!NOTE]
3030-**🐲 It is a work in progress and is not yet ready for use. 🏗️🚧**
3131+> [!NOTE] **🐲 It is a work in progress and is not yet ready for use. 🏗️🚧**
31323233
33343435## 🚀 Quickstart
35363637To quickly get started, you can run the following docker command:
3838+3739```sh
3840docker run \
3941 --device /dev/snd \
···48504951## Requirements
50525151-Run the following commands to build the project:
5252-Before building the project, you need to install the necessary dependencies for your operating system.
5353+Run the following commands to build the project: Before building the project,
5454+you need to install the necessary dependencies for your operating system.
53555456### On Ubuntu/Debian
5557···8082```
818382843. Build the webui
8585+8386```sh
8487cd webui/rockbox
8588deno install
···121124122125## 📦 Downloads
123126124124-- `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)
127127+- `Linux`: intel:
128128+ [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)
129129+ arm64:
130130+ [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)
125131126132## ✨ Features
127133···131137- [x] GraphQL API
132138- [x] HTTP API
133139- [x] Web Client (React)
134134-- [x] Fast search engine, built with [Tantivy](https://github.com/quickwit-oss/tantivy)
140140+- [x] Fast search engine, built with
141141+ [Tantivy](https://github.com/quickwit-oss/tantivy)
135142- [x] Desktop Client (Electron/Gtk)
136143- [x] Rockbox REPL
137144- [x] Terminal Client (TUI)
145145+- [x] Systemd service
138146- [ ] Android Library
139147- [ ] Mobile version (React Native)
140148- [ ] Stream from Youtube (audio only)
···156164157165## 📚 GraphQL API
158166159159-Open [http://localhost:6062/graphiql](http://localhost:6062/graphiql) in your browser.
167167+Open [http://localhost:6062/graphiql](http://localhost:6062/graphiql) in your
168168+browser.
160169161170<p style="margin-top: 20px; margin-bottom: 20px;">
162171 <img src="./docs/graphql.png" width="100%" />
···174183175184[https://buf.build/tsiry/rockboxapis/docs/main:rockbox.v1alpha1](https://buf.build/tsiry/rockboxapis/docs/main:rockbox.v1alpha1)
176185177177-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).
186186+Try Rockbox gRPC API using
187187+[Buf Studio](https://buf.build/studio/tsiry/rockboxapis/rockbox.v1alpha1.LibraryService/GetAlbums?target=http%3A%2F%2Flocalhost%3A6061&selectedProtocol=grpc-web).
178188179189<p style="margin-top: 20px; margin-bottom: 20px;">
180190 <img src="./docs/grpc.png" width="100%" />
+1
cli/src/cmd/mod.rs
···22pub mod repl;
33pub mod run;
44pub mod scan;
55+pub mod service;
56pub mod start;
67pub mod webui;
+89
cli/src/cmd/service.rs
···11+use anyhow::Error;
22+use std::path::Path;
33+use std::process::Command;
44+55+const SERVICE_TEMPLATE: &str = include_str!("../../systemd/rockbox.service");
66+77+pub fn install() -> Result<(), Error> {
88+ let home = std::env::var("HOME")?;
99+ let service_path: &str = &format!("{}/.config/systemd/user/rockbox.service", home);
1010+ std::fs::create_dir_all(format!("{}/.config/systemd/user", home))
1111+ .expect("Failed to create systemd user directory");
1212+1313+ if Path::new(service_path).exists() {
1414+ println!("Service file already exists. Nothing to install.");
1515+ return Ok(());
1616+ }
1717+1818+ std::fs::write(service_path, SERVICE_TEMPLATE).expect("Failed to write service file");
1919+2020+ Command::new("systemctl")
2121+ .arg("--user")
2222+ .arg("daemon-reload")
2323+ .status()?;
2424+2525+ Command::new("systemctl")
2626+ .arg("--user")
2727+ .arg("enable")
2828+ .arg("rockbox")
2929+ .status()?;
3030+3131+ Command::new("systemctl")
3232+ .arg("--user")
3333+ .arg("start")
3434+ .arg("rockbox")
3535+ .status()?;
3636+3737+ println!("✅ Rockbox service installed successfully!");
3838+3939+ Ok(())
4040+}
4141+4242+pub fn uninstall() -> Result<(), Error> {
4343+ let home = std::env::var("HOME")?;
4444+ let service_path: &str = &format!("{}/.config/systemd/user/rockbox.service", home);
4545+4646+ if Path::new(service_path).exists() {
4747+ Command::new("systemctl")
4848+ .arg("--user")
4949+ .arg("stop")
5050+ .arg("rockbox")
5151+ .status()?;
5252+5353+ Command::new("systemctl")
5454+ .arg("--user")
5555+ .arg("disable")
5656+ .arg("rockbox")
5757+ .status()?;
5858+5959+ std::fs::remove_file(service_path).expect("Failed to remove service file");
6060+6161+ Command::new("systemctl")
6262+ .arg("--user")
6363+ .arg("daemon-reload")
6464+ .status()?;
6565+6666+ println!("✅ Rockbox service uninstalled successfully!");
6767+ } else {
6868+ println!("Service file does not exist. Nothing to uninstall.");
6969+ }
7070+7171+ Ok(())
7272+}
7373+7474+pub fn status() -> Result<(), Error> {
7575+ let home = std::env::var("HOME")?;
7676+ let service_path: &str = &format!("{}/.config/systemd/user/rockbox.service", home);
7777+7878+ if Path::new(service_path).exists() {
7979+ Command::new("systemctl")
8080+ .arg("--user")
8181+ .arg("status")
8282+ .arg("rockbox")
8383+ .status()?;
8484+ } else {
8585+ println!("Service file does not exist. Rockbox service is not installed.");
8686+ }
8787+8888+ Ok(())
8989+}
+31-1
cli/src/main.rs
···44use clap::{arg, Command};
55use owo_colors::OwoColorize;
6677-use cmd::{community::*, repl::*, run::*, scan::*, start::*, webui::*};
77+use cmd::{community::*, repl::*, run::*, scan::*, start::*, webui::*, service};
8899pub mod cmd;
1010···5454 .about("Run a JavaScript or TypeScript program")
5555 .visible_alias("x"),
5656 )
5757+ .subcommand(
5858+ Command::new("service")
5959+ .about("Manage systemd service for Rockbox")
6060+ .subcommand(
6161+ Command::new("install")
6262+ .about("Install systemd service for Rockbox")
6363+ )
6464+ .subcommand(
6565+ Command::new("uninstall")
6666+ .about("Uninstall systemd service for Rockbox")
6767+ )
6868+ .subcommand(
6969+ Command::new("status")
7070+ .about("Check status of systemd service for Rockbox")
7171+ )
7272+ )
5773}
58745975#[tokio::main]
···94110 Some(("tui", _)) => {
95111 rmpc::main_tui()?;
96112 }
113113+ Some(("service", sub_m)) => match sub_m.subcommand() {
114114+ Some(("install", _)) => {
115115+ service::install()?;
116116+ }
117117+ Some(("uninstall", _)) => {
118118+ service::uninstall()?;
119119+ }
120120+ Some(("status", _)) => {
121121+ service::status()?;
122122+ }
123123+ _ => {
124124+ println!("Invalid subcommand. Use `rockbox service --help` for more information.");
125125+ }
126126+ },
97127 _ => {
98128 start(true)?;
99129 }
+11
cli/systemd/rockbox.service
···11+[Unit]
22+Description=Rockbox Music Server
33+After=network.target
44+55+[Service]
66+ExecStart=/usr/local/bin/rockboxd
77+Restart=always
88+Environment="SDL_VIDEODRIVER=dummy"
99+1010+[Install]
1111+WantedBy=default.target