cfangmeier / tuijam

A fancy TUI client for Google Play Music
MIT License
129 stars 9 forks source link

Can't control with bluetooth AVRCP controls via mpris-proxy #55

Closed nickclyde closed 4 years ago

nickclyde commented 4 years ago

Hello, thanks for writing this awesome TUI player, I use it everyday while I work and am super appreciative of your work!

Just wanted to log an issue I came across while playing with my new bluetooth headphones. According to the Arch wiki, bluetooth device AVRCP controls can be forwarded to players via MPRIS using the mpris-proxy tool included in bluez-utils. However, when I run mpris-proxy, I'm getting the following message:

org.bluez appeared
Bluetooth Adapter /org/bluez/hci0 found
player org.mpris.MediaPlayer2.tuijam at :1.68646 found
Can't register player
Operation is not supported
Bluetooth Transport /org/bluez/hci0/dev_38_18_4C_10_57_8C/sep1/fd0 found  <-- this is my headset connecting

Digging through the source of mpris-proxy led me to believe that something with the RegisterPlayer message is off and causing bluez to fail to register the player here. I also found this commit to another project that might hold a clue to the solution. But for all I can tell from reading the MPRIS spec, nothing really seems to be missing.

Obviously this is just a quality of life improvement and not a huge issue, but was curious if anyone knew how to solve this.

If it helps, here is the output of busctl while monitoring mpris-proxy:

‣ Type=method_call  Endian=l  Flags=0  Version=1  Priority=0 Cookie=57
  Sender=:1.17312  Destination=org.bluez  Path=/org/bluez/hci0  Interface=org.bluez.Media1  Member=RegisterPlayer
  UniqueName=:1.17312
  MESSAGE "oa{sv}" {
          OBJECT_PATH "/_1_10513";
          ARRAY "{sv}" {
                  DICT_ENTRY "sv" {
                          STRING "PlaybackStatus";
                          VARIANT "s" {
                                  STRING "Stopped";
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "Rate";
                          VARIANT "d" {
                                  DOUBLE 1;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "Metadata";
                          VARIANT "a{sv}" {
                                  ARRAY "{sv}" {
                                  };
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "Volume";
                          VARIANT "d" {
                                  DOUBLE 1;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "Position";
                          VARIANT "x" {
                                  INT64 0;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "MinimumRate";
                          VARIANT "d" {
                                  DOUBLE 1;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "MaximumRate";
                          VARIANT "d" {
                                  DOUBLE 1;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "CanGoNext";
                          VARIANT "b" {
                                  BOOLEAN true;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "CanGoPrevious";
                          VARIANT "b" {
                                  BOOLEAN true;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "CanPlay";
                          VARIANT "b" {
                                  BOOLEAN true;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "CanPause";
                          VARIANT "b" {
                                  BOOLEAN false;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "CanSeek";
                          VARIANT "b" {
                                  BOOLEAN false;
                          };
                  };
                  DICT_ENTRY "sv" {
                          STRING "CanControl";
                          VARIANT "b" {
                                  BOOLEAN true;
                          };
                  };
          };
  };

‣ Type=error  Endian=l  Flags=1  Version=1  Priority=0 Cookie=6076  ReplyCookie=57
  Sender=:1.12  Destination=:1.17312
  ErrorName=org.bluez.Error.NotSupported  ErrorMessage="Operation is not supported"
  UniqueName=:1.12
  MESSAGE "s" {
          STRING "Operation is not supported";
  };
cfangmeier commented 4 years ago

Hi @ClydeDroid! Thanks for reporting this and for the already quite detailed investigation.

Looking at the commit you linked, it appears that TUIJam may just be missing the org.bluez.Media1 endpoint that is described by:

    <interface name="org.bluez.Media1">
        <method name="RegisterEndpoint"><arg name="endpoint" type="o" direction="in"/>
            <arg name="properties" type="a{sv}" direction="in"/>
        </method>
        <method name="UnregisterEndpoint"><arg name="endpoint" type="o" direction="in"/>
        </method>
        <method name="RegisterPlayer"><arg name="player" type="o" direction="in"/>
            <arg name="properties" type="a{sv}" direction="in"/>
        </method>
        <method name="UnregisterPlayer"><arg name="player" type="o" direction="in"/>
        </method>
    </interface>

I'll have some time this evening to dig into this a bit more. Hopefully I can get something for you to test over the next couple days.

nickclyde commented 4 years ago

Ahh, excellent! Glad I was able to help, and I'm happy to help test out as well. Thanks for looking into it!

cfangmeier commented 4 years ago

I was able to play around with this with a set of bluetooth headphones I have and made a few observations.

First, with no modifications from the latest release of TUIJam, mpris-proxy doesn't complain about being able to register the player.

> $ mpris-proxy
org.bluez appeared
Bluetooth Adapter /org/bluez/hci0 found
player org.mpris.MediaPlayer2.tuijam at :1.782 found
Bluetooth Transport /org/bluez/hci0/dev_00_25_BB_01_10_57/sep1/fd3 found

My headset has a play/pause button and two volume control buttons. The play/pause button seems to do nothing and while the volume control buttons audibly change the volume of the playback, this isn't reflected in either the TUIJam volume control or my GNOME system volume.

Second, I added the org.bluez.Media1 interface to TUIJam and tested again. Doing this seems to have no effect on the behavior previously observed. I then used d-feet to compare the D-bus interface that TUIJam is producing with the Gnome music player (which does seem to work fine with mpris-proxy). I found that there were a few properties from the spec that TUIJam didn't implement. I added them, and now at least the play button works on my headset.

Can you try checking out the latest version and see how it behaves on your system?

nickclyde commented 4 years ago

Okay, so this is weird. I installed tuijam-git from AUR instead of tuijam to pick up the latest changes, rebooted, even confirmed by looking at the installed mpris.py file, but there doesn't seem to be any change, still getting the same output from mpris-proxy:

❯ mpris-proxy
org.bluez appeared
Bluetooth Adapter /org/bluez/hci0 found
Bluetooth Transport /org/bluez/hci0/dev_38_18_4C_10_57_8C/sep1/fd0 found
player org.mpris.MediaPlayer2.tuijam at :1.1836 found
Can't register player
Operation is not supported

And the output of busctl monitor mpris-proxy is the same as before as well...

Really bizarre, as it seems to have made a difference on your end

cfangmeier commented 4 years ago

Given that even the previous version behaved differently on our systems, I'm not too surprised. The "Operation" in "Operation not supported" may be some capability that your bluetooth device requires that mine doesn't. Maybe it would help to know what what model of bluetooth device you are using. I'm testing with a Tautronics Soundelite 72. Also, does your device work with other players (Eg Gnome music, VLC, or similar)?

nickclyde commented 4 years ago

Ahhh, I see. I have a pair of Sony WH-CH700N wireless headphones, as well as an Insignia NS-HSB318 soundbar, which both exhibit the same behavior. I just tried VLC, with no luck:

❯ mpris-proxy
org.bluez appeared
Bluetooth Adapter /org/bluez/hci0 found
player org.mpris.MediaPlayer2.vlc at :1.5886 found
Can't register player
Operation is not supported
Bluetooth Transport /org/bluez/hci0/dev_38_18_4C_10_57_8C/sep1/fd2 found
cfangmeier commented 4 years ago

Interesting. Then I guess this isn't a TUIJam-specific problem, but it's interesting that you see the issue across different hardware as well. My best guess is that there is some configuration on your system that isn't quite right... What desktop env are you using? I'm running Gnome which maybe installs something that is critical for this to work.

nickclyde commented 4 years ago

Yeah, that's possible. I'm just using i3, no desktop env, so I'm probably missing a package. I'll do some digging to see if I can find something

nickclyde commented 4 years ago

Found a post on the Arch forums with a similar issue: https://bbs.archlinux.org/viewtopic.php?pid=1884292

Anyways, definitely seems like it's not a tuijam issue. Thanks anyways for helping me dig @cfangmeier!!