diff options
-rw-r--r-- | .SRCINFO | 2 | ||||
-rw-r--r-- | PKGBUILD | 4 | ||||
-rw-r--r-- | README.md | 15 | ||||
-rwxr-xr-x | fix-bt-a2dp.rb | 35 |
4 files changed, 45 insertions, 11 deletions
@@ -1,7 +1,7 @@ pkgbase = fix-bt-a2dp pkgdesc = Workaround fixing no A2DP when BT headphone reconnects automatically (after being paired) pkgver = 0.1 - pkgrel = 1 + pkgrel = 2 url = https://github.com/pastleo/fix-bt-a2dp arch = any license = MIT @@ -1,7 +1,7 @@ # Maintainer: PastLeo <chgu82837@gmail.com> pkgname=fix-bt-a2dp pkgver=0.1 -pkgrel=1 +pkgrel=2 pkgdesc="Workaround fixing no A2DP when BT headphone reconnects automatically (after being paired)" arch=('any') url="https://github.com/pastleo/fix-bt-a2dp" @@ -14,7 +14,7 @@ source=( 'fix-bt-a2dp.udev-rules' ) md5sums=( - 'f63057d641cb3c2e005653acdd6a4af9' + 'f762db18584951f49296c1231a46d9ec' '24aa8ecab3f87b3cd6f8a318d314b27d' '53997fa84224bae44cdd1c4b5f88550f' ) diff --git a/README.md b/README.md index 96fa1ef95383..03f3a3991227 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ Workaround fixing no A2DP when BT headphone reconnects automatically (after bein On my ArchLinux KDE plasma setup, BT headphone will use A2DP only when connected by pairing; after disconnect and reconnect, only HSP/HFP is available +> According to https://github.com/EHfive/pulseaudio-modules-bt/issues/14#issuecomment-462039332, this should soon become unnecessary + this workaround deploys a [`udev-rules`](https://wiki.archlinux.org/index.php/udev) to detect changes of BT dev and [`systemctl start fix-bt-a2dp`](https://wiki.archlinux.org/index.php/systemd) to call `fix-bt-a2dp.rb` in background with correct user > basically a rewrite from https://gist.github.com/EHfive/c4f1218a75f95b076f0387403246de78, mainly because I want to avoid slowing down connecting of other BT devs @@ -20,3 +22,16 @@ run this command with root to set GUI session owner: ``` /usr/bin/fix-bt-a2dp set-user [user] ``` + +## When used with `pulseaudio-modules-bt` + +recently [pulseaudio-modules-bt](https://github.com/EHfive/pulseaudio-modules-bt) has added codec name after `a2dp_sink` profile, and `pacmd list-cards` tells that my MDR-1ABT only supports AptX...so I finally came up with a solution by telling `fix-bt-a2dp` what profile should be used for a device manually...(so `fix-bt-a2dp` will set card profile to what you assigned when connected) + +```shell +bluetoothctl devices +# => Device 10:4F:A8:CE:DB:D2 MDR-1ABT +fix-bt-a2dp set-device-profile MDR-1ABT a2dp_sink_ldac +# currently known profiles are +# a2dp_sink_sbc a2dp_sink_aac a2dp_sink_aptx a2dp_sink_aptx_hd a2dp_sink_ldac +``` + diff --git a/fix-bt-a2dp.rb b/fix-bt-a2dp.rb index cd049f6f4315..c5991800ae8c 100755 --- a/fix-bt-a2dp.rb +++ b/fix-bt-a2dp.rb @@ -2,6 +2,7 @@ RUNNING_FILE = '/tmp/.fix-bt-a2dp.running' USER_FILE = '/etc/.fix-bt-a2dp.user' +DEVICE_PROFILE_FILE = '/etc/.fix-bt-a2dp.device-profiles' ROOT_UID = 0 if system("which notify-send &> /dev/null") @@ -23,6 +24,11 @@ def command_failed(name, stdout) end end +DEVICE_PROFILE_MAPPING = + File.exist?(DEVICE_PROFILE_FILE) ? Hash[ + File.read(DEVICE_PROFILE_FILE).lines.map {|l| l.split('=') } + ] : {} + def bluetoothctl_info_value(v) return true if v.downcase == 'yes' return false if v.downcase == 'no' @@ -39,7 +45,7 @@ def bluetoothctl_info(mac) k end.map do |k, v| if v.count == 1 - [k, bluetoothctl_info_value(v[0][1])] + [k, bluetoothctl_info_value(v[0][1].to_s)] else [k, v.map {|vv| vv[1]}] end @@ -50,7 +56,7 @@ end def have_audio_sink?(uuid_values) uuid_value = uuid_values.kind_of?(Array) ? uuid_values.join : uuid_values - uuid_value.downcase.gsub(' ', '').include?("audiosink") + uuid_value.to_s.downcase.gsub(' ', '').include?("audiosink") end def enable_a2dp(name, mac, bluez_mac, info) @@ -64,14 +70,15 @@ def enable_a2dp(name, mac, bluez_mac, info) sleep 1 - puts ">> pacmd set-card-profile bluez_card.#{bluez_mac} a2dp_sink" - set_card_profile_out = `pacmd set-card-profile bluez_card.#{bluez_mac} a2dp_sink` + profile_name = DEVICE_PROFILE_MAPPING[name] || 'a2dp_sink' + puts ">> pacmd set-card-profile bluez_card.#{bluez_mac} #{profile_name}" + set_card_profile_out = `pacmd set-card-profile bluez_card.#{bluez_mac} #{profile_name}` unless $?.success? && set_card_profile_out == '' command_failed('pacmd set-card-profile', set_card_profile_out) end puts "a2dp enabled for #{name}!" - gui_notify("#{name} connected and set to A2DP") + gui_notify("#{name} connected and set to #{profile_name}") end def scan_enable_a2dp @@ -82,8 +89,8 @@ def scan_enable_a2dp command_failed('`pacmd list-sinks`', pacmd_sinks) unless $?.success? bt_sinks_no_a2dp = bt_devs.lines.map do |bt_dev_line| - bt_dev_line.split(' ') - end.map do |_, mac, name| + /^(\S+)\s(\S+)\s(.+)$/.match(bt_dev_line).to_a.drop(2) + end.map do |mac, name| [name, mac, "#{mac.gsub(':', '_')}", bluetoothctl_info(mac)] end.keep_if do |name, mac, bluez_mac, info| !info.empty? && @@ -132,7 +139,19 @@ def main end if Process.uid == ROOT_UID - if ARGV[0] == 'set-user' + if ARGV[0] == 'set-device-profile' + `rm -f #{DEVICE_PROFILE_FILE}` + name = ARGV[1] + profile = ARGV[2] + File.open(DEVICE_PROFILE_FILE, 'w') do |f| + f.write( + DEVICE_PROFILE_MAPPING + .merge(name => profile) + .to_a.map {|kv| kv.join('=')}.join("\n") + ) + end + exit 0 + elsif ARGV[0] == 'set-user' `rm -f #{USER_FILE}` user = ARGV[1].strip uid = `id -u #{user}`.strip |