[GH-ISSUE #107] [Linux] 'a2dp-sink' is called 'a2dp_sink' on Arch Linux #42

Open
opened 2026-03-02 12:02:54 +03:00 by kerem · 14 comments
Owner

Originally created by @jdholtz on GitHub (Apr 23, 2025).
Original GitHub issue: https://github.com/kavishdevar/librepods/issues/107

Hello, I recently discovered this project and really like it! I've built the new Linux app but I've been getting the following error when activating the A2DP profile:

Failure: No such entity
airpodsApp:  Failed to activate A2DP profile 

I noticed that this was because the pactl command to activate this profile uses a2dp-sink, whereas on Arch Linux, it is a2dp_sink. I'm not sure where exactly this discrepancy comes from.

I think a potential solution could be to try a2dp-sink, and then fallback to a2dp_sink if the first command fails. I can definitely submit a PR with whatever decision is decided as well.

Originally created by @jdholtz on GitHub (Apr 23, 2025). Original GitHub issue: https://github.com/kavishdevar/librepods/issues/107 Hello, I recently discovered this project and really like it! I've built the new Linux app but I've been getting the following error when activating the A2DP profile: ``` Failure: No such entity airpodsApp: Failed to activate A2DP profile ``` I noticed that this was because [the pactl command](https://github.com/kavishdevar/aln/blob/ed0de4d9fac7fd125f03b8acba26095af9baebb2/linux/mediacontroller.cpp#L196) to activate this profile uses `a2dp-sink`, whereas on Arch Linux, it is `a2dp_sink`. I'm not sure where exactly this discrepancy comes from. I think a potential solution could be to try `a2dp-sink`, and then fallback to `a2dp_sink` if the first command fails. I can definitely submit a PR with whatever decision is decided as well.
Author
Owner

@kavishdevar commented on GitHub (Apr 23, 2025):

Thanks for pointing it out! I remember in the early days when I was playing around with this on Arch and then switched my daily driver to Neon, I did encounter this. And, I just forgot about it.

I think finding the BlueZ device's name might be possible with D-Bus. I'll have a look if I get time. @tim-gromeyer if you have some idea on how to get the entity name, let me know!

<!-- gh-comment-id:2823648360 --> @kavishdevar commented on GitHub (Apr 23, 2025): Thanks for pointing it out! I remember in the early days when I was playing around with this on Arch and then switched my daily driver to Neon, I did encounter this. And, I just forgot about it. I think finding the BlueZ device's name might be possible with D-Bus. I'll have a look if I get time. @tim-gromeyer if you have some idea on how to get the entity name, let me know!
Author
Owner

@tim-gromeyer commented on GitHub (Apr 23, 2025):

Yes, I already got an idea and a concept implementation, but it will add dependencies for the pactl and pw-cli commands. Will test when I'm at home.

@jdholtz Just out of curiosity, does everything else work? Which airpods are you using?

<!-- gh-comment-id:2823896223 --> @tim-gromeyer commented on GitHub (Apr 23, 2025): Yes, I already got an idea and a concept implementation, but it will add dependencies for the pactl and pw-cli commands. Will test when I'm at home. @jdholtz Just out of curiosity, does everything else work? Which airpods are you using?
Author
Owner

@jdholtz commented on GitHub (Apr 23, 2025):

@jdholtz Just out of curiosity, does everything else work? Which airpods are you using?

Yes, everything else is working (ear detection, battery, connect/disconnect notifications). I'm using the AirPods 1st gen.

One small thing I noticed is that the MPRIS controls don't work when I'm pressing a modifier button (using i3wm). For example, double tapping while holding control, alt, win key. When I used mpris-proxy, this wasn't a problem. A very small problem though.

<!-- gh-comment-id:2825037105 --> @jdholtz commented on GitHub (Apr 23, 2025): > @jdholtz Just out of curiosity, does everything else work? Which airpods are you using? Yes, everything else is working (ear detection, battery, connect/disconnect notifications). I'm using the AirPods 1st gen. One small thing I noticed is that the MPRIS controls don't work when I'm pressing a modifier button (using i3wm). For example, double tapping while holding control, alt, win key. When I used mpris-proxy, this wasn't a problem. A very small problem though.
Author
Owner

@kavishdevar commented on GitHub (Apr 23, 2025):

I have had this problem as well. And I too just start mpris-proxy when I connect my airpods. My controls don't work at all otherwise, not only when pressing a modifier. iirc someone on reddit had suggested this.

maybe we can find the binary in PATH and start it when airpods are connected. I guess these are just normal Linux problems ¯\_(ツ)_/¯ I couldn't pair my airpods without setting the Bluetooth mode to dual or bredr.

<!-- gh-comment-id:2825043871 --> @kavishdevar commented on GitHub (Apr 23, 2025): I have had this problem as well. And I too just start mpris-proxy when I connect my airpods. My controls don't work at all otherwise, not only when pressing a modifier. iirc someone on reddit had suggested this. maybe we can find the binary in PATH and start it when airpods are connected. I guess these are just normal Linux problems ¯\\\_(ツ)_/¯ I couldn't pair my airpods without setting the Bluetooth mode to dual or bredr.
Author
Owner

@jdholtz commented on GitHub (Apr 23, 2025):

I have had this problem as well. And I too just start mpris-proxy when I connect my airpods. My controls don't work at all otherwise, not only when pressing a modifier.

Now I'm getting this issue as well where it doesn't work at all. There might be something deeper going on for me though because even when I run mpris-proxy, a double tap pauses the music but then it takes 3-5 more double taps to replay the music. dbus-monitor shows that 'Pause' is still being sent for those taps until the last one, which is 'Play'. With mpris-proxy, it does work reliably for me too.

maybe we can find the binary in PATH and start it when airpods are connected

Yeah, I think that would be a good solution. There is also a systemd service, maybe that would be helpful too.

<!-- gh-comment-id:2825286433 --> @jdholtz commented on GitHub (Apr 23, 2025): > I have had this problem as well. And I too just start mpris-proxy when I connect my airpods. My controls don't work at all otherwise, not only when pressing a modifier. Now I'm getting this issue as well where it doesn't work at all. ~~There might be something deeper going on for me though because even when I run mpris-proxy, a double tap pauses the music but then it takes 3-5 more double taps to replay the music. `dbus-monitor` shows that 'Pause' is still being sent for those taps until the last one, which is 'Play'.~~ With mpris-proxy, it does work reliably for me too. > maybe we can find the binary in PATH and start it when airpods are connected Yeah, I think that would be a good solution. There is also a systemd service, maybe that would be helpful too.
Author
Owner

@tim-gromeyer commented on GitHub (Apr 23, 2025):

Well for me mpris-proxy doesn't work at all.

BTW, can you test #108? It should fix this issue

<!-- gh-comment-id:2825330411 --> @tim-gromeyer commented on GitHub (Apr 23, 2025): Well for me `mpris-proxy` doesn't work at all. BTW, can you test #108? It should fix this issue
Author
Owner

@jdholtz commented on GitHub (Apr 23, 2025):

I've tested #108, but it seems to not find the device sink name at all

airpodsApp:  Both AirPods are out of ear 
airpodsApp:  Connected device MAC address or output name is empty, cannot remove audio output device 
airpodsApp:  Ear detection status:  "Primary: In Ear, Secondary: In case" 
airpodsApp:  Default sink:  "bluez_sink.XXX.a2dp_sink" 
airpodsApp:  Ear detection status: primaryInEar= true , secondaryInEar= false , isAirPodsActive= true 
airpodsApp:  At least one AirPod is in ear 
airpodsApp:  Connected device MAC address or output name is empty, cannot activate A2DP profile

Here's my pactl list sinks output for the a2dp_sink:

Sink #52
	State: SUSPENDED
	Name: bluez_sink.XXX.a2dp_sink
	Description: XXX
	Driver: module-bluez5-device.c
	Sample Specification: s16le 2ch 44100Hz
	Channel Map: front-left,front-right
	Owner Module: 51
	Mute: no
	Volume: front-left: 42315 /  65% / -11.40 dB,   front-right: 42315 /  65% / -11.40 dB
	       balance 0.00
	Base Volume: 65536 / 100% / 0.00 dB
	Monitor Source: bluez_sink.XXX.a2dp_sink.monitor
	Latency: 0 usec, configured 0 usec
	Flags: HARDWARE HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY 
	Properties:
		bluetooth.protocol = "a2dp_sink"
		bluetooth.codec = "sbc"
		device.description = "XXX"
		device.string = "XXX"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "headphone"
		bluez.path = "/org/bluez/hci0/dev_XXX"
		bluez.class = "XXX"
		bluez.alias = "XXX"
		device.icon_name = "audio-headphones-bluetooth"
	Ports:
		headphone-output: Headphone (type: Headphones, priority: 0, availability unknown)
        ...
<!-- gh-comment-id:2825440007 --> @jdholtz commented on GitHub (Apr 23, 2025): I've tested #108, but it seems to not find the device sink name at all ``` airpodsApp: Both AirPods are out of ear airpodsApp: Connected device MAC address or output name is empty, cannot remove audio output device airpodsApp: Ear detection status: "Primary: In Ear, Secondary: In case" airpodsApp: Default sink: "bluez_sink.XXX.a2dp_sink" airpodsApp: Ear detection status: primaryInEar= true , secondaryInEar= false , isAirPodsActive= true airpodsApp: At least one AirPod is in ear airpodsApp: Connected device MAC address or output name is empty, cannot activate A2DP profile ``` Here's my `pactl list sinks` output for the a2dp_sink: ``` Sink #52 State: SUSPENDED Name: bluez_sink.XXX.a2dp_sink Description: XXX Driver: module-bluez5-device.c Sample Specification: s16le 2ch 44100Hz Channel Map: front-left,front-right Owner Module: 51 Mute: no Volume: front-left: 42315 / 65% / -11.40 dB, front-right: 42315 / 65% / -11.40 dB balance 0.00 Base Volume: 65536 / 100% / 0.00 dB Monitor Source: bluez_sink.XXX.a2dp_sink.monitor Latency: 0 usec, configured 0 usec Flags: HARDWARE HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY Properties: bluetooth.protocol = "a2dp_sink" bluetooth.codec = "sbc" device.description = "XXX" device.string = "XXX" device.api = "bluez" device.class = "sound" device.bus = "bluetooth" device.form_factor = "headphone" bluez.path = "/org/bluez/hci0/dev_XXX" bluez.class = "XXX" bluez.alias = "XXX" device.icon_name = "audio-headphones-bluetooth" Ports: headphone-output: Headphone (type: Headphones, priority: 0, availability unknown) ... ```
Author
Owner

@tim-gromeyer commented on GitHub (Apr 23, 2025):

The app looks for the device.name attribute. Can you find it? Or find any other attribute which we can use to remove airpods as device (pactl set-card-profile <card name> off) (use a2dp-sink instead of off to turn on again)

<!-- gh-comment-id:2825465406 --> @tim-gromeyer commented on GitHub (Apr 23, 2025): The app looks for the `device.name` attribute. Can you find it? Or find any other attribute which we can use to remove airpods as device (`pactl set-card-profile <card name> off`) (use `a2dp-sink` instead of off to turn on again)
Author
Owner

@jdholtz commented on GitHub (Apr 23, 2025):

The app looks for the device.name attribute. Can you find it?

No, unfortunately I don't see that attribute or any other attribute that has a2dp-sink. The only place I can find a2dp* appear is when attached to my bluez_card/bluez_sink. Here's the output of pactl list cards. Maybe the profiles attribute for the bluez card can be parsed? To parse more easily, pactl --format=json can be used too.

Card #32
	Name: bluez_card.XXX
	Driver: module-bluez5-device.c
	Owner Module: 56
	Properties:
		device.description = "XXX"
		device.string = "XXX"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "headphone"
		bluez.path = "/org/bluez/hci0/dev_XXX"
		bluez.class = "0x240418"
		bluez.alias = "XXX"
		device.icon_name = "audio-headphones-bluetooth"
		bluetooth.codec = "sbc"
	Profiles:
		a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes)
		handsfree_head_unit: Handsfree Head Unit (HFP) (sinks: 1, sources: 1, priority: 30, available: yes)
		off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
	Active Profile: a2dp_sink
	Ports:
		headphone-output: Headphone (type: Headphones, priority: 0, latency offset: 0 usec, availability unknown)
			Part of profile(s): a2dp_sink, handsfree_head_unit
		headphone-input: Bluetooth Input (type: Bluetooth, priority: 0, latency offset: 0 usec, availability unknown)
			Part of profile(s): handsfree_head_unit
<!-- gh-comment-id:2825509673 --> @jdholtz commented on GitHub (Apr 23, 2025): > The app looks for the device.name attribute. Can you find it? No, unfortunately I don't see that attribute or any other attribute that has `a2dp-sink`. The only place I can find a2dp* appear is when attached to my bluez_card/bluez_sink. Here's the output of `pactl list cards`. Maybe the profiles attribute for the bluez card can be parsed? To parse more easily, `pactl --format=json` can be used too. ``` Card #32 Name: bluez_card.XXX Driver: module-bluez5-device.c Owner Module: 56 Properties: device.description = "XXX" device.string = "XXX" device.api = "bluez" device.class = "sound" device.bus = "bluetooth" device.form_factor = "headphone" bluez.path = "/org/bluez/hci0/dev_XXX" bluez.class = "0x240418" bluez.alias = "XXX" device.icon_name = "audio-headphones-bluetooth" bluetooth.codec = "sbc" Profiles: a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes) handsfree_head_unit: Handsfree Head Unit (HFP) (sinks: 1, sources: 1, priority: 30, available: yes) off: Off (sinks: 0, sources: 0, priority: 0, available: yes) Active Profile: a2dp_sink Ports: headphone-output: Headphone (type: Headphones, priority: 0, latency offset: 0 usec, availability unknown) Part of profile(s): a2dp_sink, handsfree_head_unit headphone-input: Bluetooth Input (type: Bluetooth, priority: 0, latency offset: 0 usec, availability unknown) Part of profile(s): handsfree_head_unit ```
Author
Owner

@kavishdevar commented on GitHub (Apr 24, 2025):

@jdholtz does pactl list short sinks | awk '$2 ~ /^bluez/ {print $2}' print the correct name?

<!-- gh-comment-id:2825970127 --> @kavishdevar commented on GitHub (Apr 24, 2025): @jdholtz does `pactl list short sinks | awk '$2 ~ /^bluez/ {print $2}'` print the correct name?
Author
Owner

@tim-gromeyer commented on GitHub (Apr 24, 2025):

You guys are definitely onto something. Will test when I'm home (~9hrs)

<!-- gh-comment-id:2826515936 --> @tim-gromeyer commented on GitHub (Apr 24, 2025): You guys are definitely onto something. Will test when I'm home (~9hrs)
Author
Owner

@jdholtz commented on GitHub (Apr 24, 2025):

@jdholtz does pactl list short sinks | awk '$2 ~ /^bluez/ {print $2}' print the correct name?

Yes, it outputs: bluez_sink.XX_XX_XX_XX_XX_XX.a2dp_sink. The only problem may be if I set this: pactl set-card-profile bluez_card.XX_XX_XX_XX_XX_XX handsfree_head_unit, the list command displays with handsfree_head_unit at the end. It's unclear to me how much of a problem this would be though, but potentially it could if the card doesn't default to a2dp_sink.

<!-- gh-comment-id:2826575041 --> @jdholtz commented on GitHub (Apr 24, 2025): > @jdholtz does pactl list short sinks | awk '$2 ~ /^bluez/ {print $2}' print the correct name? Yes, it outputs: `bluez_sink.XX_XX_XX_XX_XX_XX.a2dp_sink`. The only problem may be if I set this: `pactl set-card-profile bluez_card.XX_XX_XX_XX_XX_XX handsfree_head_unit`, the list command displays with `handsfree_head_unit` at the end. It's unclear to me how much of a problem this would be though, but potentially it could if the card doesn't default to `a2dp_sink`.
Author
Owner

@kavishdevar commented on GitHub (Apr 25, 2025):

Oh, I just remembered - we need the card name (we set card's profile), not the sink name. And, the card name is just bluez_card.XX_XX_XX_XX_XX_XX. So, defaulting to HS/FP should not be a problem.

<!-- gh-comment-id:2830829104 --> @kavishdevar commented on GitHub (Apr 25, 2025): Oh, I just remembered - we need the card name (we set card's profile), not the sink name. And, the card name is just `bluez_card.XX_XX_XX_XX_XX_XX`. So, defaulting to HS/FP should not be a problem.
Author
Owner

@jdholtz commented on GitHub (Apr 26, 2025):

On main, I am still getting the following error:

Failure: No such entity
airpodsApp:  Failed to activate A2DP profile

It correctly sets the device output, but it is still looking for a2dp-sink instead of a2dp_sink.

airpodsApp:  Device output name set to:  "bluez_card.XX_XX_XX_XX_XX_XX"

And it does work when changing the following

-                  << m_deviceOutputName << "a2dp-sink");
+                  << m_deviceOutputName << "a2dp_sink");
<!-- gh-comment-id:2831700287 --> @jdholtz commented on GitHub (Apr 26, 2025): On `main`, I am still getting the following error: ``` Failure: No such entity airpodsApp: Failed to activate A2DP profile ``` It correctly sets the device output, but it is still looking for `a2dp-sink` instead of `a2dp_sink`. ``` airpodsApp: Device output name set to: "bluez_card.XX_XX_XX_XX_XX_XX" ``` And it does work when changing the following ```diff - << m_deviceOutputName << "a2dp-sink"); + << m_deviceOutputName << "a2dp_sink"); ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/librepods#42
No description provided.