Автоматично підключайте надійний динамік Bluetooth


10

Я дотримувався наступного підручника ( http://mygeeks014.blogspot.nl/2015/01/audio-streaming-to-bluetooth-speaker.html ), щоб підключити динамік Bluetooth до мого Raspberry Pi. Все працює так, як належить, але динамік не підключиться автоматично при перезапуску Raspberry або включенні / вимкненні динаміка. Зараз я вручну знову підключаю динамік через Raspbian GUI, але мені цікаво, чи є просте рішення для підключення динаміка через CLI. Тоді я зможу написати простий CRON для підключення динаміка, якщо він ще не підключений.

Відповіді:


17

Ось дуже детальне пояснення:

Den3243

Ось рішення командного рядка:

Спочатку давайте скануємо, з’єднаємо, довіряємо своєму пристрою "bluetoothctl". Для цього запустіть це в командному рядку свого терміналу:

bluetoothctl -a

Ви повинні отримати інший командний рядок типу:

[bluetooth]

Увімкнувши цей динамік BT:

scan on

Через кілька моментів вам слід побачити наявні пристрої BT. Поруч із пристроєм буде його MAC-адреса, наприклад: 00: AA: 22: BB: 33. Тепер наберіть це:

info <your mac address>

Виключіть більше та менше символів. Що ви шукаєте, це якась попередня асоціація з вашим спікером BT. Ви будете знати, що була попередня асоціація, оскільки bluetoothctl покаже інформацію про ваш BT-пристрій. Деяка частина цієї інформації стосуватиметься пристрою, яким ви користуєтесь парним та надійним. Це добре.

Якщо bluetoothctl скаржиться на відсутність пристрою, то нам потрібно встановити це в цей момент. Для цього введіть це:

pair <your mac address>

Ви повинні побачити повідомлення про успішне сполучення пристрою. Тепер довіримось нашому новому пристрою BT. Наберіть це:

trust <your mac address>

Знову слід побачити повідомлення про успіх щодо довіри. Дозвольте попередньо попередити вас. Ваш BT-пристрій може підключитися, а потім знову не може. Ніколи не бійтеся, ми не хочемо, щоб це з'єднувалося. Вперед і виходимо з "bluetoothctl". Для цього введіть:

quit

Тепер вас буде повернено до командного рядка. У попередньому дописі я запропонував вам створити каталог сценаріїв у вашому домашньому каталозі. Якщо ви цього не зробили, продовжуйте робити це зараз. Введіть це в командному рядку:

mkdir -p ~/scripts

Натисніть клавішу Enter і тепер давайте створимо наш сценарій автозапуску. Наберіть це:

nano ~/scripts/autopair

Введіть цей код у сценарій:

#!/bin/bash
bluetoothctl << EOF
connect [enter your MAC add]
EOF

Виключіть дужки!

Тепер натисніть CTRL + x одночасно, а тепер натисніть клавішу Enter, щоб зберегти сценарій. Нам потрібно зробити його виконуваним. Для цього введіть це:

chmod +x ~/scripts/autopair

Я припускаю, що ви не використовуєте зовнішні аналогові динаміки для роз'єму 3,5 мм. Якщо це правда, давайте відключимо alsa. Для цього давайте відредагуємо файл у каталозі / boot під назвою config.txt. Для цього введіть це у свій термінал:

sudo nano /boot/config.txt

Сторінку внизу файлу знайдіть два рядки, які читають:

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

Поставте (знак # фунта) перед рядком, на якому написано:

dtparam=audio=on

На вигляд:

#dtparam=audio=on

Натисніть CTRL + x, а потім натисніть Enter, щоб зберегти файл.

Я припускаю, що у вас встановлений pulseaudio? Якщо ні, то вперед і запустіть цю команду з командного рядка:

sudo apt-get update && sudo apt-get install pulseaudio -y

Це дасть вам дуже важливу складову для роботи Bluetooth! Тепер давайте відредагуємо наш .bashrc файл у нашому домашньому каталозі. Наберіть це:

nano ~/.bashrc

Сторінка вниз донизу та додайте цей рядок:

pulseaudio --start

Натисніть CTRL + x і тепер натисніть Enter, щоб зберегти файл.

ДОБРЕ! Нам потрібно зайти у світ Python. Я написав програму Python, яка буде стежити за пристроєм Bluetooth. Коротше кажучи, він активує зв’язок між RPi та Bluetooth-динаміком, як тільки ваш Bluetooth-динамік увімкнений. І навпаки. Створіть у вашому домашньому каталозі каталог під назвою python. Для цього введіть це:

mkdir -p ~/python

Тепер давайте створимо програмний файл python. Для цього введіть це:

nano ~/python/on.py

Всередині цього файлу нам потрібно скопіювати та вставити таке:

#!/usr/bin/python
#
# Monitor removal of bluetooth reciever
import os
import sys
import subprocess
import time

def blue_it():
    status = subprocess.call('ls /dev/input/event0 2>/dev/null', shell=True)
    while status == 0:
        print("Bluetooth UP")
        print(status)
        time.sleep(15)
        status = subprocess.call('ls /dev/input/event0 2>/dev/null', shell=True)
    else:
        waiting()

def waiting():
    subprocess.call('killall -9 pulseaudio', shell=True)
    time.sleep(3)
    subprocess.call('pulseaudio --start', shell=True)
    time.sleep(2)
    status = subprocess.call('ls /dev/input/event0 2>/dev/null', shell=True)  
    while status == 2:
        print("Bluetooth DOWN")
        print(status)
        subprocess.call('~/scripts/autopair', shell=True)
        time.sleep(15)
        status = subprocess.call('ls /dev/input/event0 2>/dev/null', shell=True)
    else:
        blue_it() 

blue_it()

Тепер натисніть CTRL + x, а потім натисніть Enter, щоб зберегти файл програми Python. Тепер нам потрібно зробити цей файл виконуваним. Для цього введіть це:

chmod +x ~/python/on.py

Нарешті, додамо це до нашого .bashrc скрипту в нашому домашньому каталозі:

nano ~/.bashrc

Сторінка внизу файлу та додайте ці два рядки:

wait
~/python/on.py

Тепер натисніть CTRL + x, а потім натисніть Enter, щоб зберегти. Увімкніть Bluetooth-динамік і перезавантажте Raspberry Pi.

Щасти!

-nitrolinux


Дякуємо за ваш коментар Я також повинен натиснути кнопку "Sink Audio" в інтерфейсі, чи є альтернатива CLI для цього також?
Den3243

Я оновив свою оригінальну відповідь.
Джейсон Вудруф

1
Дякую за дуже детальне пояснення! Працює як шарм.
Den3243

Я радий, що це спрацювало!
Джейсон Вудруф

не вдасться цей сценарій вийти з ладу через нескінченну рекурсію між blue_it та очікуванням?
Кевін Чен

4

Я виявив, що з pulseaudio5 є актуальні проблеми, особливо якщо мова йде про відтворення аудіо через Bluetooth. Як такий, я пропоную замість того, щоб налагоджувати їх, коли вони приходять разом, просто використовувати PulseAudio6 для того, що ви хочете.

Я створив репо, яке автоматизує все, що внизу, тож вам не потрібно робити всю роботу з ногами, але якщо ви все ще налаштовані на самостійне виконання роботи, продовжуйте знизу.

Репо: https://github.com/BaReinhard/a2dp_bluetooth

Встановити процес:

git clone https://github.com/bareinhard/a2dp_bluetooth
cd a2dp_bluetooth/a2dp_source
./configure

Зачекайте, поки завершиться процес установки та перезавантажте. Після завершення вам потрібно буде спочатку з'єднати, довіритись та підключити свій пристрій. Після початкового часу вам потрібно буде лише увімкнути пристрій.

З'єднання, довіра та підключення:

sudo bluetoothctl
[bluetooth]# power on
[bluetooth]# agent on
[bluetooth]# default-agent
[bluetooth]# scan on
[bluetooth]# pair XX:XX:XX:XX:XX
[bluetooth]# trust XX:XX:XX:XX:XX
[bluetooth]# connect XX:XX:XX:XX:XX
[bluetooth]# exit

-------------------- Повна інструкція: --------------------

Компіляція PulseAudio 6

Додайте наступні файли

/etc/init.d/pulseaudio

#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          pulseaudio esound
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Should-Start:      udev network-manager
# Should-Stop:       udev network-manager
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start the PulseAudio sound server
# Description:       System mode startup script for
#                    the PulseAudio sound server.
### END INIT INFO

DAEMON=/usr/local/bin/pulseaudio
PIDDIR=/var/run/pulse
PIDFILE=$PIDDIR/pid
DAEMONUSER=pulse
PATH=/sbin:/bin:/usr/sbin:/usr/bin

test -x $DAEMON || exit 0

. /lib/lsb/init-functions

pulseaudio_start () {
        log_daemon_msg "Starting system PulseAudio Daemon"
        if [ ! -d $PIDDIR ]; then
                mkdir -p $PIDDIR
                chown $DAEMONUSER:$DAEMONUSER $PIDDIR
        fi
        start-stop-daemon -x $DAEMON -p $PIDFILE --start -- --system --disallow-exit --disallow-module-loading=0 --daemonize --log-target=syslog --high-priority
        status=$?
        if [ -e /var/run/pulse/.esd_auth ]; then
                chown pulse:pulse-access /var/run/pulse/.esd_auth
                chmod 640 /var/run/pulse/.esd_auth
        fi
        if [ -e /var/run/pulse/.pulse-cookie ]; then
                chown pulse:pulse-access /var/run/pulse/.pulse-cookie
                chmod 640 /var/run/pulse/.pulse-cookie
        fi
        log_end_msg ${status}
}

pulseaudio_stop () {
        log_daemon_msg "Stopping system PulseAudio Daemon"
        start-stop-daemon -p $PIDFILE --stop --retry 5 || echo -n "...which is not running"
        log_end_msg $?
}

case "$1" in
        start|stop)
                pulseaudio_${1}
                ;;
        restart|reload|force-reload)
                if [ -s $PIDFILE ] && kill -0 $(cat $PIDFILE) >/dev/null 2>&1; then
                        pulseaudio_stop
                        pulseaudio_start
                fi
                ;;
        force-stop)
                pulseaudio_stop
                killall pulseaudio || true
                sleep 2
                killall -9 pulseaudio || true
                ;;
        status)
                status_of_proc -p $PIDFILE "$DAEMON" "system-wide PulseAudio" && exit 0 || exit $?
                ;;
        *)
                echo "Usage: /etc/init.d/pulseaudio {start|stop|force-stop|restart|reload|force-reload|status}"
                exit 1
                ;;
esac

exit 0

/etc/init.d/bluetooth

#!/bin/sh -e
### BEGIN INIT INFO
# Provides:            bluetooth
# Required-Start:      $local_fs $syslog dbus
# Required-Stop:       $local_fs $syslog
# Default-Start:       2 3 4 5
# Default-Stop:        0 1 6
# Short-Description:   Starts bluetooth daemons
### END INIT INFO

. /lib/lsb/init-functions

DESC=bluetoothd
DAEMON=/usr/libexec/bluetooth/bluetoothd
#SSD_OPTIONS="--oknodo --quiet --exec $DAEMON --plugin=a2dp"
SSD_OPTIONS="--oknodo --quiet --exec $DAEMON" #Change to this if you want media control using DBus at the expense of volume control 
HCI=hci0

case "${1}" in
    start)
       log_daemon_msg "Starting Bluetooth daemon bluetoothd..."
       start-stop-daemon --start --background $SSD_OPTIONS
       log_progress_msg "${DAEMON}"

       hciconfig $HCI up > /dev/null 2>&1
       log_end_msg 0
       ;;

    stop)
        log_daemon_msg "Stopping Bluetooth daemon bluetoothd..."
        start-stop-daemon --stop $SSD_OPTIONS
        log_progress_msg "${DAEMON}"
        log_end_msg 0
       ;;

    restart)
       ${0} stop
       sleep 1
       ${0} start
       ;;

    status)
        status_of_proc "$DAEMON" "$DESC" && exit 0 || exit $?
       ;;

    *)
         echo "Usage: ${0} {start|stop|restart|status}"
         exit 1
       ;;
esac

exit 0

Увімкніть нові послуги init.d і зробіть виконуваний файл

sudo chmod +x /etc/init.d/bluetooth
sudo chmod +x /etc/init.d/pulseaudio
sudo update-rc.d bluetooth defaults
sudo update-rc.d pulseaudio defaults

Переконайтеся, що у нас є всі необхідні модулі

sudo apt-get install bluez pulseaudio-module-bluetooth python-dbus libtool intltool libsndfile-dev libcap-dev libjson0-dev libasound2-dev libavahi-client-dev libbluetooth-dev libglib2.0-dev libsamplerate0-dev libsbc-dev libspeexdsp-dev libssl-dev libtdb-dev libbluetooth-dev intltool autoconf autogen automake build-essential libasound2-dev libflac-dev libogg-dev libtool libvorbis-dev pkg-config python -y

Перейдіть у домашній каталог та встановіть json-c з джерела git (потрібно для PA6)

cd ~
git clone https://github.com/json-c/json-c.git
cd json-c
./configure 
make
sudo make install

Перейдіть до домашньої каталоги та встановіть libsndfile з джерела git

git clone git://github.com/erikd/libsndfile.git
cd libsndfile
./autogen.sh
./configure --enable-werror
make
sudo make install

Переконайтеся, що Bluetooth здійснює пошук ( sudo hciconfig hci0 piscanзастарілий)

cat << EOT | sudo tee -a /etc/bluetooth/main.conf
[Policy]
AutoEnable=true
EOT

Перейдіть у домашній каталог та встановіть PulseAudio 6 з джерела git

git clone --branch v6.0 https://github.com/pulseaudio/pulseaudio
cd pulseaudio
sudo ./bootstrap.sh
sudo make
sudo make install
sudo ldconfig

Переконайтесь, що пульс є у всіх необхідних групах

sudo addgroup --system pulse
sudo adduser --system --ingroup pulse --home /var/run/pulse pulse
sudo addgroup --system pulse-access
sudo adduser pulse audio
sudo adduser root pulse-access
sudo adduser pulse lp

Оновіть /etc/pulse/system.paі /etc/pulse/daemon.confвиглядайте так:

/etc/pulse/system.pa

#!/usr/bin/pulseaudio -nF
#
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

# This startup script is used only if PulseAudio is started in system
# mode.

### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
 #load-module module-udev-detect
 load-module module-udev-detect tsched=0
.else
### Use the static hardware detection module (for systems that lack udev/hal support)
load-module module-detect
.endif

### Load several protocols
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix
.endif
load-module module-native-protocol-unix

### Automatically restore the volume of streams and devices
load-module module-stream-restore
load-module module-device-restore

### Automatically restore the default sink/source when changed by the user
### during runtime
### NOTE: This should be loaded as early as possible so that subsequent modules
### that look up the default sink/source get the right value
load-module module-default-device-restore

### Automatically move streams to the default sink if the sink they are
### connected to dies, similar for sources
load-module module-rescue-streams

### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink

### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle

### Enable positioned event sounds
load-module module-position-event-sounds

### Automatically load driver modules for Bluetooth hardware
.ifexists module-bluetooth-discover.so
    load-module module-bluetooth-discover
.endif
load-module module-bluetooth-policy
load-module module-switch-on-connect

/etc/pulse/daemon.conf

# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA.

## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for
## more information. Default values are commented out.  Use either ; or # for
## commenting.

; daemonize = no
; fail = yes
; allow-module-loading = yes
; allow-exit = yes
; use-pid-file = yes
; system-instance = no
; local-server-type = user
; enable-shm = yes
; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
; lock-memory = no
; cpu-limit = no

; high-priority = yes
; nice-level = -15

; realtime-scheduling = yes
; realtime-priority = 5

exit-idle-time = -1
; scache-idle-time = 20

; dl-search-path = (depends on architecture)

; load-default-script-file = yes
; default-script-file = /etc/pulse/default.pa

; log-target = auto
; log-level = notice
; log-meta = no
; log-time = no
; log-backtrace = 0

# resample-method defaults to  speex-float-1 on most architectures,
# speex-fixed-1 on ARM
; resample-method = speex-float-1
resample-method = ffmpeg
enable-remixing = no
enable-lfe-remixing = no

; flat-volumes = yes

; rlimit-fsize = -1
; rlimit-data = -1
; rlimit-stack = -1
; rlimit-core = -1
; rlimit-as = -1
; rlimit-rss = -1
; rlimit-nproc = -1
; rlimit-nofile = 256
; rlimit-memlock = -1
; rlimit-locks = -1
; rlimit-sigpending = -1
; rlimit-msgqueue = -1
; rlimit-nice = 31
; rlimit-rtprio = 9
; rlimit-rttime = 1000000

default-sample-format = s16le
default-sample-rate = 44100
;alternate-sample-rate = 48000
default-sample-channels = 2
; default-channel-map = front-left,front-right

default-fragments = 10
default-fragment-size-msec = 10

; enable-deferred-volume = yes
; deferred-volume-safety-margin-usec = 8000
; deferred-volume-extra-delay-usec = 0

Налаштування udev Правило

Відредагуйте /etc/udev/rules.d/99-com.rulesта додайте наступні два рядки:

SUBSYSTEM=="input", GROUP="input", MODE="0660"
KERNEL=="input[0-9]*", RUN+="/usr/local/bin/bluez-udev"

Створіть /usr/local/bin/bluez-udev

/ usr / local / bin / bluez-udev

#!/bin/bash
name=$(sed 's/\"//g' <<< $NAME)
#exit if not a BT address
if [[ ! $name =~ ^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$ ]]; then exit 0;  fi

bt_name=`grep Name /var/lib/bluetooth/*/$name/info | awk -F'=' '{print $2}'`

audio_sink=bluez_source.$(sed 's/:/_/g' <<< $name)

action=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
logger "Action: $action"
if [ "$action" = "add" ]; then
    logger "[$(basename $0)] Bluetooth device is being added [$name] - $bt_name"
    logger "[$(basename $0)] Patching $audio_source into ALSA sink #$audio_sink"
    #hciconfig hci0 noscan
    bluetoothctl << EOT
discoverable off
EOT
    # Grab Card Number
    PACARD=`pactl list cards | grep "Card #" | sed "s/Card #//"`

    # Grab Sink Input if it exists
    audio_source=`pactl pactl list sink-inputs | grep "Sink Input" | sed "s/Sink Input #//"`
    if [ $audio_source = "" ];then
        sleep 5
        audio_source=`pactl pactl list sink-inputs | grep "Sink Input" | sed "s/Sink Input #//"`

    fi
    pactl set-sink-volume $audio_sink 65537
    if [ $audio_source != "" ]; then
        pactl set-source-volume $audio_source 90%
    fi
    pactl set-card-profile $PACARD a2dp_sink


    pactl set-default-sink $audio_sink





    # loop back this source to the default sink
    handle=$(pactl load-module module-loopback source=$audio_source sink=$audio_sink)
    logger "[$(basename $0)] PulseAudio module-loopback returned handle [$handle]"
    logger "$bt_name"


fi

if [ "$action" = "remove" ]; then
    # Grab Sink Input if it exists
    audio_source=`pactl pactl list sink-inputs | grep "Sink Input" | sed "s/Sink Input #//"`
    if [ $audio_source = "" ];then
        sleep 5
        audio_source=`pactl pactl list sink-inputs | grep "Sink Input" | sed "s/Sink Input #//"`

    fi
    pactl set-sink-volume 0 65537
    if [ $audio_source = "" ]; then
#        pactl set-default-sink 0
        pactl set-source-volume $audio_source 90%
    else
        pactl move-sink-input $audio_source 0 
    fi

    logger "[$(basename $0)] Bluetooth device is being removed [$name] - $bt_name"
    #hciconfig hci0 pscan

    bluetoothctl << EOT
discoverable on
EOT

    # remove any loopback modules assigned to this source
    # only required for USB sound cards, which PulseAudio will not automatically remove
    for handle in $(pactl list short modules | grep module-loopback | grep source=$audio_source | cut -f 1); do
        logger "[$(basename $0)] Unloading module-loopback with handle [$handle]"
        pactl unload-module $handle
    done

    sleep 5
    amixer cset numid=3 80%
    amixer cset numid=3 80%
fi

Переконайтесь, що bluez-udev виконується

sudo chmod +x /usr/local/bin/bluez-udev

Підсумок

Що тут робиться?

  • Створення служб init.d для Bluetooth та pulseaudio та їх включення
  • Встановлення залежностей для PulseAudio6
  • Компіляція PulseAudio6 та додавання користувача імпульсу до необхідних груп (більшість вже зроблено)
  • Налаштуйте daemon.conf та system.pa для завантаження належних модулів
  • Створіть правило udev, щоб запускати bluez-udev кожного разу підключення пристрою. bluez-udev перевіряє, чи пристрій є пристроєм Bluetooth, якщо він намагається підключити поточне відтворювальне аудіо до раковини Bluetooth, створеного pulseaudio. Після відключення Bluetooth він перемістить потік назад до раковини за замовчуванням, або раковина 0. Там у вас є все-таки, що тепер у вас повинен бути автоматично підключений Bluetooth-пристрій, правило bluez-udev автоматично підключить музику, що відтворюється, до нової підключений Bluetooth-пристрій. Звичайно, якщо це здається страшним

1

Ви намагалися створити сценарій Bash, який використовує hcitool для підключення?

#!/bin/bash
sudo hcitool cc [speaker Bluetooth address]


Додайте права на виконання цього файлу, а потім додайте його в cron (ви можете вибрати будь-який час).

Це працювало для мене, коли я намагався підключитися до клавіатури Bluetooth. Я не впевнений, чи буде це працювати для оратора (не впевнений, чи це інший протокол). Сподіваюся, це допомагає!


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.