Connecter automatiquement un haut-parleur Bluetooth fiable


10

J'ai suivi le tutoriel suivant ( http://mygeeks014.blogspot.nl/2015/01/audio-streaming-to-bluetooth-speaker.html ) pour connecter un haut-parleur Bluetooth à mon Raspberry Pi. Tout fonctionne comme prévu, mais le haut-parleur ne se reconnecte pas automatiquement lorsque le Raspberry est redémarré ou que le haut-parleur est allumé / éteint. À l'heure actuelle, je reconnecte manuellement le haut-parleur via l'interface graphique Raspbian, mais je me demande s'il existe une solution simple pour reconnecter le haut-parleur via la CLI. Je pourrai alors écrire un simple CRON pour reconnecter le haut-parleur s'il n'est pas encore connecté.

Réponses:


17

Voici une explication très détaillée:

Den3243

Voici une solution en ligne de commande:

Commençons par numériser, coupler et faire confiance à votre appareil avec "bluetoothctl". Pour ce faire, exécutez ceci sur la ligne de commande, votre terminal:

bluetoothctl -a

Vous devriez obtenir une invite de commande différente comme:

[bluetooth]

Avec votre haut-parleur BT allumé, tapez ceci:

scan on

Dans quelques instants, vous devriez voir les appareils BT disponibles. À côté de l'appareil se trouve son adresse MAC, comme: 00: AA: 22: BB: 33. Tapez maintenant ceci:

info <your mac address>

Excluez les caractères supérieur et inférieur à. Ce que vous recherchez est une sorte d'association précédente avec votre enceinte BT. Vous saurez qu'il y avait une association précédente car bluetoothctl affichera des informations sur votre appareil BT. Certaines de ces informations concerneront le périphérique à coupler et à approuver. C'est bon.

Si bluetoothctl se plaint qu'il n'y a pas d'appareil, alors nous devons le configurer à ce moment. Pour ce faire, tapez ceci:

pair <your mac address>

Vous devriez voir un message de réussite concernant le couplage de votre appareil avec succès. Faisons maintenant confiance à notre nouvel appareil BT. Tapez ceci:

trust <your mac address>

Encore une fois, vous devriez voir un message de réussite sur la confiance. Permettez-moi de vous avertir. Votre appareil BT peut se connecter, puis il peut ne pas le faire. N'ayez crainte, nous ne voulons pas qu'il se connecte. Allez-y et quittons "bluetoothctl". Pour ce faire, tapez:

quit

Vous serez maintenant ramené à l'invite de ligne de commande. Dans un article précédent, je vous ai suggéré de créer un répertoire de scripts dans votre répertoire personnel. Si ce n'est pas le cas, allez-y et faites-le maintenant. Tapez ceci à l'invite de commande:

mkdir -p ~/scripts

Appuyez sur Entrée et créons maintenant notre script bash de paire automatique. Tapez ceci:

nano ~/scripts/autopair

Entrez ce code dans le script:

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

Excluez les crochets!

Appuyez maintenant sur CTRL + x en même temps, puis appuyez sur Entrée pour enregistrer le script. Nous devons le rendre exécutable. Pour ce faire, tapez ceci:

chmod +x ~/scripts/autopair

Je suppose que vous n'utilisez pas de haut-parleurs analogiques externes dans la prise 3,5 mm. Si cela est vrai, désactivons alsa. Pour ce faire, éditons un fichier dans le répertoire / boot appelé config.txt. Pour ce faire, saisissez ceci dans votre terminal:

sudo nano /boot/config.txt

Page vers le bas du fichier et recherchez deux lignes qui se lisent:

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

Placez un (signe dièse #) devant la ligne qui lit:

dtparam=audio=on

Ressembler à:

#dtparam=audio=on

Appuyez sur CTRL + x puis appuyez sur Entrée pour enregistrer votre fichier.

Je suppose que pulseaudio est installé? Sinon, allez-y et exécutez cette commande à partir de la ligne de commande:

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

Cela vous donnera un élément très important pour faire fonctionner le bluetooth! Modifions maintenant notre fichier .bashrc dans notre répertoire personnel. Tapez ceci:

nano ~/.bashrc

Page vers le bas et ajoutez cette ligne:

pulseaudio --start

Appuyez sur CTRL + x et maintenant appuyez sur Entrée pour enregistrer votre fichier.

D'ACCORD! Nous devons entrer dans le monde Python. J'ai écrit un programme Python qui surveillera le périphérique Bluetooth. En bref, il activera la connexion entre RPi et votre haut-parleur Bluetooth, une fois que votre haut-parleur Bluetooth est allumé. Et vice versa. Créons un répertoire appelé python dans votre répertoire personnel Pour ce faire, tapez ceci:

mkdir -p ~/python

Créons maintenant le fichier programme python. Pour ce faire, tapez ceci:

nano ~/python/on.py

Dans ce fichier, nous devons copier et coller les éléments suivants:

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

Appuyez maintenant sur CTRL + x puis appuyez sur Entrée pour enregistrer le fichier programme Python. Maintenant, nous devons rendre ce fichier exécutable. Pour ce faire, tapez ceci:

chmod +x ~/python/on.py

Enfin, ajoutons ceci à notre script .bashrc dans notre répertoire personnel:

nano ~/.bashrc

Page vers le bas du fichier et ajoutez ces deux lignes:

wait
~/python/on.py

Appuyez maintenant sur CTRL + x puis appuyez sur Entrée pour enregistrer. Allumez votre haut-parleur Bluetooth et redémarrez votre Raspberry Pi.

Bonne chance!

-nitrolinux


Merci pour votre commentaire. Je dois également appuyer sur le bouton «Sink Audio» dans l'interface utilisateur, existe-t-il également une alternative CLI?
Den3243

J'ai mis à jour ma réponse d'origine.
Jason Woodruff

1
Merci pour votre explication très détaillée! Fonctionne comme un charme.
Den3243

Je suis content que ça ait marché!
Jason Woodruff

ce script ne tombera-t-il pas finalement en raison d'une récursion infinie entre blue_it et l'attente?
Kevin Chen

4

J'ai constaté qu'il existe des problèmes actuels avec pulseaudio5, en particulier en ce qui concerne la lecture audio via Bluetooth. En tant que tel, je propose qu'au lieu d'avoir à déboguer ceux-ci lorsqu'ils arrivent, utilisez simplement PulseAudio6 pour ce que vous voulez.

J'ai créé un dépôt qui automatisera tout ci-dessous afin que vous n'ayez pas besoin de faire tout le travail de jambe, mais si vous êtes toujours prêt à le faire vous-même, continuez ci-dessous.

Repo: https://github.com/BaReinhard/a2dp_bluetooth

Processus d'installation:

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

Attendez que le processus d'installation soit terminé et redémarrez. Une fois terminé, vous devrez initialement coupler, faire confiance et connecter votre appareil. Après l'heure initiale, vous n'aurez plus qu'à allumer l'appareil.

Pairage, approbation et connexion:

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

-------------------- Procédure pas à pas complète: --------------------

Compilation de PulseAudio 6

Ajoutez les fichiers suivants

/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

Activer les nouveaux services init.d et rendre exécutable

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

Assurez-vous que nous avons tous les modules nécessaires

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

Passez au répertoire personnel et installez json-c à partir de git source (requis pour PA6)

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

Passez au répertoire personnel et installez libsndfile à partir de git source

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

Assurez-vous que Bluetooth recherche ( sudo hciconfig hci0 piscanest déconseillé)

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

Accédez au répertoire personnel et installez PulseAudio 6 à partir de git source

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

Assurez-vous que le pouls est dans tous les groupes nécessaires

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

Mettez à jour /etc/pulse/system.paet /etc/pulse/daemon.confregardez comme suit:

/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

Configurer la règle udev

Modifiez /etc/udev/rules.d/99-com.ruleset ajoutez les deux lignes suivantes:

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

Créer /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

Assurez-vous que bluez-udev est exécutable

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

Résumé

Que fait-on ici?

  • Créer des services init.d pour bluetooth et pulseaudio et les activer
  • Installation de dépendances pour PulseAudio6
  • Compiler PulseAudio6 et ajouter l'utilisateur Pulse aux groupes nécessaires (la plupart auront déjà été effectués)
  • Configurez daemon.conf et system.pa pour charger les modules appropriés
  • Créez une règle udev pour exécuter bluez-udev chaque fois qu'un périphérique est connecté. bluez-udev vérifie si l'appareil est un appareil bluetooth, s'il l'est, il essaiera de connecter l'audio en cours de lecture au récepteur d'appareil bluetooth créé par pulseaudio. Lors de la déconnexion Bluetooth, le flux reviendra au récepteur par défaut, ou récepteur 0. Voilà, après tout, vous devriez maintenant avoir un périphérique Bluetooth connecté automatiquement, la règle bluez-udev connectera automatiquement la musique en cours de lecture au nouveau périphérique Bluetooth connecté. Bien sûr, si cela semble intimidant

1

Avez-vous essayé de créer un script Bash qui utilise hcitool pour se connecter?

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


Ajoutez des droits exécutables à ce fichier, puis ajoutez-le à cron (vous pouvez choisir à tout moment).

Cela a fonctionné pour moi lorsque j'ai essayé de me connecter à un clavier Bluetooth. Je ne sais pas si cela fonctionnera pour un haut-parleur (je ne sais pas si c'est un protocole différent). J'espère que cela t'aides!


0

a trouvé cela encore mieux

sudo bluetoothctl <<EOF
power on
discoverable on
pairable on
agent NoInputNoOutput
default-agent 
EOF
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.