16.04 Bluetooth A2DP kulaklık kullanamaz, çiftler bağlanmaz. İçindeki günlükler


15

İlk olarak, her ikisini de takip etmeyi denedim: https://vilimpoc.org/blog/2016/04/30/ubuntu-16-04-bluetooth-speakers/ ve PulseAudio bluetooth modülü 15.10 / 16.04 / 16.10'u yükleyemiyor

Jaybird X2 cihazımı (hem masaüstü hem de dizüstü bilgisayar, broadcom ve intel'de denedim) bağlamaya çalıştığımda eşleşiyor, iki saniye bağlanıyor ve sonra kesiliyor.

Günlük formu syslog (masaüstümden broadcom BT ile)

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.

Ve diğer zamanlarda:

a2dp-sink profile connect failed for xxxxxxx Protocol not available

DÜZENLE .. ÖNEMLİ:

Şimdi diğer cihazlara bağlanmaya çalışmanın çoğu zaman iyi çalıştığını öğrendim (Micropod BT ve Samsung AirTrack), ancak Jaybird X2'yi denediğimde, modül-bluetooth-keşfetmek'i devre dışı bırakıyor / kaldırıyor pactl load-module module-bluetooth-discoverve diğer ikisi tekrar işlev görecek ..

Şimdi bu dizüstü bilgisayar ile olur:

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.

Daha önce masaüstüme kısaca bağlayabildim, ancak A2DP çoğu zaman çalışmadı.

İki farklı hata ama aynı sorun. Ne oluyor?

Bluetooth Ubuntu 16.04'te kırıldı mı? Windows ve Android Telefonumla çalışır.

Herhangi bir yardım harika olurdu! :) Bir şekilde kısaca çalışmayı başardım, önce çalıştı, sonra A2DP işe yaramadı .. bu yüzden bunun A2DP ile bir ilgisi olduğundan şüpheleniyorum. Emin değil.


Bağlamadan önce kulaklığınızı eşleştirme moduna getirdiniz mi? Kapalı cihazdan, kırmızı / yeşil yanıp sönen ışık yanana kadar orta tuşu 4 saniye basılı tutun. Ubuntu'da arayın ve bağlanın. Bkz. Askubuntu.com/questions/259354/…
Takkat

Evet, ve gayet iyi çiftler .. Sorun soyma değil, "bağlanıyor" .. Bağlanır ve "kulaklık bağlı" der ve sonra 2 saniye sonra kesilir.
Joakim Koed

Sadece sormak, çünkü düzgün bir şekilde eşleştirilmemiş cihazların bağlandığını görüyor, ancak başarısız oluyor. Yeniden denemeye değer olabilir (cihazı bilinen cihazlardan çıkardıktan sonra).
Takkat

Takket: Muhtemelen 20 kere yaptım. sert sıfırlama kulaklık vb.
Joakim Koed

1
Hatayı gönderdiğiniz için teşekkür ederiz, @RobertIanHawdon. Kendimi etkilenmiş olarak işaretledim.
Joakim Koed

Yanıtlar:


12

Bilinen bir hatadır. Deneyin rmmod btusb ; modprobe btusb. Bunu dört kata kadar yapmak zorunda kaldım.

Bunu Intel 8260 wifi / bluetooth özellikli Lenovo P50 ile gördüm. Bazen bluetooth ürün yazılımı önyüklemede doğru yüklenmiyor. Diğer zamanlarda işe yaramıyor.


2
Bluetooth desteğinde 16.04 için bazı ciddi gerilemeler olmuştur.
Amias

@Amias Eh, ben de 14.04 bluetooth çalışma yapamadı.
jarno

1
16.04 çalıştıran Lenovo Y510P cihazımda çalışıyor. ~ / .Bashrc'ye bir takma ad ekledim:alias headphones='sudo rmmod btusb ; sudo modprobe btusb'
BenB

3

Diğer Bluetooth ses cihazları sorunsuz çalışmasına rağmen, Jaybird X2 ve Bluebuds X ile aynı sorunu yaşadım. Kulaklıklarla bu hatayı aldım:

Assertion 'pa_channels_valid(channels)' failed at pulse/volume.c:74, function pa_cvolume_set(). Aborting.

ve pulseaudio çöktü. Ne çözdü pulseaudio'yu kaynaklardan kuruyordu:

  • Gerekli tüm paketleri yükleyin: sudo apt-get build-dep pulseaudio
  • Https://freedesktop.org/software/pulseaudio/releases/pulseaudio-9.0.tar.gz dosyasını indirin ve açın.
  • Kaynak dir yılında çalıştırın: ./bootstrap.sh --prefix=/usr. İsterseniz, CFLAGSderleyici optimizasyonlarını etkinleştirmek için değişkeni değiştirebilirsiniz; örneğin, -O2yerine kullanın -O0.
  • Sonra makevesudo make install

Bu, varsayılan sistem kurulumunun üzerine yazılır, ancak paketler güncellenene kadar çalışır. Güncellemeleri önlemek için pulseaudio paketlerini beklemeye alabiliriz:

sudo apt-mark hold libpulse-dev libpulse0 libpulse-mainloop-glib0 pulseaudio pulseaudio-module-bluetooth pulseaudio-utils libpulsedsp pulseaudio-module-x11

Not ben pulseaudio 9.0 yüklü, ancak o iş yapılmış versiyonu olmadığını. İ PulseAudio'dan 9.0 paket versiyonunu kullanarak güvenilir PPA , ama aynı zamanda aynı hata ile çöktü.


Selam. Bu da tüm ahlakları derliyor mu? Aslında dün wily'den 6'ya düştüm. Mükemmel çalıştı.
Joakim KOED

Derlemeyle ilgili herhangi bir sorun yoktu. Ne demek istiyorsun?
Andrzej Pronobis

Sürüm değilse, farkı ne yaptı?
Daniel Szmulewicz

2

Bluedio T + 3 kulaklığımla bu sorunu yaşadım ve bence ne olduğunu bir bağlantı zaman aşımı var. Noktalı virgül (;) 'yi kaldırarak ; exit-idle-time = 20dosyadaki satırı açmanız gerekir /etc/pulse/daemon.conf.

Olmak için değeri değiştirin -1:

exit-idle-time = -1

Bu kullanımdan sonra bluetoothctl tekrar denemek ve cihaza bağlanmak için kullanın. Talimatlar için buraya bakın:

Arch wiki: bluetooth kulaklık


1

Aşağıdakileri sağlayın:

  • Jaybird X2 eşlendi
  • güvenilir ( bluetoothctlve trust XX:XX:XX:XX( XX:XX:XX:XXJaybird'ünüzün MAC adresi nerede ) aracılığıyla veya yoluylablueman-manager )
  • açık

Jaybird X2 cihazınızın güç düğmesine bir kez basın. Bu muhtemelen bilinen cihazlara otomatik bağlanmayı tetikler. Dolayısıyla, diğer cihazların burada parazit yapmadığından emin olmanız gerekebilir. O andan itibaren bağlantı kararlıydı ve yeniden başlatıldıktan sonra da otomatik olarak bağlanıyor.

Bunun sorununuzu çözüp çözmediğini bana bildirin. Ayrıca başka birçok şey yaptım ve yanlışlıkla güç düğmesine bastığımda neredeyse vazgeçiyordum ;-) Yani bu diğer şeylerden biri de sorunu çözmüş olabilir. (zaten Bluetooth, pulseaudio, bluez, pactl yük modülü etrafında bir şeyler araştırıyor ve deniyordu; bu yüzden hala bir sürü başka ipucum var :-D)

GÜNCELLEME (tekrar bağlantı sorunları yaşadıktan sonra)

Android telefonuma Jaybird X2'yi bağladıktan sonra, android telefonumdan bağlantıyı kestikten sonra bile dizüstü bilgisayarıma tekrar bağlanamadım. Henüz bilmiyorum, sorunun tam olarak ne olduğunu, ancak bağlantıyı geri almak için aşağıdakileri yapmak zorundaydım:

  1. Jaybird X2'yi android telefonumdan (veya başka bir cihazdan) ayır
  2. ubuntu'yu yeniden başlat
  3. yeniden bağlanma çalışır ve bağlantı sabittir (genellikle ilk kez eşleştirilirken çalışmadı ... Bundan sonra yeniden başlatmam da gerekiyordu)

Ayrıca başka şeyler denedim ve en azından pulseaudio-module-bluetoothgerekli gibi görünüyor . Ayrıca en azından makinemde wifi / bluetooth bir arada var olma yapılandırması gerekiyor (bkz . Https://askubuntu.com/a/645072/558838 ). Ve son fakat en az değil: başka bir cihaza geçersem bağlantıyı geri almak için her zaman yeniden başlatma gerekir.

Özetlemek gerekirse: Bu yeniden başlatma adımıyla Jaybird X2'yi başarıyla yeniden bağlayabilirim ve bağlantı kararlı. Yeniden başlatma adımını atlamanın daha kolay bir yolunu bilen biri varsa, lütfen katkıda bulunun :) /etc/init.d/bluetooth restart yeterli değildir.

(denediğim ek adımlar):

Tarihime baktım. Ayrıca, yukarıdaki çözümün birine ya da diğerinin katkıda bulunabileceği aşağıdakileri de denedim:

  • apt-get install pulseaudio-module-bluetooth (sistemime yüklenmedi)
  • günlükleri eksik hakkında bir şey bahsetti ofono, bu yüzden de
  • yaptı sudo chown -R $USER ~/*
  • Ayrıca uygulandı: /ubuntu//a/691299/558838 (Ancak yardım etmediği için geri döndüm. Ama otomatik bağlantıyı denediğimde hala aktif olabilir)
  • ayrıca pulseaudio, blueman, bluetooth packag tasfiye / yüklemek

Yardım etmeye çalıştığınız için teşekkür ederiz, sadece test ettim, denediğim anda çökün. Sonra denedim: pactl yük modülü modülü-bluetooth-keşfetmek ve tekrar güç basın, bir kez daha pulseaudio çöktü: /
Joakim Koed

Denediğim yanıta ek adımlar eklendi. Herhangi bir ayrıntı gerekiyorsa, sadece isteyin.
Roland

TAMAM. Bugün başka bir şey öğrendim: Bir uykudan sonra tekrar çalışamadım. Yine de yeniden başlatmanın ardından çalışır. Daha da kötüsü: Bluetooth bağlantısı kurulur kurulmaz, kablosuz bağlantım artık çalışmıyor. Bağlı kalır ancak hiçbir şey aktarmaz. Bunu daha fazla araştırmam gerekiyor.
Roland


Aşağıdaki ile wifi / bluetooth bir arada yaşama sorununu düzelttim : askubuntu.com/a/645072/558838 :) Tekrar uyudum ve bluetooth bağlantısını geri aldım ... bu yüzden başka ne yaptığımı kontrol etmek zorunda kalacağım, böylece şimdi çalışıyor ... Belki de birlikte yaşama hatası da istikrarlı bağlantı için sorun oldu? En azından listelediğim diğer şeylerden daha makul geliyor :-) Bunu da deneyebilir misin?
Roland

1

Komut dosyasını GitHub'da çalıştırın

Ve sorun ortadan kalkacak.

#! /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())))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.