16.04 ไม่สามารถใช้คู่หูฟังบลูทู ธ A2DP แต่ไม่ได้เชื่อมต่อ เข้าสู่ระบบภายใน


15

ก่อนอื่นฉันลองทำตามทั้งสองอย่าง: https://vilimpoc.org/blog/2016/04/30/ubuntu-16-04-bluetooth-speakers/และPulseAudio ไม่สามารถโหลดโมดูลบลูทู ธ 15.10 / 16.04 / 16.10

เมื่อฉันพยายามเชื่อมต่อ Jaybird X2 ของฉัน (ลองทั้งบนเดสก์ท็อปและแล็ปท็อป Broadcom และ intel) จับคู่เชื่อมต่อเป็นเวลาสองวินาทีจากนั้นตัดการเชื่อมต่อ

บันทึกฟอร์ม syslog (จากเดสก์ท็อปของฉันด้วย 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.

และเวลาอื่น ๆ :

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 ไม่ทำงานส่วนใหญ่ ..

ข้อผิดพลาดที่แตกต่างกันสองข้อ แต่เป็นปัญหาเดียวกัน เกิดอะไรขึ้น?

บลูทู ธ เสียใน Ubuntu 16.04 ไหม? มันทำงานได้ใน Windows และกับโทรศัพท์ Android ของฉัน

ความช่วยเหลือใด ๆ จะยอดเยี่ยม! :) ฉันจัดการเพื่อให้มันทำงานได้อย่างรวดเร็วก่อนอื่นก็ใช้งานได้แล้ว A2DP ไม่ทำงาน .. ดังนั้นฉันจึงสงสัยว่านี่จะเกี่ยวข้องกับ A2DP ไม่แน่ใจ.


คุณใส่ชุดหูฟังของคุณเข้าสู่โหมดการจับคู่ก่อนเชื่อมต่อหรือไม่? จากการปิดอุปกรณ์กดปุ่มกลางค้างไว้ 4 วินาทีจนกระทั่งไฟกระพริบสีแดง / เขียว ค้นหาใน Ubuntu และเชื่อมต่อ ดูaskubuntu.com/questions/259354/…
Takkat

ใช่และมันจับคู่กันได้ดี .. ปัญหาไม่ได้อยู่ที่การจับคู่ แต่ "กำลังเชื่อมต่อ" .. มันเชื่อมต่อและพูดว่า "เชื่อมต่อหูฟัง" แล้วตัดการเชื่อมต่อ 2 วินาทีหลังจากนั้น
Joakim Koed

เพียงแค่ถามเพราะมันเป็นอาการของอุปกรณ์ที่จับคู่ไม่ถูกต้องที่จะเชื่อมต่อ แต่ล้มเหลว อาจลองใหม่อีกครั้ง (หลังจากนำอุปกรณ์ออกจากอุปกรณ์ที่รู้จัก)
Takkat

Takket: ฉันทำไปแล้ว 20 ครั้ง ชุดหูฟังที่รี
เซต

1
ขอขอบคุณที่ส่งข้อผิดพลาด @RobertIanHawdon ฉันทำเครื่องหมายตัวเองว่าได้รับผลกระทบ
Joakim Koed

คำตอบ:


12

มันเป็นข้อผิดพลาดที่รู้จักกัน ลองrmmod btusb ; modprobe btusbดู ฉันต้องทำถึงสี่ครั้ง

ฉันได้เห็นสิ่งนี้กับ Lenovo P50 ของฉันกับ Intel 8260 wifi / bluetooth บางครั้งเฟิร์มแวร์บลูทู ธ ไม่โหลดอย่างถูกต้องตอนบูต บางครั้งมันก็ไม่ทำงาน


2
มีการถดถอยอย่างรุนแรงในการรองรับบลูทู ธ สำหรับ 16.04
Amias

@ Amias ดีฉันไม่สามารถทำงานบลูทู ธ ใน 14.04 ทั้ง
jarno

1
ใช้งานได้กับฉันบน Lenovo Y510P ที่ใช้ 16.04 ฉันได้เพิ่มนามแฝงใน ~ / .bashrc ของฉัน:alias headphones='sudo rmmod btusb ; sudo modprobe btusb'
BenB

3

ฉันมีปัญหาเดียวกันกับ Jaybird X2 และ Bluebuds X แม้ว่าอุปกรณ์เสียง Bluetooth อื่น ๆ จะทำงานได้โดยไม่มีปัญหา ด้วยหูฟังฉันได้รับข้อผิดพลาดนี้:

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

และ pulseaudio ล้มเหลว สิ่งที่แก้ไขได้คือการติดตั้ง pulseaudio จากแหล่งที่มา:

  • ติดตั้งแพ็คเกจที่จำเป็นทั้งหมด: sudo apt-get build-dep pulseaudio
  • ดาวน์โหลด https://freedesktop.org/software/pulseaudio/releases/pulseaudio-9.0.tar.gzและแกะออก
  • ในซอร์ส dir ให้รัน: ./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

โปรดทราบว่าฉันติดตั้ง pulseaudio 9.0 แต่ไม่ใช่รุ่นที่ใช้งานได้ ฉันพยายามใช้ Pulseaudio 9.0 รุ่นที่จัดทำแพคเกจจากPPAแต่ก็ล้มเหลวด้วยข้อผิดพลาดเดียวกัน


สวัสดี นั่นรวบรวมความดีทั้งหมดหรือไม่ ฉันเพิ่งลดระดับเป็น 6 จากเจ้าเล่ห์เมื่อวานนี้ ทำงานได้อย่างสมบูรณ์แบบ
Joakim Koed

ไม่มีปัญหากับการรวบรวม คุณหมายถึงอะไร
Andrzej Pronobis

ถ้าไม่ใช่เวอร์ชั่นอะไรที่ทำให้แตกต่าง?
Daniel Szmulewicz

2

ฉันมีปัญหานี้กับหูฟัง Bluedio T + 3 ของฉันและสิ่งที่ฉันคิดว่าเกิดขึ้นคือว่ามีการหมดเวลาเชื่อมต่อ คุณต้องยกเลิกการใส่เครื่องหมาย; exit-idle-time = 20ในบรรทัดในไฟล์/etc/pulse/daemon.confโดยลบเครื่องหมายอัฒภาค (;)

เปลี่ยนค่า-1เป็นเป็น:

exit-idle-time = -1

หลังจากนั้นใช้bluetoothctlอีกครั้งเพื่อลองและเชื่อมต่อกับอุปกรณ์ ดูคำแนะนำที่นี่:

Arch wiki: ชุดหูฟังบลูทู ธ


1

ตรวจสอบสิ่งต่อไปนี้:

  • มีการจับคู่ Jaybird X2
  • มันถูกทำเครื่องหมายว่าเชื่อถือได้ (ผ่านbluetoothctlและtrust XX:XX:XX:XX(ที่XX:XX:XX:XXอยู่ MAC ของ Jaybird ของคุณ) หรือผ่านทางใดblueman-manager )
  • มันเปิดอยู่

กดปุ่มเปิดปิดของ Jaybird X2 หนึ่งครั้ง นี่อาจเป็นสาเหตุให้การเชื่อมต่ออัตโนมัติกับอุปกรณ์ที่รู้จัก ดังนั้นคุณอาจต้องตรวจสอบให้แน่ใจว่าอุปกรณ์อื่นไม่รบกวนที่นี่ ตั้งแต่นั้นมาการเชื่อมต่อก็เสถียรและมันก็เชื่อมต่อโดยอัตโนมัติหลังจากรีบูต

แจ้งให้เราทราบว่าสิ่งนี้สามารถแก้ไขปัญหาของคุณได้ ฉันยังทำสิ่งอื่น ๆ อีกมากมายและเกือบจะยอมแพ้เมื่อฉันกดปุ่มเปิด / ปิดเครื่องโดยไม่ได้ตั้งใจ ;-) ดังนั้นอาจเป็นได้ว่าสิ่งหนึ่งในนั้นแก้ปัญหาได้ (กำลังค้นหาและลองสิ่งต่าง ๆ รอบบลูทู ธ , pulseaudio, bluez, pactl load-module อะไรก็ตามดังนั้นฉันยังมีคำแนะนำอื่น ๆ อีกมากมาย :-D)

อัปเดต (หลังจากมีปัญหาการเชื่อมต่ออีกครั้ง)

หลังจากที่ฉันเชื่อมต่อ Jaybird X2 กับโทรศัพท์ Android ของฉันฉันไม่สามารถเชื่อมต่อกับแล็ปท็อปของฉันได้อีกแม้ว่าฉันจะทำการเชื่อมต่อจากโทรศัพท์ Android ของฉันแล้ว ยังไม่รู้ปัญหาอยู่ตรงนี้ แต่เพื่อให้ได้การเชื่อมต่อกลับมาฉันต้องทำสิ่งต่อไปนี้:

  1. ตัดการเชื่อมต่อ Jaybird X2 จากโทรศัพท์ Android ของฉัน (หรืออุปกรณ์อื่น ๆ )
  2. รีบูต Ubuntu
  3. เชื่อมต่องานอีกครั้งและการเชื่อมต่อมีเสถียรภาพ (โดยปกติแล้วจะไม่ทำงานเมื่อจับคู่ครั้งแรก ... ฉันต้องรีบูตหลังจากนั้น)

ฉันลองสิ่งอื่นด้วยและดูเหมือนว่าอย่างน้อยpulseaudio-module-bluetoothก็ต้องการ นอกจากนี้ยังต้องมีการกำหนดค่า wifi / bluetooth coexistence อย่างน้อยในเครื่องของฉัน (ดู: /ubuntu//a/645072/558838 ) และสุดท้าย แต่ไม่ท้ายสุด: ต้องรีบูตเครื่องเสมอเพื่อรับการเชื่อมต่อกลับในกรณีที่ฉันเปลี่ยนไปใช้อุปกรณ์อื่น

เพื่อสรุป: ด้วยขั้นตอนการรีบูตนั้นฉันสามารถเชื่อมต่อ Jaybird X2 อีกครั้งได้สำเร็จและการเชื่อมต่อนั้นเสถียร หากใครรู้วิธีที่ง่ายกว่าในการข้ามขั้นตอนการรีบูตโปรดช่วย :) /etc/init.d/bluetooth restartไม่พอเพียง

(ขั้นตอนเพิ่มเติมที่ฉันได้ลอง):

ฉันดูประวัติของฉัน ฉันลองด้วยวิธีต่อไปนี้ซึ่งอาจมีส่วนหนึ่งหรือส่วนอื่นได้แก้ไขปัญหาข้างต้น:

  • apt-get install pulseaudio-module-bluetooth (ในระบบของฉันมันไม่ได้ติดตั้ง)
  • บันทึกกล่าวถึงบางสิ่งที่หายไป ofonoดังนั้นฉันจึงติดตั้ง
  • ทำ sudo chown -R $USER ~/*
  • ใช้กับ: /ubuntu//a/691299/558838 (แต่ฉันเปลี่ยนกลับเป็นเพราะมันไม่ได้ช่วย แต่มันอาจจะยังใช้งานได้เมื่อฉันพยายามเชื่อมต่ออัตโนมัติ)
  • ยังกำจัด / ติดตั้ง pulseaudio, blueman, bluetooth packag

ขอขอบคุณที่พยายามช่วยทดสอบความผิดพลาดทันทีที่ฉันลอง ฉันลองแล้ว: pactl load-module module-bluetooth-discover และกด power อีกครั้งมันพัง pulseaudio อีกครั้ง: /
Joakim Koed

เพิ่มขั้นตอนเพิ่มเติมในคำตอบซึ่งฉันได้ลองแล้ว หากคุณต้องการรายละเอียดใด ๆ เพียงแค่ถาม
Roland

ตกลง. พบสิ่งอื่นวันนี้: หลังจากนอนหลับฉันไม่สามารถกลับไปทำงานได้อีก ยังคงทำงานหลังจากรีบูต ยิ่งแย่ลง: ทันทีที่มีการเชื่อมต่อบลูทู ธ การเชื่อมต่อไร้สายของฉันจะไม่ทำงานอีกต่อไป มันเชื่อมต่ออยู่ แต่ไม่โอนถ่ายอะไรเลย ฉันต้องตรวจสอบอีกครั้งหนึ่ง
Roland

อย่าลังเลที่จะทำเครื่องหมายตัวเราเองว่าได้รับผลกระทบ: bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/1574324
Joakim Koed

ฉันแก้ไขปัญหาการอยู่ร่วมกันของ wifi / bluetooth กับสิ่งต่อไปนี้: askubuntu.com/a/645072/558838 :) นอนหลับอีกครั้งและได้รับการเชื่อมต่อบลูทู ธ กลับ ... ดังนั้นฉันอาจต้องตรวจสอบสิ่งอื่นที่ฉันทำเพื่อที่ มันใช้งานได้แล้ว ... บางทีการอยู่ร่วมกันอาจเป็นปัญหาสำหรับการเชื่อมต่อที่เสถียรหรือไม่? อย่างน้อยมันฟังดูสมเหตุสมผลกว่าสิ่งอื่น ๆ ที่ฉันได้ระบุไว้ :-) คุณลองแบบนั้นด้วยได้มั้ย
Roland

1

เรียกใช้สคริปต์ที่นี่ใน 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())))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.