11use mpris:: { Metadata , PlaybackStatus , Player , PlayerFinder } ;
2+ use playerctld:: PlayerctldProxyBlocking ;
3+ use zbus:: blocking:: Connection ;
24
35use super :: config:: user:: ServerConfig ;
4- use crate :: utils:: get_player;
6+ use crate :: utils:: get_player as get_player_raw ;
57use std:: { error:: Error , sync:: Arc , thread:: sleep, time:: Duration } ;
68use PlaybackStatus :: * ;
79use PlayerctlAction :: * ;
@@ -21,6 +23,8 @@ pub enum PlayerctlDeviceRaw {
2123 None ,
2224 All ,
2325 Some ( String ) ,
26+ Shift ,
27+ Unshift ,
2428}
2529
2630pub enum PlayerctlDevice {
@@ -36,27 +40,54 @@ pub struct Playerctl {
3640 fmt_str : Option < String > ,
3741}
3842
43+ fn get_player ( player : PlayerctlDeviceRaw ) -> Result < PlayerctlDevice , Box < dyn Error > > {
44+ fn get_playerctld < ' a > ( ) -> Result < PlayerctldProxyBlocking < ' a > , Box < dyn Error > > {
45+ Ok ( PlayerctldProxyBlocking :: new ( & Connection :: session ( ) ?) ?)
46+ }
47+
48+ fn get_playerctld_devices ( ) -> Result < Vec < String > , Box < dyn Error > > {
49+ Ok ( get_playerctld ( ) ?. player_names ( ) ?)
50+ }
51+
52+ fn get_single_player ( player : String ) -> Result < PlayerctlDevice , Box < dyn Error > > {
53+ let possible_player = PlayerFinder :: new ( ) ?. find_all ( ) ?. into_iter ( ) . find ( |p| {
54+ let bus = p. bus_name ( ) ;
55+ bus. contains ( & player)
56+ } ) ;
57+ match possible_player {
58+ Some ( player) => Ok ( PlayerctlDevice :: Some ( player) ) ,
59+ None => Err ( From :: from ( mpris:: FindingError :: NoPlayerFound ) ) ,
60+ }
61+ }
62+
63+ match player {
64+ PlayerctlDeviceRaw :: None => {
65+ let fallback = || -> Result < PlayerctlDevice , Box < dyn Error > > {
66+ Ok ( PlayerctlDevice :: Some ( PlayerFinder :: new ( ) ?. find_active ( ) ?) )
67+ } ;
68+ let Ok ( players) = get_playerctld_devices ( ) else {
69+ return fallback ( ) ;
70+ } ;
71+ let Some ( player) = players. first ( ) else {
72+ return fallback ( ) ;
73+ } ;
74+ get_single_player ( player. to_string ( ) )
75+ }
76+ PlayerctlDeviceRaw :: Some ( name) => get_single_player ( name) ,
77+ PlayerctlDeviceRaw :: All => Ok ( PlayerctlDevice :: All ( PlayerFinder :: new ( ) ?. find_all ( ) ?) ) ,
78+
79+ PlayerctlDeviceRaw :: Shift => get_single_player ( get_playerctld ( ) ?. shift ( ) ?) ,
80+ PlayerctlDeviceRaw :: Unshift => get_single_player ( get_playerctld ( ) ?. unshift ( ) ?) ,
81+ }
82+ }
83+
3984impl Playerctl {
4085 pub fn new (
4186 action : PlayerctlAction ,
4287 config : Arc < ServerConfig > ,
4388 ) -> Result < Playerctl , Box < dyn Error > > {
44- let playerfinder = PlayerFinder :: new ( ) ?;
45- let player = get_player ( ) ;
46- let player = match player {
47- PlayerctlDeviceRaw :: None => PlayerctlDevice :: Some ( playerfinder. find_active ( ) ?) ,
48- PlayerctlDeviceRaw :: Some ( name) => {
49- let possible_player = playerfinder. find_all ( ) ?. into_iter ( ) . find ( |p| {
50- let bus = p. bus_name ( ) ;
51- bus. strip_prefix ( "org.mpris.MediaPlayer2." ) . unwrap_or ( bus) == name
52- } ) ;
53- match possible_player {
54- Some ( player) => PlayerctlDevice :: Some ( player) ,
55- None => return Err ( From :: from ( mpris:: FindingError :: NoPlayerFound ) ) ,
56- }
57- }
58- PlayerctlDeviceRaw :: All => PlayerctlDevice :: All ( playerfinder. find_all ( ) ?) ,
59- } ;
89+ let player = get_player_raw ( ) ;
90+ let player = get_player ( player) ?;
6091 let fmt_str = config. playerctl_format . clone ( ) ;
6192 Ok ( Self {
6293 player,
@@ -230,6 +261,8 @@ impl PlayerctlDeviceRaw {
230261 match player. as_str ( ) {
231262 "auto" | "" => Ok ( None ) ,
232263 "all" => Ok ( All ) ,
264+ "shift" => Ok ( Shift ) ,
265+ "unshift" => Ok ( Unshift ) ,
233266 _ => Ok ( Some ( player) ) ,
234267 }
235268 }
0 commit comments