Skip to content

Commit 8a903dd

Browse files
authored
Merge pull request #108 from tsirysndr/fix/mpris-identity
fix(mpris): handle mpris play_pause function and set app identity
2 parents 0399208 + eea3dd9 commit 8a903dd

File tree

12 files changed

+217
-11
lines changed

12 files changed

+217
-11
lines changed

README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ curl -fsSL https://raw.githubusercontent.com/tsirysndr/rockbox-zig/HEAD/install.
124124
## 📦 Downloads
125125

126126
- `Linux`: intel:
127-
[rockbox_2025.01.26_x86_64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.26/rockbox_2025.01.26_x86_64-linux.tar.gz)
127+
[rockbox_2025.01.27_x86_64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.27/rockbox_2025.01.27_x86_64-linux.tar.gz)
128128
arm64:
129-
[rockbox_2025.01.26_aarch64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.26/rockbox_2025.01.26_aarch64-linux.tar.gz)
129+
[rockbox_2025.01.27_aarch64-linux.tar.gz](https://github.com/tsirysndr/rockbox-zig/releases/download/2025.01.27/rockbox_2025.01.27_aarch64-linux.tar.gz)
130130

131131
## 🧙‍♂️ Systemd Service
132132

@@ -161,14 +161,13 @@ your operating system.
161161
### On Ubuntu/Debian
162162

163163
```bash
164-
sudo apt-get install libusb-dev libsdl2-dev libfreetype6-dev libunwind-dev zip protobuf-compiler cmake
164+
sudo apt-get install libsdl2-dev libfreetype6-dev libunwind-dev zip protobuf-compiler cmake
165165
```
166166

167167
### On Fedora40/41:
168168

169169
```sh
170-
sudo dnf install libusb1-devel SDL2-devel freetype-devel libunwind-devel zip protobuf-compiler cmake
171-
sudo ln -s /lib64/libusb-1.0.so /usr/lib64/libusb.so
170+
sudo dnf install SDL2-devel freetype-devel libunwind-devel zip protobuf-compiler cmake
172171
```
173172

174173
### Build Instructions

cli/src/api/rockbox.v1alpha1.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,10 @@ pub struct PlayResponse {}
20602060
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
20612061
pub struct PauseRequest {}
20622062
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2063+
pub struct PlayOrPauseRequest {}
2064+
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2065+
pub struct PlayOrPauseResponse {}
2066+
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
20632067
pub struct PauseResponse {}
20642068
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
20652069
pub struct ResumeRequest {}
@@ -2421,6 +2425,32 @@ pub mod playback_service_client {
24212425
.insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Pause"));
24222426
self.inner.unary(req, path, codec).await
24232427
}
2428+
pub async fn play_or_pause(
2429+
&mut self,
2430+
request: impl tonic::IntoRequest<super::PlayOrPauseRequest>,
2431+
) -> std::result::Result<
2432+
tonic::Response<super::PlayOrPauseResponse>,
2433+
tonic::Status,
2434+
> {
2435+
self.inner
2436+
.ready()
2437+
.await
2438+
.map_err(|e| {
2439+
tonic::Status::unknown(
2440+
format!("Service was not ready: {}", e.into()),
2441+
)
2442+
})?;
2443+
let codec = tonic::codec::ProstCodec::default();
2444+
let path = http::uri::PathAndQuery::from_static(
2445+
"/rockbox.v1alpha1.PlaybackService/PlayOrPause",
2446+
);
2447+
let mut req = request.into_request();
2448+
req.extensions_mut()
2449+
.insert(
2450+
GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayOrPause"),
2451+
);
2452+
self.inner.unary(req, path, codec).await
2453+
}
24242454
pub async fn resume(
24252455
&mut self,
24262456
request: impl tonic::IntoRequest<super::ResumeRequest>,
@@ -2963,6 +2993,13 @@ pub mod playback_service_server {
29632993
&self,
29642994
request: tonic::Request<super::PauseRequest>,
29652995
) -> std::result::Result<tonic::Response<super::PauseResponse>, tonic::Status>;
2996+
async fn play_or_pause(
2997+
&self,
2998+
request: tonic::Request<super::PlayOrPauseRequest>,
2999+
) -> std::result::Result<
3000+
tonic::Response<super::PlayOrPauseResponse>,
3001+
tonic::Status,
3002+
>;
29663003
async fn resume(
29673004
&self,
29683005
request: tonic::Request<super::ResumeRequest>,
@@ -3277,6 +3314,51 @@ pub mod playback_service_server {
32773314
};
32783315
Box::pin(fut)
32793316
}
3317+
"/rockbox.v1alpha1.PlaybackService/PlayOrPause" => {
3318+
#[allow(non_camel_case_types)]
3319+
struct PlayOrPauseSvc<T: PlaybackService>(pub Arc<T>);
3320+
impl<
3321+
T: PlaybackService,
3322+
> tonic::server::UnaryService<super::PlayOrPauseRequest>
3323+
for PlayOrPauseSvc<T> {
3324+
type Response = super::PlayOrPauseResponse;
3325+
type Future = BoxFuture<
3326+
tonic::Response<Self::Response>,
3327+
tonic::Status,
3328+
>;
3329+
fn call(
3330+
&mut self,
3331+
request: tonic::Request<super::PlayOrPauseRequest>,
3332+
) -> Self::Future {
3333+
let inner = Arc::clone(&self.0);
3334+
let fut = async move {
3335+
<T as PlaybackService>::play_or_pause(&inner, request).await
3336+
};
3337+
Box::pin(fut)
3338+
}
3339+
}
3340+
let accept_compression_encodings = self.accept_compression_encodings;
3341+
let send_compression_encodings = self.send_compression_encodings;
3342+
let max_decoding_message_size = self.max_decoding_message_size;
3343+
let max_encoding_message_size = self.max_encoding_message_size;
3344+
let inner = self.inner.clone();
3345+
let fut = async move {
3346+
let method = PlayOrPauseSvc(inner);
3347+
let codec = tonic::codec::ProstCodec::default();
3348+
let mut grpc = tonic::server::Grpc::new(codec)
3349+
.apply_compression_config(
3350+
accept_compression_encodings,
3351+
send_compression_encodings,
3352+
)
3353+
.apply_max_message_size_config(
3354+
max_decoding_message_size,
3355+
max_encoding_message_size,
3356+
);
3357+
let res = grpc.unary(method, req).await;
3358+
Ok(res)
3359+
};
3360+
Box::pin(fut)
3361+
}
32803362
"/rockbox.v1alpha1.PlaybackService/Resume" => {
32813363
#[allow(non_camel_case_types)]
32823364
struct ResumeSvc<T: PlaybackService>(pub Arc<T>);

cli/src/api/rockbox_descriptor.bin

252 Bytes
Binary file not shown.

crates/mpris/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rockbox_rpc::api::rockbox::v1alpha1::{
1212
sound_service_client::SoundServiceClient, AdjustVolumeRequest, GetGlobalSettingsRequest,
1313
HardStopRequest, NextRequest, PauseRequest, PlayRequest, PlayTrackRequest, PreviousRequest,
1414
ResumeRequest, SaveSettingsRequest,
15+
PlayOrPauseRequest,
1516
};
1617
use tokio::sync::Mutex;
1718

@@ -50,6 +51,8 @@ impl MprisServer {
5051
.build()
5152
.await?;
5253

54+
player.set_identity("Rockbox").await?;
55+
5356
connect_player_action!(
5457
player,
5558
client,
@@ -60,6 +63,7 @@ impl MprisServer {
6063
connect_player_action!(player, client, connect_next, next, NextRequest {});
6164
connect_player_action!(player, client, connect_play, resume, ResumeRequest {});
6265
connect_player_action!(player, client, connect_pause, pause, PauseRequest {});
66+
connect_player_action!(player, client, connect_play_pause, play_or_pause, PlayOrPauseRequest {});
6367
connect_player_seek_action!(player, client);
6468
connect_player_set_position_action!(player, client);
6569
connect_player_action!(player, client, connect_stop, hard_stop, HardStopRequest {});

crates/rpc/proto/rockbox/v1alpha1/playback.proto

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ message PlayResponse {}
1111

1212
message PauseRequest {}
1313

14+
message PlayOrPauseRequest {}
15+
16+
message PlayOrPauseResponse {}
17+
1418
message PauseResponse {}
1519

1620
message ResumeRequest {}
@@ -174,6 +178,7 @@ message PlaylistResponse {
174178
service PlaybackService {
175179
rpc Play(PlayRequest) returns (PlayResponse) {}
176180
rpc Pause(PauseRequest) returns (PauseResponse) {}
181+
rpc PlayOrPause(PlayOrPauseRequest) returns (PlayOrPauseResponse) {}
177182
rpc Resume(ResumeRequest) returns (ResumeResponse) {}
178183
rpc Next(NextRequest) returns (NextResponse) {}
179184
rpc Previous(PreviousRequest) returns (PreviousResponse) {}

crates/rpc/src/api/rockbox.v1alpha1.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,6 +2654,10 @@ pub struct PlayResponse {}
26542654
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
26552655
pub struct PauseRequest {}
26562656
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2657+
pub struct PlayOrPauseRequest {}
2658+
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2659+
pub struct PlayOrPauseResponse {}
2660+
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
26572661
pub struct PauseResponse {}
26582662
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
26592663
pub struct ResumeRequest {}
@@ -3015,6 +3019,32 @@ pub mod playback_service_client {
30153019
.insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Pause"));
30163020
self.inner.unary(req, path, codec).await
30173021
}
3022+
pub async fn play_or_pause(
3023+
&mut self,
3024+
request: impl tonic::IntoRequest<super::PlayOrPauseRequest>,
3025+
) -> std::result::Result<
3026+
tonic::Response<super::PlayOrPauseResponse>,
3027+
tonic::Status,
3028+
> {
3029+
self.inner
3030+
.ready()
3031+
.await
3032+
.map_err(|e| {
3033+
tonic::Status::unknown(
3034+
format!("Service was not ready: {}", e.into()),
3035+
)
3036+
})?;
3037+
let codec = tonic::codec::ProstCodec::default();
3038+
let path = http::uri::PathAndQuery::from_static(
3039+
"/rockbox.v1alpha1.PlaybackService/PlayOrPause",
3040+
);
3041+
let mut req = request.into_request();
3042+
req.extensions_mut()
3043+
.insert(
3044+
GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayOrPause"),
3045+
);
3046+
self.inner.unary(req, path, codec).await
3047+
}
30183048
pub async fn resume(
30193049
&mut self,
30203050
request: impl tonic::IntoRequest<super::ResumeRequest>,
@@ -3557,6 +3587,13 @@ pub mod playback_service_server {
35573587
&self,
35583588
request: tonic::Request<super::PauseRequest>,
35593589
) -> std::result::Result<tonic::Response<super::PauseResponse>, tonic::Status>;
3590+
async fn play_or_pause(
3591+
&self,
3592+
request: tonic::Request<super::PlayOrPauseRequest>,
3593+
) -> std::result::Result<
3594+
tonic::Response<super::PlayOrPauseResponse>,
3595+
tonic::Status,
3596+
>;
35603597
async fn resume(
35613598
&self,
35623599
request: tonic::Request<super::ResumeRequest>,
@@ -3871,6 +3908,51 @@ pub mod playback_service_server {
38713908
};
38723909
Box::pin(fut)
38733910
}
3911+
"/rockbox.v1alpha1.PlaybackService/PlayOrPause" => {
3912+
#[allow(non_camel_case_types)]
3913+
struct PlayOrPauseSvc<T: PlaybackService>(pub Arc<T>);
3914+
impl<
3915+
T: PlaybackService,
3916+
> tonic::server::UnaryService<super::PlayOrPauseRequest>
3917+
for PlayOrPauseSvc<T> {
3918+
type Response = super::PlayOrPauseResponse;
3919+
type Future = BoxFuture<
3920+
tonic::Response<Self::Response>,
3921+
tonic::Status,
3922+
>;
3923+
fn call(
3924+
&mut self,
3925+
request: tonic::Request<super::PlayOrPauseRequest>,
3926+
) -> Self::Future {
3927+
let inner = Arc::clone(&self.0);
3928+
let fut = async move {
3929+
<T as PlaybackService>::play_or_pause(&inner, request).await
3930+
};
3931+
Box::pin(fut)
3932+
}
3933+
}
3934+
let accept_compression_encodings = self.accept_compression_encodings;
3935+
let send_compression_encodings = self.send_compression_encodings;
3936+
let max_decoding_message_size = self.max_decoding_message_size;
3937+
let max_encoding_message_size = self.max_encoding_message_size;
3938+
let inner = self.inner.clone();
3939+
let fut = async move {
3940+
let method = PlayOrPauseSvc(inner);
3941+
let codec = tonic::codec::ProstCodec::default();
3942+
let mut grpc = tonic::server::Grpc::new(codec)
3943+
.apply_compression_config(
3944+
accept_compression_encodings,
3945+
send_compression_encodings,
3946+
)
3947+
.apply_max_message_size_config(
3948+
max_decoding_message_size,
3949+
max_encoding_message_size,
3950+
);
3951+
let res = grpc.unary(method, req).await;
3952+
Ok(res)
3953+
};
3954+
Box::pin(fut)
3955+
}
38743956
"/rockbox.v1alpha1.PlaybackService/Resume" => {
38753957
#[allow(non_camel_case_types)]
38763958
struct ResumeSvc<T: PlaybackService>(pub Arc<T>);
252 Bytes
Binary file not shown.

crates/rpc/src/playback.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,40 @@ impl PlaybackService for Playback {
6262
.map_err(|e| tonic::Status::internal(e.to_string()))?;
6363
Ok(tonic::Response::new(PauseResponse::default()))
6464
}
65+
66+
async fn play_or_pause(
67+
&self,
68+
_request: tonic::Request<PlayOrPauseRequest>,
69+
) -> Result<tonic::Response<PlayOrPauseResponse>, tonic::Status> {
70+
let client = reqwest::Client::new();
71+
let response = client
72+
.get(&format!("{}/player/status", rockbox_url()))
73+
.send()
74+
.await
75+
.map_err(|e| tonic::Status::internal(e.to_string()))?
76+
.json::<AudioStatus>()
77+
.await
78+
.map_err(|e| tonic::Status::internal(e.to_string()))?;
79+
80+
let client = reqwest::Client::new();
81+
match response.status {
82+
1 => {
83+
client
84+
.put(&format!("{}/player/pause", rockbox_url()))
85+
.send()
86+
.await
87+
.map_err(|e| tonic::Status::internal(e.to_string()))?;
88+
},
89+
_ => {
90+
client
91+
.put(&format!("{}/player/resume", rockbox_url()))
92+
.send()
93+
.await
94+
.map_err(|e| tonic::Status::internal(e.to_string()))?;
95+
}
96+
};
97+
Ok(tonic::Response::new(PlayOrPauseResponse::default()))
98+
}
6599

66100
async fn resume(
67101
&self,

dist/debian/amd64/DEBIAN/control

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: rockbox
2-
Version: 2025.01.26
2+
Version: 2025.01.27
33
Section: user/multimedia
44
Priority: optional
55
Architecture: amd64
66
Maintainer: Tsiry Sandratraina <tsiry.sndr@fluentci.io>
7-
Depends: libusb-dev, libsdl2-dev, libfreetype6-dev, libunwind-dev, alsa-utils, libasound2-dev
7+
Depends: libsdl2-dev, libfreetype6-dev, libunwind-dev, alsa-utils, libasound2-dev
88
Description: Rockbox open source high quality audio player

dist/debian/arm64/DEBIAN/control

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: rockbox
2-
Version: 2025.01.26
2+
Version: 2025.01.27
33
Section: user/multimedia
44
Priority: optional
55
Architecture: arm64
66
Maintainer: Tsiry Sandratraina <tsiry.sndr@fluentci.io>
7-
Depends: libusb-dev, libsdl2-dev, libfreetype6-dev, libunwind-dev, alsa-utils, libasound2-dev
7+
Depends: libsdl2-dev, libfreetype6-dev, libunwind-dev, alsa-utils, libasound2-dev
88
Description: Rockbox open source high quality audio player

0 commit comments

Comments
 (0)