우선, 나는 다음 두 가지를 모두 시도했습니다 : https://vilimpoc.org/blog/2016/04/30/ubuntu-16-04-bluetooth-speakers/ 및 PulseAudio는 블루투스 모듈 15.10 / 16.04 / 16.10을로드 할 수 없습니다
Jaybird X2 (데스크톱 및 랩톱, Broadcom 및 인텔 모두에서 시도)를 연결하려고하면 2 초 동안 연결 한 다음 연결이 끊어집니다.
syslog 양식 기록 (widecom BT가있는 데스크탑에서)
May 31 23:50:54 desktop pulseaudio[6247]: [pulseaudio] socket-server.c: bind(): Address already in use
May 31 23:50:54 desktop pulseaudio[6247]: [pulseaudio] module.c: Failed to load module "module-cli-protocol-unix" (argument: ""): initialization failed.
May 31 23:50:54 desktop pulseaudio[6247]: [pulseaudio] socket-server.c: bind(): Address already in use
May 31 23:50:54 desktop pulseaudio[6247]: [pulseaudio] module.c: Failed to load module "module-cli-protocol-unix" (argument: ""): initialization failed.
그리고 다른 시간 :
a2dp-sink profile connect failed for xxxxxxx Protocol not available
편집 .. 중요 :
이제 다른 장치에 연결하려고하면 대부분 잘 작동합니다 (Micropod BT 및 Samsung AirTrack). 그러나 Jaybird X2를 사용 하자마자 모듈-블루투스 감지를 비활성화 / 언로드pactl load-module module-bluetooth-discover
합니다. 다른 두 개는 다시 작동합니다 ..
이제 이것은 노트북에서 발생합니다.
May 31 17:02:58 vooze-x1 pulseaudio[3534]: [pulseaudio] backend-native.c: connect(): Function not implemented
May 31 17:02:58 vooze-x1 pulseaudio[3534]: [pulseaudio] volume.c: Assertion 'pa_channels_valid(channels)' failed at pulse/volume.c:74, function pa_cvolume_set(). Aborting.
May 31 17:02:58 vooze-x1 bluetoothd[865]: Endpoint unregistered: sender=:1.130 path=/MediaEndpoint/A2DPSource
May 31 17:02:58 vooze-x1 bluetoothd[865]: Endpoint unregistered: sender=:1.130 path=/MediaEndpoint/A2DPSink
May 31 17:03:00 vooze-x1 pulseaudio[3764]: [pulseaudio] main.c: User-configured server at {ddcf951d58914c47b9adca0056c50142}unix:/run/user/1000/pulse/native, which appears to be local. Probing deeper.
May 31 17:03:00 vooze-x1 pulseaudio[3767]: [pulseaudio] pid.c: Stale PID file, overwriting.
이전에 데스크톱에서 간단히 연결할 수 있었지만 A2DP는 대부분 작동하지 않았습니다.
서로 다른 두 가지 오류가 있지만 동일한 문제 무슨 일이야?
우분투 16.04에서 블루투스가 고장 났습니까? 그것은 Windows와 내 안드로이드 폰에서 작동합니다.
어떤 도움이라도 좋을 것입니다! 🙂 어떻게 든 간단하게 작동 시켜서 처음에는 효과가 있었고 A2DP는 작동하지 않았습니다. 그래서 이것이 A2DP와 관련이 있다고 생각합니다. 확실하지 않다.
답변
알려진 버그입니다. 시도하십시오 rmmod btusb ; modprobe btusb
. 나는 그것을 4 번까지해야했다.
Intel 8260 wifi / bluetooth가 장착 된 Lenovo P50에서이를 확인했습니다. 때때로 부팅시 블루투스 펌웨어가 올바르게로드되지 않습니다. 다른 경우에는 작동하지 않습니다.
답변
다른 Bluetooth 오디오 장치가 문제없이 작동했지만 Jaybird X2 및 Bluebuds X와 동일한 문제가있었습니다. 헤드폰으로 다음과 같은 오류가 발생했습니다.
Assertion 'pa_channels_valid(channels)' failed at pulse/volume.c:74, function pa_cvolume_set(). Aborting.
펄스 오디오가 추락했습니다. 그것을 해결 한 것은 소스에서 펄스 오디오를 설치하는 것이 었습니다.
- 필요한 모든 패키지를 설치하십시오.
sudo apt-get build-dep pulseaudio
- https://freedesktop.org/software/pulseaudio/releases/pulseaudio-9.0.tar.gz를 다운로드 하고 압축을 풉니 다.
- 소스 디렉토리에서 다음을 실행하십시오
./bootstrap.sh --prefix=/usr
.. 원하는 경우CFLAGS
컴파일러 최적화를 사용 하도록 변수를 변경할 수 있습니다 ( 예 :-O2
대신 사용)-O0
. - 그런 다음,
make
및sudo make install
기본 시스템 설치를 덮어 쓰지만 패키지가 업데이트 될 때까지 작동합니다. 업데이트를 방지하기 위해 pulseaudio 패키지를 보류시킬 수 있습니다.
sudo apt-mark hold libpulse-dev libpulse0 libpulse-mainloop-glib0 pulseaudio pulseaudio-module-bluetooth pulseaudio-utils libpulsedsp pulseaudio-module-x11
참고 내가 펄스 오디오 9.0을 설치했지만 작동 만든 버전이 아닌 것을. PPA 에서 패키지 버전의 pulseaudio 9.0을 사용해 보았지만 동일한 오류가 발생했습니다.
답변
Bluedio T + 3 헤드셋에서이 문제가 발생했으며 연결 시간이 초과되었다고 생각합니다. 세미콜론 (;)을 제거하여 ; exit-idle-time = 20
파일 에서 행의 주석을 해제해야합니다 /etc/pulse/daemon.conf
.
값을 다음 -1
과 같이 변경하십시오 .
exit-idle-time = -1
그런 다음 bluetoothctl
다시 사용 하여 장치에 연결하십시오. 지침은 여기를 참조하십시오.
답변
다음을 확인하십시오.
- Jaybird X2가 페어링되었습니다
- 신뢰할 수있는 것으로 표시됩니다 (via
bluetoothctl
및trust XX:XX:XX:XX
(여기서XX:XX:XX:XX
Jaybird의 MAC 주소) 또는를 통해blueman-manager
) - 켜져있다
Jaybird X2의 전원 버튼을 한 번 누르십시오. 이것은 알려진 장치에 대한 자동 연결을 트리거합니다. 따라서 다른 장치가 여기에 방해가되지 않도록해야합니다. 그때부터 연결이 안정적이었고 재부팅 후 자동으로 연결됩니다.
이 방법으로도 문제가 해결되었는지 알려주십시오. 나는 실수로 전원 버튼을 눌렀을 때 다른 일을 많이하고 거의 포기했습니다. 😉 그래서 다른 것들 중 하나가 문제를 해결했을 수도 있습니다. (이미 블루투스, pulseaudio, bluez, pactl load-module 주위에서 이미 검색하고 시도하고 있었으므로 여전히 많은 힌트가 있습니다 :-D)
업데이트 (연결 문제가 다시 발생한 후)
Jaybird X2를 안드로이드 폰에 연결 한 후, 안드로이드 폰에서 연결을 끊은 후에도 랩톱에 다시 연결할 수 없었습니다. 아직 문제가 무엇인지 모르지만 연결을 다시 얻으려면 다음을 수행해야했습니다.
- 내 안드로이드 폰 (또는 다른 기기)에서 Jaybird X2 연결 해제
- 우분투 재부팅
- 다시 연결이 작동하고 연결이 안정적입니다 (일반적으로 처음 페어링 할 때 작동하지 않았습니다 … 그 후에도 재부팅해야 함)
나는 또한 다른 것들을 시도했고 적어도 pulseaudio-module-bluetooth
요구되는 것처럼 보입니다 . 또한 wifi / bluetooth 공존 구성은 적어도 내 컴퓨터에 필요합니다 ( /ubuntu//a/645072/558838 참조 ). 그리고 마지막으로 : 다른 장치로 전환 한 경우 항상 연결을 다시 시작하려면 재부팅해야합니다.
요약하면, 재부팅 단계를 통해 Jaybird X2를 성공적으로 다시 연결할 수 있으며 연결이 안정적입니다. 누구든지 재부팅 단계를 생략하는 더 쉬운 방법을 알고 있다면 /etc/init.d/bluetooth restart
충분합니다 🙂 기여
하지 마십시오.
(내가 시도한 추가 단계) :
나는 내 역사를 조사했다. 또한 하나 또는 다른 하나가 위의 솔루션에 기여했을 수있는 다음을 시도했습니다.
apt-get install pulseaudio-module-bluetooth
(내 시스템에는 설치되지 않았습니다)- 로그는 missing
ofono
에 대해 언급 했으므로 설치했습니다. - 했다
sudo chown -R $USER ~/*
- 또한 적용 : /ubuntu//a/691299/558838 (그러나 도움이되지 않아 되돌 렸지만 자동 연결을 시도했을 때 여전히 활성화되었을 수 있습니다)
- 또한 pulseaudio, blueman, bluetooth packag를 제거 / 설치했습니다
답변
GitHub에서 스크립트를 실행하십시오 .
그리고 문제는 사라질 것입니다.
#! /usr/bin/env python3.5
"""
Fixing bluetooth stereo headphone/headset problem in ubuntu 16.04 and also debian jessie, with bluez5.
Workaround for bug: https://bugs.launchpad.net/ubuntu/+source/indicator-sound/+bug/1577197
Run it with python3.5 or higher after pairing/connecting the bluetooth stereo headphone.
This will be only fixes the bluez5 problem mentioned above .
Licence: Freeware
See ``python3.5 a2dp.py -h``.
Shorthands:
$ alias speakers="a2dp.py 10:08:C1:44:AE:BC"
$ alias headphones="a2dp.py 00:22:37:3D:DA:50"
$ alias headset="a2dp.py 00:22:37:F8:A0:77 -p hsp"
$ speakers
Check here for the latest updates: https://gist.github.com/pylover/d68be364adac5f946887b85e6ed6e7ae
Thanks to:
* https://github.com/DominicWatson, for adding the ``-p/--profile`` argument.
* https://github.com/IzzySoft, for mentioning wait before connecting again.
* https://github.com/AmploDev, for v0.4.0
Change Log
----------
- 0.4.1
* Sorting device list
- 0.4.0
* Adding ignore_fail argument by @AmploDev.
* Sending all available streams into selected sink, after successfull connection by @AmploDev.
- 0.3.3
* Updating default sink before turning to ``off`` profile.
- 0.3.2
* Waiting a bit: ``-w/--wait`` before connecting again.
- 0.3.0
* Adding -p / --profile option for using the same script to switch between headset and A2DP audio profiles
- 0.2.5
* Mentioning [mac] argument.
- 0.2.4
* Removing duplicated devices in select device list.
- 0.2.3
* Matching ANSI escape characters. Tested on 16.10 & 16.04
- 0.2.2
* Some sort of code enhancements.
- 0.2.0
* Adding `-V/--version`, `-w/--wait` and `-t/--tries` CLI arguments.
- 0.1.1
* Supporting the `[NEW]` prefix for devices & controllers as advised by @wdullaer
* Drying the code.
"""
import sys
import re
import asyncio
import subprocess as sb
import argparse
__version__ = '0.4.0'
HEX_DIGIT_PATTERN = '[0-9A-F]'
HEX_BYTE_PATTERN = '%s{2}' % HEX_DIGIT_PATTERN
MAC_ADDRESS_PATTERN = ':'.join((HEX_BYTE_PATTERN, ) * 6)
DEVICE_PATTERN = re.compile('^(?:.*\s)?Device\s(?P<mac>%s)\s(?P<name>.*)' % MAC_ADDRESS_PATTERN)
CONTROLLER_PATTERN = re.compile('^(?:.*\s)?Controller\s(?P<mac>%s)\s(?P<name>.*)' % MAC_ADDRESS_PATTERN)
WAIT_TIME = .75
TRIES = 4
PROFILE = 'a2dp'
_profiles = {
'a2dp': 'a2dp_sink',
'hsp': 'headset_head_unit',
'off': 'off'
}
# CLI Arguments
parser = argparse.ArgumentParser(prog=sys.argv[0])
parser.add_argument('-e', '--echo', action='store_true', default=False,
help='If given, the subprocess stdout will be also printed on stdout.')
parser.add_argument('-w', '--wait', default=WAIT_TIME, type=float,
help='The seconds to wait for subprocess output, default is: %s' % WAIT_TIME)
parser.add_argument('-t', '--tries', default=TRIES, type=int,
help='The number of tries if subprocess is failed. default is: %s' % TRIES)
parser.add_argument('-p', '--profile', default=PROFILE,
help='The profile to switch to. available options are: hsp, a2dp. default is: %s' % PROFILE)
parser.add_argument('-V', '--version', action='store_true', help='Show the version.')
parser.add_argument('mac', nargs='?', default=None)
# Exceptions
class SubprocessError(Exception):
pass
class RetryExceededError(Exception):
pass
class BluetoothctlProtocol(asyncio.SubprocessProtocol):
def __init__(self, exit_future, echo=True):
self.exit_future = exit_future
self.transport = None
self.output = None
self.echo = echo
def listen_output(self):
self.output = ''
def not_listen_output(self):
self.output = None
def pipe_data_received(self, fd, raw):
d = raw.decode()
if self.echo:
print(d, end='')
if self.output is not None:
self.output += d
def process_exited(self):
self.exit_future.set_result(True)
def connection_made(self, transport):
self.transport = transport
print('Connection MADE')
async def send_command(self, c):
stdin_transport = self.transport.get_pipe_transport(0)
# noinspection PyProtectedMember
stdin_transport._pipe.write(('%s\n' % c).encode())
async def search_in_output(self, expression, fail_expression=None):
if self.output is None:
return None
for l in self.output.splitlines():
if fail_expression and re.search(fail_expression, l, re.IGNORECASE):
raise SubprocessError('Expression "%s" failed with fail pattern: "%s"' % (l, fail_expression))
if re.search(expression, l, re.IGNORECASE):
return True
async def send_and_wait(self, cmd, wait_expression, fail_expression='fail'):
try:
self.listen_output()
await self.send_command(cmd)
while not await self.search_in_output(wait_expression.lower(), fail_expression=fail_expression):
await wait()
finally:
self.not_listen_output()
async def disconnect(self, mac):
print('Disconnecting the device.')
await self.send_and_wait('disconnect %s' % ':'.join(mac), 'Successful disconnected')
async def connect(self, mac):
print('Connecting again.')
await self.send_and_wait('connect %s' % ':'.join(mac), 'Connection successful')
async def trust(self, mac):
await self.send_and_wait('trust %s' % ':'.join(mac), 'trust succeeded')
async def quit(self):
await self.send_command('quit')
async def get_list(self, command, pattern):
result = set()
try:
self.listen_output()
await self.send_command(command)
await wait()
for l in self.output.splitlines():
m = pattern.match(l)
if m:
result.add(m.groups())
return sorted(list(result), key=lambda i: i[1])
finally:
self.not_listen_output()
async def list_devices(self):
return await self.get_list('devices', DEVICE_PATTERN)
async def list_paired_devices(self):
return await self.get_list('paired-devices', DEVICE_PATTERN)
async def list_controllers(self):
return await self.get_list('list', CONTROLLER_PATTERN)
async def select_paired_device(self):
print('Selecting device:')
devices = await self.list_paired_devices()
count = len(devices)
if count < 1:
raise SubprocessError('There is no connected device.')
elif count == 1:
return devices[0]
for i, d in enumerate(devices):
print('%d. %s %s' % (i+1, d[0], d[1]))
print('Select device[1]:')
selected = input()
return devices[0 if not selected.strip() else (int(selected) - 1)]
async def wait():
return await asyncio.sleep(WAIT_TIME)
async def execute_command(cmd, ignore_fail=False):
p = await asyncio.create_subprocess_shell(cmd, stdout=sb.PIPE, stderr=sb.PIPE)
stdout, stderr = await p.communicate()
stdout, stderr = \
stdout.decode() if stdout is not None else '', \
stderr.decode() if stderr is not None else ''
if p.returncode != 0 or stderr.strip() != '':
message = 'Command: %s failed with status: %s\nstderr: %s' % (cmd, p.returncode, stderr)
if ignore_fail:
print('Ignoring: %s' % message)
else:
raise SubprocessError(message)
return stdout
async def execute_find(cmd, pattern, tries=0, fail_safe=False):
tries = tries or TRIES
message = 'Cannot find `%s` using `%s`.' % (pattern, cmd)
retry_message = message + ' Retrying %d more times'
while True:
stdout = await execute_command(cmd)
match = re.search(pattern, stdout)
if match:
return match.group()
elif tries > 0:
await wait()
print(retry_message % tries)
tries -= 1
continue
if fail_safe:
return None
raise RetryExceededError('Retry times exceeded: %s' % message)
async def find_dev_id(mac, **kw):
return await execute_find('pactl list cards short', 'bluez_card.%s' % '_'.join(mac), **kw)
async def find_sink(mac, **kw):
return await execute_find('pacmd list-sinks', 'bluez_sink.%s' % '_'.join(mac), **kw)
async def set_profile(device_id, profile):
print('Setting the %s profile' % profile)
try:
return await execute_command('pactl set-card-profile %s %s' % (device_id, _profiles[profile]))
except KeyError:
print('Invalid profile: %s, please select one one of a2dp or hsp.' % profile, file=sys.stderr)
raise SystemExit(1)
async def set_default_sink(sink):
print('Updating default sink to %s' % sink)
return await execute_command('pacmd set-default-sink %s' % sink)
async def move_streams_to_sink(sink):
streams = await execute_command('pacmd list-sink-inputs | grep "index:"', True)
for i in streams.split():
i = ''.join(n for n in i if n.isdigit())
if i != '':
print('Moving stream %s to sink' % i)
await execute_command('pacmd move-sink-input %s %s' % (i, sink))
return sink
async def main(args):
global WAIT_TIME, TRIES
if args.version:
print(__version__)
return 0
mac = args.mac
# Hacking, Changing the constants!
WAIT_TIME = args.wait
TRIES = args.tries
exit_future = asyncio.Future()
transport, protocol = await asyncio.get_event_loop().subprocess_exec(
lambda: BluetoothctlProtocol(exit_future, echo=args.echo), 'bluetoothctl'
)
try:
if mac is None:
mac, _ = await protocol.select_paired_device()
mac = mac.split(':' if ':' in mac else '_')
print('Device MAC: %s' % ':'.join(mac))
device_id = await find_dev_id(mac, fail_safe=True)
if device_id is None:
print('It seems device: %s is not connected yet, trying to connect.' % ':'.join(mac))
await protocol.trust(mac)
await protocol.connect(mac)
device_id = await find_dev_id(mac)
sink = await find_sink(mac, fail_safe=True)
if sink is None:
await set_profile(device_id, args.profile)
sink = await find_sink(mac)
print('Device ID: %s' % device_id)
print('Sink: %s' % sink)
await set_default_sink(sink)
await wait()
await set_profile(device_id, 'off')
if args.profile is 'a2dp':
await protocol.disconnect(mac)
await wait()
await protocol.connect(mac)
device_id = await find_dev_id(mac)
print('Device ID: %s' % device_id)
await set_profile(device_id, args.profile)
await set_default_sink(sink)
await move_streams_to_sink(sink)
except (SubprocessError, RetryExceededError) as ex:
print(str(ex), file=sys.stderr)
return 1
finally:
print('Exiting bluetoothctl')
await protocol.quit()
await exit_future
# Close the stdout pipe
transport.close()
if args.profile == 'a2dp':
print('"Enjoy" the HiFi stereo music :)')
else:
print('"Enjoy" your headset audio :)')
if __name__ == '__main__':
sys.exit(asyncio.get_event_loop().run_until_complete(main(parser.parse_args())))