起因

只是其中一个简单的需求:

在蓝牙耳机上通过树莓派播放音乐,且可以用 Python 控制暂停 / 音量 / 进度等。

这就花费了一个晚上的时间。而且,过程 十分令人恼火 。走了不知道多少弯路,以前大多问题都是面向 Google 即可解决的,但现在得自己试错,很多时候都是觉得已经把所有可能都琢磨了一遍还是毫无进展。

另外想提一嘴的是,越来越讨厌 CSDN 这样的博客平台。就算是 博客园 都比这样封闭的平台好上不少。自定义主题没有也就算了;代码块必须要登录复制也就算了,虽然说已经够恶心的了;我无法理解,某些文章需要关注才能展开(虽然这功能也许是博主选择启用的,不过 CSDN 加入这样的特性也使它的封闭属性++)。


于是本着知识共享的精神,在深夜走完这段弯路写下这篇文章。希望对因这些问题而困惑甚至抓狂,正在网上寻找解决方案的人一点解脱。以下内容注重于解决,而非理论分析。想要更深入了解其中原理的朋友,这要靠你自己了。

Raspberry Pi 4B (armv7l+) Raspbian 10 (buster)Raspberry Pi Zero W (armv6l) Raspberry Pi OS Lite 11 (bullseye) 测试通过。

安装 Bluez-alsa

蓝牙音频会用到这个库。

sudo apt install bluealsa

如果你用的 Raspbian 发行版基于 Debian 11 (bullseye) 及以上的版本,默认的 apt 安装源是无法安装的。

血泪教训:把 "/etc/apt/" 下的 "sources.list" 和 "sources.list.d/raspi.list" 中的源地址中,"bullseye" 等标明版本的地方换成 "buster" 。然后 sudo apt update。之后即可正常安装 Bluez-alsa装完记得马上改回来,否则下次装东西又得出错。

运行 Bluez-alsa

我是在 root 身份的 screen 中直接运行 "bluealsa" 就扔在一边。你可以试试将它运行成服务,应该是没问题的。

如果不运行 bluealsa ,在 bluetoothctl 中执行 "pair " 没有问题,不过到 "connect " 时会立即报错。

配置默认音频

在 "/etc/asound.conf" 或 "~/.asoundrc" (针对某个用户) 中,填写这样的配置:

pcm.!default {
	type bluealsa
	device AA:BB:CC:DD:EE:FF  # 蓝牙设备的 MAC 地址
	profile a2dp
}

然后重启之前的 bluealsa 进程。

到这一步,可以测试下之前的配置是否正确:

aplay test.wav  # 测试音频需要自行准备且必须为 wav 格式,默认的情况

在 pygame 中播放音频

首先安装 合适版本pygame

这里顺带说一下,如果发现没有安装 pip (比如说用的是 lite 版本的发行版),请在 apt 中安装 python3-pip

如果安装后者时报错,称依赖的 Python 版本必须 < 3.8 之类的,上一步改了 apt 源之后可能没改回来。别问我怎么知道的,我因为这个经历了龟速下载重装 Python。

>>> import pygame
pygame 2.1.2 (SDL 2.0.14, Python 3.7.3)
Hello from the pygame community. https://www.pygame.org/contribute.html
>>>

大概像这样。 pygameSDL 的大版本应该 >= 2 。否则调用 alsa 时会出现各种奇怪问题。最好是最新版吧。

如果在执行 pygame.mixer.init() 时报错,则需要安装与 SDL 2 有关的依赖。

sudo apt install libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0
# 此解决方法来源:<https://stackoverflow.com/a/66872381>

测试需要连接蓝牙耳机进行。否则提示找不到设备等等的错误。

最后

以上都没有问题的话,那么你应该能顺利在蓝牙耳机中听到测试音乐了。晚上搞了这么久,弄好之后瘫坐在树莓派旁边听了首歌。音质一般,也没有感觉十分释然。不过总算是完成了计划中的一个,小环节。

顺便再花了一个小时水了这么篇文章,就已经很晚了。说实话下午也是在走弯路,甚至还不如现在。现在起码是能用树莓派 + 蓝牙耳机 在纯终端环境下听歌了,下午却只是花了约四个小时,否定了一个猜想罢了。说不值吧,派出了一个错误选项;说值吧,四个小时学了点用不着的东西 。