16.04 Impossibile utilizzare le cuffie bluetooth A2DP, le coppie ma non si collegano. Entra dentro


15

Innanzitutto, ho provato a seguire entrambi: https://vilimpoc.org/blog/2016/04/30/ubuntu-16-04-bluetooth-speakers/ e PulseAudio non è in grado di caricare il modulo bluetooth 15.10 / 16.04 / 16.10

Quando provo a connettere il mio Jaybird X2 (provato su desktop e laptop, broadcom e Intel) si accoppia, si connette per due secondi e poi si disconnette.

Log modulo syslog (dal mio desktop con broadcom 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.

E altre volte:

a2dp-sink profile connect failed for xxxxxxx Protocol not available

MODIFICA .. IMPORTANTE:

Ora ho scoperto che il tentativo di connettersi ad altri dispositivi funziona bene (Micropod BT e Samsung AirTrack) per la maggior parte del tempo, ma non appena provo Jaybird X2, disabilita / scarica il modulo-bluetooth-discover e devo farlo pactl load-module module-bluetooth-discoverper altri due per funzionare di nuovo ..

Ora questo succede con il laptop:

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.

Prima ero in grado di collegarlo brevemente sul mio desktop, ma A2DP non funzionava per la maggior parte del tempo ..

Due errori diversi ma lo stesso problema. Cosa sta succedendo?

Il bluetooth è appena rotto in Ubuntu 16.04? Funziona su Windows e con il mio telefono Android.

Qualsiasi aiuto sarebbe fantastico! :) In qualche modo sono riuscito a farlo funzionare brevemente, prima ha funzionato, quindi A2DP non ha funzionato .. quindi sospetto che questo abbia qualcosa a che fare con A2DP. Non sono sicuro.


Hai messo l'auricolare in modalità di associazione prima della connessione? Dal dispositivo spento, tenere premuto il tasto centrale per 4 s fino a quando le luci rosse / verdi lampeggiano. Cerca in Ubuntu e connettiti. Vedi askubuntu.com/questions/259354/…
Takkat

Sì, e si accoppia bene ... Il problema non è il paring, ma "il collegamento" .. Si collega e dice "cuffia connessa" e quindi si disconnette dopo 2 secondi.
Joakim Koed,

Chiedo solo perché è un sintomo di dispositivi non correttamente accoppiati che sembrano connettersi ma poi falliscono. Potrebbe essere utile riprovare (dopo aver rimosso il dispositivo da dispositivi noti).
Takkat,

Takket: Probabilmente l'ho fatto 20 volte. Cuffie con hard reset, ecc. ecc.
Joakim Koed

1
Grazie per aver inviato il bug, @RobertIanHawdon. Mi sono segnato come colpito.
Joakim Koed,

Risposte:


12

È un bug noto. Prova rmmod btusb ; modprobe btusb. Ho dovuto farlo fino a quattro volte.

L'ho visto con il mio Lenovo P50 con Intel 8260 wifi / bluetooth. A volte il firmware bluetooth non si carica correttamente all'avvio. Altre volte non funziona.


2
Ci sono state alcune gravi regressioni nel supporto Bluetooth per 16.04.
Amias,

@Amias Beh, non sono riuscito a far funzionare il Bluetooth anche nel 14.04.
jarno,

1
Funziona per me sul mio Lenovo Y510P con 16.04. Ho aggiunto un alias al mio ~ / .bashrc:alias headphones='sudo rmmod btusb ; sudo modprobe btusb'
BenB il

3

Ho avuto lo stesso problema con Jaybird X2 e Bluebuds X, sebbene altri dispositivi audio Bluetooth funzionassero senza problemi. Con le cuffie ho riscontrato questo errore:

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

e pulseaudio si è schiantato. Ciò che ha risolto è stato installare pulseaudio da fonti:

  • Installa tutti i pacchetti richiesti: sudo apt-get build-dep pulseaudio
  • Scarica https://freedesktop.org/software/pulseaudio/releases/pulseaudio-9.0.tar.gz e decomprimilo.
  • Nel dir fonte, eseguire: ./bootstrap.sh --prefix=/usr. Se lo desideri, puoi modificare la CFLAGSvariabile per abilitare le ottimizzazioni del compilatore, ad esempio utilizzare al -O2posto di -O0.
  • Quindi, makeesudo make install

Ciò sovrascriverà l'installazione di sistema predefinita, ma funzionerà fino all'aggiornamento dei pacchetti. Per impedire gli aggiornamenti, possiamo mettere in attesa i pacchetti pulseaudio:

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

Nota che ho installato pulseaudio 9.0, ma non è la versione a farlo funzionare. Ho provato a utilizzare la versione in pacchetto di pulseaudio 9.0 dal PPA , ma si è bloccato anche con lo stesso errore.


Ciao. Questo compila anche tutte le decenze? Ieri ho appena declassato a 6 da astuto. Ha funzionato perfettamente.
Joakim Koed,

Non ci sono stati problemi con la compilation. Cosa intendi?
Andrzej Pronobis,

Se non la versione, cosa ha fatto la differenza?
Daniel Szmulewicz,

2

Ho riscontrato questo problema con le mie cuffie Bluedio T + 3 e ciò che penso stia accadendo è che c'è un timeout di connessione. È necessario decommentare la riga ; exit-idle-time = 20nel file /etc/pulse/daemon.confrimuovendo il punto e virgola (;).

Modifica il valore in -1per diventare:

exit-idle-time = -1

Successivamente utilizzare bluetoothctlnuovamente per provare e connettersi al dispositivo. Vedi qui per le istruzioni:

Arch wiki: auricolare bluetooth


1

Garantire quanto segue:

  • Jaybird X2 è accoppiato
  • è contrassegnato come attendibile (tramite bluetoothctle trust XX:XX:XX:XX(dove si XX:XX:XX:XXtrova l'indirizzo MAC del tuo Jaybird) o via blueman-manager)
  • è acceso

Premi una volta il pulsante di accensione del tuo Jaybird X2. Ciò probabilmente avvia una connessione automatica a dispositivi noti. Quindi potrebbe essere necessario assicurarsi che altri dispositivi non interferiscano qui. Da quel momento in poi la connessione è stata stabile e si connette automaticamente anche dopo un riavvio.

Fammi sapere se anche questo ha risolto il tuo problema. Ho anche fatto molte altre cose e mi stavo quasi arrendendo, quando ho accidentalmente premuto il pulsante di accensione ;-) Quindi potrebbe anche essere che una di quelle altre cose abbia risolto il problema. (Stavo già cercando e provando cose intorno a bluetooth, pulseaudio, bluez, pactl load-module qualunque; quindi ho ancora molti altri suggerimenti MrGreen)

AGGIORNAMENTO (dopo aver riscontrato nuovamente problemi di connessione)

Dopo aver collegato Jaybird X2 al mio telefono Android, non sono stato in grado di riconnettermi nuovamente al mio laptop, anche dopo aver abbandonato la connessione dal mio telefono Android. Non so ancora, qual è esattamente il problema qui, ma per riavere la connessione, ho dovuto fare quanto segue:

  1. disconnetto Jaybird X2 dal mio telefono Android (o qualsiasi altro dispositivo)
  2. riavvia Ubuntu
  3. la riconnessione funziona e la connessione è stabile (di solito non ha funzionato al primo accoppiamento ... Ho anche richiesto un riavvio dopo)

Ho anche provato alcune altre cose e sembra che almeno pulseaudio-module-bluetoothsia richiesto. Anche la configurazione di coesistenza wifi / bluetooth è richiesta almeno sulla mia macchina (vedi: /ubuntu//a/645072/558838 ). E, ultimo ma non meno importante: un riavvio è sempre necessario per ripristinare la connessione nel caso in cui passassi a un altro dispositivo.

Riassumendo: con quel passo di riavvio sono in grado di riconnettere Jaybird X2 con successo e la connessione è stabile. Se qualcuno conosce un modo più semplice per omettere il riavvio, ti preghiamo di contribuire :) /etc/init.d/bluetooth restartnon è sufficiente.

(passaggi aggiuntivi che ho provato):

Ho esaminato la mia storia. Ho provato anche quanto segue in cui l'uno o l'altro potrebbe aver contribuito alla soluzione sopra:

  • apt-get install pulseaudio-module-bluetooth (sul mio sistema non è stato installato)
  • i registri menzionavano qualcosa sulla mancanza ofono, quindi l'ho installato anche io
  • fatto a sudo chown -R $USER ~/*
  • applicato anche: /ubuntu//a/691299/558838 (tuttavia l'ho ripristinato in quanto non ha aiutato. Ma potrebbe essere stato ancora attivo, quando ho provato la connessione automatica)
  • ha anche eliminato / installato pulseaudio, blueman, bluetooth packag

Grazie per aver cercato di aiutare, appena provato, crash non appena ho provato. Poi ho provato: modulo di caricamento pactl-modulo-bluetooth-scopri e premi di nuovo potenza, ancora una volta si è schiantato pulseaudio: /
Joakim Koed

Aggiunti ulteriori passaggi alla risposta, che ho provato. Se hai bisogno di dettagli su qualsiasi, basta chiedere.
Roland,

OK. Ho scoperto qualcos'altro oggi: dopo un sonno non sono riuscito a farlo funzionare di nuovo. Funziona ancora dopo un riavvio. Ancora peggio: non appena viene stabilita la connessione bluetooth, la mia connessione wireless non funziona più. Rimane connesso ma non trasferisce nulla. Devo indagare ulteriormente su quello.
Roland,

Sentiti libero di contrassegnarci come interessato: bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/1574324
Joakim Koed

Ho risolto il problema di coesistenza wifi / bluetooth con quanto segue: askubuntu.com/a/645072/558838 :) Ho dormito di nuovo e ripristinato la connessione bluetooth ... quindi potrei dover controllare cos'altro ho fatto, in modo che ora funziona ... Forse il bug di coesistenza era anche il problema per la connessione stabile? Almeno suona più ragionevole delle altre cose che ho elencato :-) Potresti provare anche quella?
Roland,

1

Esegui lo script qui su GitHub

E il problema svanirà.

#! /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())))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.