16.04 Tidak dapat menggunakan headphone bluetooth A2DP, berpasangan tetapi tidak terhubung. Log di dalam

15

Pertama, saya telah mencoba mengikuti kedua hal ini: https://vilimpoc.org/blog/2016/04/30/ubuntu-16-04-bluetooth-speakers/ dan PulseAudio tidak dapat memuat modul bluetooth 15.10 / 16.04 / 16.10

Ketika saya mencoba untuk menghubungkan Jaybird X2 saya (dicoba pada desktop dan laptop, broadcom dan intel) berpasangan, terhubung selama dua detik kemudian terputus.

Log form syslog (dari desktop saya dengan 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.

Dan lain kali:

a2dp-sink profile connect failed for xxxxxxx Protocol not available

EDIT .. PENTING:

Saya sekarang telah menemukan bahwa mencoba menghubungkan ke perangkat lain berfungsi dengan baik (Micropod BT dan Samsung AirTrack) sebagian besar waktu, tetapi segera setelah saya mencoba Jaybird X2, ia menonaktifkan / membongkar modul-bluetooth-temukan dan saya harus melakukannya pactl load-module module-bluetooth-discoveruntuk dua lainnya berfungsi lagi ..

Sekarang ini terjadi dengan 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.

Saya sempat menghubungkannya di desktop saya sebelumnya, tetapi A2DP tidak berfungsi sebagian besar waktu ..

Dua kesalahan berbeda tetapi masalah yang sama. Apa yang sedang terjadi?

Apakah bluetooth rusak di Ubuntu 16.04? Ini bekerja di Windows dan dengan Ponsel Android saya.

Bantuan apa pun akan luar biasa! :) Saya entah bagaimana berhasil membuatnya bekerja sebentar, pertama berhasil, maka A2DP tidak bekerja .. jadi saya curiga ini ada hubungannya dengan A2DP. Tidak yakin.

Joakim Koed
sumber
Apakah Anda memasukkan headset ke mode berpasangan sebelum menghubungkan? Dari mematikan perangkat, tekan & tahan tombol tengah selama 4 detik hingga lampu berkedip merah / hijau. Cari di Ubuntu dan terhubung. Lihat askubuntu.com/questions/259354/…
Takkat
Ya, dan itu berpasangan dengan baik .. Masalahnya bukan pengupas, tetapi "menghubungkan" .. Menghubungkan dan mengatakan "headphone terhubung" dan kemudian terputus 2 detik setelah.
Joakim Koed
Hanya bertanya karena itu adalah gejala perangkat yang tidak dipasangkan dengan benar untuk terhubung tetapi kemudian gagal. Mungkin perlu mencoba ulang (setelah melepas perangkat dari perangkat yang dikenal).
Takkat
Takket: Saya mungkin melakukannya 20 kali. headset hard-reset, dll.
Joakim Koed
1
Terima kasih telah mengirimkan bug, @RobertIanHawdon. Saya telah menandai diri saya terpengaruh.
Joakim Koed

Jawaban:

12

Ini adalah bug yang dikenal. Coba rmmod btusb ; modprobe btusb. Saya harus melakukannya hingga empat kali.

Saya telah melihat ini dengan Lenovo P50 saya dengan Intel 8260 wifi / bluetooth. Terkadang firmware bluetooth tidak dimuat dengan benar saat boot. Di lain waktu itu tidak berfungsi.

pengguna550672
sumber
2
Ada beberapa kemunduran serius dalam dukungan Bluetooth untuk 16.04.
Amias
@Amias Yah, aku juga tidak bisa membuat bluetooth berfungsi di 14,04.
jarno
1
Bekerja untuk saya di Lenovo Y510P saya yang menjalankan 16.04. Saya telah menambahkan alias ke ~ / .bashrc:alias headphones='sudo rmmod btusb ; sudo modprobe btusb'
BenB
3

Saya memiliki masalah yang sama dengan Jaybird X2 dan Bluebuds X, meskipun perangkat audio Bluetooth lainnya bekerja tanpa masalah. Dengan headphone, saya mendapat kesalahan ini:

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

dan pulseaudio jatuh. Apa yang menyelesaikannya adalah menginstal pulseaudio dari sumber:

  • Instal semua paket yang dibutuhkan: sudo apt-get build-dep pulseaudio
  • Unduh https://freedesktop.org/software/pulseaudio/releases/pulseaudio-9.0.tar.gz dan bongkar.
  • Dalam sumber dir, jalankan: ./bootstrap.sh --prefix=/usr. Jika Anda mau, Anda bisa mengubah CFLAGSvariabel untuk mengaktifkan optimisasi kompiler, mis. Gunakan -O2alih-alih -O0.
  • Lalu, makedansudo make install

Ini akan menimpa instalasi sistem default, tetapi akan berfungsi sampai paket diperbarui. Untuk mencegah pembaruan, kami dapat menunda paket pulseaudio:

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

Perhatikan bahwa saya menginstal pulseaudio 9.0, tetapi bukan versi yang membuatnya bekerja. Saya mencoba menggunakan versi paket pulseaudio 9.0 dari PPA , tetapi juga mengalami kesalahan yang sama.

Andrzej Pronobis
sumber
Hai. Apakah itu mengkompilasi semua kesopanan juga? Sebenarnya saya baru saja diturunkan ke 6 dari licik kemarin. Bekerja dengan sempurna.
Joakim Koed
Tidak ada masalah dengan kompilasi. Apa maksudmu?
Andrzej Pronobis
Jika bukan versi, apa yang membuat perbedaan?
Daniel Szmulewicz
2

Saya punya masalah dengan headset Bluedio T + 3 saya dan apa yang saya pikir terjadi adalah ada batas waktu koneksi. Anda harus menghapus tanda komentar pada baris ; exit-idle-time = 20dalam file /etc/pulse/daemon.confdengan menghapus tanda titik koma (;).

Ubah nilainya -1menjadi:

exit-idle-time = -1

Setelah itu gunakan bluetoothctllagi untuk mencoba dan terhubung ke perangkat. Lihat di sini untuk instruksi:

Arch wiki: headset bluetooth

anandan111
sumber
1

Pastikan yang berikut ini:

  • Jaybird X2 dipasangkan
  • itu ditandai sebagai tepercaya (baik melalui bluetoothctldan trust XX:XX:XX:XX(di mana XX:XX:XX:XXalamat MAC Jaybird Anda) atau via blueman-manager)
  • dihidupkan

Tekan tombol daya Jaybird X2 Anda sekali. Ini mungkin memicu koneksi otomatis ke perangkat yang dikenal. Jadi, Anda mungkin perlu memastikan bahwa perangkat lain tidak ikut campur di sini. Sejak saat itu koneksi stabil dan juga terhubung secara otomatis setelah reboot.

Beri tahu saya apakah ini juga menyelesaikan masalah Anda. Saya juga melakukan banyak hal lain dan hampir menyerah, ketika saya tanpa sengaja menekan tombol daya ;-) Jadi bisa juga salah satu dari hal-hal lain menyelesaikan masalah. (sudah mencari dan mencoba hal-hal di bluetooth, pulseaudio, bluez, pactl load-module apa pun; jadi saya masih punya banyak petunjuk lain :-D)

UPDATE (setelah mengalami masalah koneksi lagi)

Setelah saya menghubungkan Jaybird X2 ke ponsel android saya, saya tidak dapat terhubung kembali ke laptop saya, bahkan setelah saya memutuskan koneksi dari ponsel android saya. Belum tahu, apa sebenarnya masalahnya di sini, tetapi untuk mendapatkan koneksi kembali, saya harus melakukan hal berikut:

  1. putuskan sambungan Jaybird X2 dari ponsel android saya (atau perangkat lain)
  2. reboot ubuntu
  3. berhubungan kembali bekerja dan koneksi yang stabil (biasanya tidak bekerja saat memasangkan pertama kalinya ... Saya juga diperlukan reboot setelah itu)

Saya juga mencoba beberapa hal lain dan tampaknya paling pulseaudio-module-bluetoothtidak diperlukan. Konfigurasi wifi / bluetooth koeksistensi diperlukan setidaknya di mesin saya (lihat: /ubuntu//a/645072/558838 ). Dan last but not least: reboot selalu diperlukan untuk mendapatkan koneksi kembali jika saya beralih ke perangkat lain.

Untuk meringkas: dengan langkah reboot saya berhasil menyambungkan kembali Jaybird X2 dan koneksi stabil. Jika ada yang tahu cara yang lebih mudah untuk menghilangkan langkah reboot, silakan berkontribusi :) /etc/init.d/bluetooth restarttidak cukup.

(langkah tambahan yang saya coba):

Saya melihat sejarah saya. Saya juga mencoba yang berikut di mana satu atau yang lain mungkin berkontribusi pada solusi di atas:

  • apt-get install pulseaudio-module-bluetooth (pada sistem saya itu tidak diinstal)
  • log menyebutkan sesuatu tentang yang hilang ofono, jadi saya juga menginstalnya
  • melakukan sudo chown -R $USER ~/*
  • juga diterapkan: /ubuntu//a/691299/558838 (Namun saya mengembalikannya karena tidak membantu. Tetapi mungkin masih aktif, ketika saya mencoba koneksi otomatis)
  • juga membersihkan / menginstal paket pulseaudio, blueman, bluetooth
Roland
sumber
Terima kasih telah mencoba membantu, baru saja mengujinya, crash segera setelah saya mencoba. Saya kemudian mencoba: pactl load-module module-bluetooth-temukan dan tekan daya lagi, itu sekali lagi jatuh pulseaudio: /
Joakim Koed
Ditambahkan langkah tambahan untuk jawabannya, yang saya sudah mencoba. Jika Anda membutuhkan rincian tentang apapun, hanya bertanya.
Roland
BAIK. Menemukan sesuatu yang lain hari ini: setelah tidur saya tidak bisa membuatnya bekerja lagi. Masih berfungsi setelah reboot. Lebih buruk lagi: begitu koneksi bluetooth terbentuk, koneksi nirkabel saya tidak berfungsi lagi. Tetap terhubung tetapi tidak mentransfer apa pun. Saya harus menyelidiki yang lebih jauh.
Roland
Jangan ragu untuk menandai diri kita sebagai yang terpengaruh: bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/1574324
Joakim Koed
Saya memperbaiki masalah koeksistensi wifi / bluetooth dengan yang berikut ini: askubuntu.com/a/645072/558838 :) Tidur lagi dan mendapatkan koneksi bluetooth kembali ... jadi saya mungkin harus memeriksa apa lagi yang saya lakukan, sehingga sekarang berfungsi ... Mungkin bug koeksistensi juga masalah untuk koneksi yang stabil? Setidaknya itu terdengar lebih masuk akal daripada hal-hal lain yang saya cantumkan :-) Bisakah Anda mencobanya juga?
Roland
1

Jalankan skrip di sini di GitHub

Dan masalahnya akan hilang.

#! /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())))
bikashg
sumber