Conectar automaticamente o alto-falante Bluetooth confiável

10

Segui o seguinte tutorial ( http://mygeeks014.blogspot.nl/2015/01/audio-streaming-to-bluetooth-speaker.html ) para conectar um alto-falante Bluetooth ao meu Raspberry Pi. Tudo funciona como deveria, mas o alto-falante não será reconectado automaticamente quando o Raspberry for reiniciado ou o alto-falante for ligado / desligado. No momento, reconecto manualmente o alto-falante por meio da GUI do Raspbian, mas me pergunto se existe uma solução simples para reconectar o alto-falante por meio da CLI. Depois, poderei escrever um CRON simples para reconectar o alto-falante, se ainda não estiver conectado.

Den3243
fonte

Respostas:

17

Aqui está uma explicação muito detalhada:

Den3243

Aqui está uma solução de linha de comando:

Primeiro, vamos digitalizar, emparelhar, confiar no seu dispositivo com "bluetoothctl". Para fazer isso, execute isso na linha de comando, no seu terminal:

bluetoothctl -a

Você deve obter um prompt de comando diferente, como:

[bluetooth]

Com o alto-falante BT ativado, digite o seguinte:

scan on

Em alguns instantes, você deverá ver os dispositivos BT disponíveis. Ao lado do dispositivo estará o endereço MAC, como: 00: AA: 22: BB: 33. Agora digite isso:

info <your mac address>

Exclua os caracteres maior que e menor que. O que você procura é algum tipo de associação anterior ao seu orador da BT. Você saberá que houve uma associação anterior porque o bluetoothctl mostrará informações sobre o seu dispositivo BT. Algumas dessas informações serão sobre o dispositivo emparelhado e confiável. Isso é bom.

Se o bluetoothctl reclamar que não há dispositivo, precisamos configurá-lo neste momento. Para fazer isso, digite o seguinte:

pair <your mac address>

Você deverá receber uma mensagem de sucesso sobre o pareamento do seu dispositivo com sucesso. Agora vamos confiar em nosso novo dispositivo BT. Digite isto:

trust <your mac address>

Novamente, você deve receber uma mensagem de sucesso sobre confiar. Deixe-me avisá-lo. O seu dispositivo BT pode conectar-se novamente. Não tenha medo, não queremos que ele se conecte. Vá em frente e vamos sair "bluetoothctl". Para fazer isso, digite:

quit

Agora você será levado de volta ao prompt da linha de comando. Em um post anterior, sugeri que você crie um diretório de scripts em seu diretório pessoal. Se você não tiver, vá em frente e faça isso agora. Digite isso no prompt de comando:

mkdir -p ~/scripts

Pressione enter e agora vamos criar nosso script basop de autopair. Digite isto:

nano ~/scripts/autopair

Digite este código no script:

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

Exclua os colchetes!

Agora pressione CTRL + x ao mesmo tempo e agora pressione enter para salvar o script. Precisamos torná-lo executável. Para fazer isso, digite o seguinte:

chmod +x ~/scripts/autopair

Suponho que você não use alto-falantes analógicos externos na tomada de 3,5 mm. Se isso for verdade, vamos desativar o alsa. Para fazer isso, vamos editar um arquivo no diretório / boot chamado config.txt. Para fazer isso, digite isto em seu terminal:

sudo nano /boot/config.txt

Vá até a parte inferior do arquivo e procure duas linhas que se lêem:

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

Coloque um (sinal de cerquilha #) na frente da linha que diz:

dtparam=audio=on

Se parecer:

#dtparam=audio=on

Pressione CTRL + xe pressione Enter para salvar seu arquivo.

Suponho que você tenha o pulseaudio instalado? Caso contrário, vá em frente e execute este comando na linha de comando:

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

Isso lhe dará um componente muito importante para fazer o bluetooth funcionar! Agora vamos editar nosso arquivo .bashrc em nosso diretório pessoal. Digite isto:

nano ~/.bashrc

Desça até a parte inferior e adicione esta linha:

pulseaudio --start

Pressione CTRL + xe agora pressione Enter para salvar seu arquivo.

ESTÁ BEM! Precisamos entrar no mundo Python. Eu escrevi um programa Python que observará o dispositivo bluetooth. Em resumo, ele ativará a conexão entre o RPi e o alto-falante bluetooth, assim que o alto-falante estiver ligado. E vice versa. Vamos criar um diretório chamado python no seu diretório pessoal. Para fazer isso, digite o seguinte:

mkdir -p ~/python

Agora vamos criar o arquivo de programa python. Para fazer isso, digite o seguinte:

nano ~/python/on.py

Dentro desse arquivo, precisamos copiar e colar o seguinte:

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

Agora pressione CTRL + xe pressione Enter para salvar o arquivo de programa Python. Agora precisamos tornar este arquivo executável. Para fazer isso, digite o seguinte:

chmod +x ~/python/on.py

Por fim, vamos adicionar isso ao nosso script .bashrc em nosso diretório inicial:

nano ~/.bashrc

Vá para a parte inferior do arquivo e adicione estas duas linhas:

wait
~/python/on.py

Agora pressione CTRL + xe pressione Enter para salvar. Ligue o alto-falante Bluetooth e reinicie o Raspberry Pi.

Boa sorte!

-nitrolinux

Jason Woodruff
fonte
Obrigado por seu comentário. Eu também tenho que pressionar o botão 'Sink Audio' na interface do usuário, existe uma alternativa CLI para isso também?
precisa saber é o seguinte
Eu atualizei minha resposta original.
Jason Woodruff
11
Obrigado por sua explicação muito detalhada! Funciona como um encanto.
precisa saber é o seguinte
Estou feliz que funcionou!
Jason Woodruff
esse script não funcionará devido a uma recursão infinita entre blue_it e espera?
Kevin Chen
4

Descobri que há problemas atuais com o pulseaudio5, especialmente quando se trata de reprodução de áudio por bluetooth. Como tal, proponho que, em vez de precisar depurá-los, eles simplesmente usem o PulseAudio6 para o que você deseja.

Eu criei um repositório que automatizará tudo abaixo, para que você não precise fazer todo o trabalho da perna, mas se você ainda estiver fazendo isso, continue abaixo.

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

Processo de instalação:

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

Aguarde até que o processo de instalação seja concluído e reinicie. Ao terminar, você precisará inicializar, emparelhar, confiar e conectar seu dispositivo. Após o horário inicial, você só precisará ligar o dispositivo.

Emparelhar, confiar e conectar:

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

-------------------- Passo a passo completo: --------------------

Compilando o PulseAudio 6

Adicione os seguintes arquivos

/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

Ative novos serviços init.d e torne executável

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

Verifique se temos todos os módulos necessários

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

Altere para o diretório inicial e instale o json-c a partir da fonte git (necessário para o PA6)

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

Mude para o diretório inicial e instale o libsndfile a partir do código-fonte git

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

Verifique se o Bluetooth está pesquisando ( sudo hciconfig hci0 piscanestá obsoleto)

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

Navegue para o diretório inicial e instale o PulseAudio 6 da fonte git

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

Verifique se o pulso está em todos os grupos necessários

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

Atualize /etc/pulse/system.pae /etc/pulse/daemon.confprocure o seguinte:

/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

Regra do udev da instalação

Edite /etc/udev/rules.d/99-com.rulese adicione as duas linhas a seguir:

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

Crio /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

Verifique se o bluez-udev é executável

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

Sumário

O que está sendo feito aqui?

  • Criando serviços init.d para bluetooth e pulseaudio e habilitando-os
  • Instalando dependências para o PulseAudio6
  • Compilando o PulseAudio6 e adicionando o usuário do pulso aos grupos necessários (a maioria já foi feita)
  • Configure daemon.conf e system.pa para carregar os módulos apropriados
  • Crie a regra do udev para executar o bluez-udev toda vez que um dispositivo estiver conectado. O bluez-udev verifica se o dispositivo é um dispositivo bluetooth; se for, ele tentará conectar o áudio atual de reprodução ao coletor de dispositivos bluetooth criado pelo pulseaudio. Após a desconexão do bluetooth, ele moverá o fluxo de volta para o coletor padrão, ou o coletor 0. Nesse caso, depois de tudo o que você deve ter agora um dispositivo bluetooth conectado automaticamente, a regra bluez-udev conectará automaticamente a música reproduzida ao novo dispositivo bluetooth conectado. Claro, se isso parece assustador
Brett Reinhard
fonte
1

Você já tentou criar um script Bash que usa o hcitool para se conectar?

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


Adicione direitos executáveis ​​a esse arquivo e adicione-o ao cron (você pode escolher a qualquer momento).

Isso funcionou para mim quando tentei me conectar a um teclado Bluetooth. Não tenho certeza se funcionará para um alto-falante (não tenho certeza se é um protocolo diferente). Espero que isto ajude!

ALinuxLover
fonte
0

achou isso ainda melhor

sudo bluetoothctl <<EOF
power on
discoverable on
pairable on
agent NoInputNoOutput
default-agent 
EOF
Jochnickel
fonte