在Android中通过蓝牙接收音频

Joh*_*nny 30 streaming android bluetooth audio-streaming rfcomm

我想创建一个能够接收音频流的Android应用程序.我想过使用A2DP配置文件,但似乎Android不支持A2DP接收器.看起来有很多人在寻找这个问题的解决方案.但接收普通比特流,然后将数据转换为应用程序中的音频呢?我想通过RFCOMM(SPP蓝牙配置文件)接收PCM或Mp3数据流,然后使用AudioTrack播放它.

首先,如何通过RFCOMM在我的Android手机上接收比特流?是否可以通过RFCOMM作为PCM或Mp3流接收比特流?

其次,如果不能通过RFCOMM接收比特流作为PCM或Mp3流,我如何将接收的比特流转换为音频?

第三,如何将接收的数据转换为音频并同时"实时"播放音频?我可以使用onDataReceived吗?

要清楚,我对使用A2DP配置文件不感兴趣!我想通过RFCOMM(SPP蓝牙配置文件)传输数据.接收的数据流将采用PCM或Mp3.我想写自己的应用程序,但如果有人知道一个应用程序来解决这个问题,我很高兴听到它!我正在使用Android 2.3 Gingerbread.

/约翰尼

Hal*_*oum 42

试图写一个Android应用程序来处理这不是解决办法.至少如果你想使用A2DP Sink角色.

事实上,正如你所提到的,Android并没有实现API调用BlueZ(Android使用的蓝牙堆栈直到Jelly Bean 4.1)的A2DP sink功能.你必须自己实现它们.我会尽力指导你,因为我也有兴趣在近期做这件事.

支持蓝牙功能的Android设备A2DP source默认将自己宣传为设备.您必须先更改此设置,以便附近的设备可以将您的设备识别为接收器.要做到这一点,你必须修改audio.conf文件(通常位于/ etc/bluetooth /中),并确保Enable密钥存在并且值Source附加到此密钥,因此您将得到如下内容:

Enable=Source
Run Code Online (Sandbox Code Playgroud)

重启,附近的设备现在应该将您的设备识别为A2DP sink.

现在,当A2DP源设备开始向您的手机传输音频时,您必须与BlueZ进行交互以做出适当的反应.

Android和BlueZ通过互相交谈D-BUS.事实上,Android的连接到DBUS_SYSTEM渠道,听取每一个广告的BlueZ,如事件,文件描述符...

我记得有成功使用本地应用这个d-总线通道约束我自己,并配齐了各种事件中的BlueZ张贴.这是相对容易的使用作为参考,可用的API的BlueZ达到这里.如果你这样做,你将不得不构建一个本机应用程序(C/C++)并为您的平台编译它.你必须能够使用Android NDK.

如果您发现它很难使用D-BUS,您可以尝试使用我刚刚找到的Java库来处理与D-BUS的通信:http://jbluez.sourceforge.net/.我从未使用它,但在我看来值得一试.

您真正需要做的是找出A2DP源设备何时与您的手机配对以及何时开始播放音乐.您可以通过D-BUS检索这些事件.一旦有人尝试流式传输音乐,您需要告诉BlueZ您的本机应用程序将处理它.有一个非常好的文档可以解释为此需要处理的事件流.此文档可在此处访问.您感兴趣的部分见第7页.给定示例中的接收器应用程序是,PulseAudio但它也可能是您的应用程序.

当您调用该org.bluez.MediaTransport.Acquire方法时,BlueZ将转发您的UNIX套接字.读取此套接字将为您提供当前由远程设备流式传输的数据.但是我记得一个在BlueZ堆栈上工作的人告诉我这个套接字上读取的数据不是PCM纯音频,而是编码音频内容.通常以称为SBC (低复杂度子带编码)的格式对数据进行编码.

解码SBC并不是很困难,你可以在这里找到解码器.

最终的步骤是将PCM音频转发到扬声器.

为了防止卡住,并且为了更轻松地测试应用程序,您可以使用d-busAndroid系统上应该可用的二进制文件.他位于/ system/bin.

在执行上述任何操作之前,您可以进行快速测试:

获取设备列表:

dbus-send --system --dest = org.bluez --print-reply/org.bluez.Manager.GetProperties

这将返回一个带有路径的适配器数组.获得这些路径后,您可以检索与适配器配对的所有蓝牙设备的列表.

获得配对设备:

dbus-send --system --print-reply --dest = org.bluez/org/bluez/{pid}/hci0 org.bluez.Adapter.GetProperties

这将为您提供Devices数组字段中配对设备的列表.

获得与蓝牙适配器配对的设备列表后,您就可以知道它是否已连接到AudioSource界面.

获取连接到AudioSource接口的设备:

dbus-send --system --print-reply --dest = org.bluez/org/bluez/{pid}/hci0/dev_XX_XX_XX_XX_XX_XX org.bluez.AudioSource.GetProperties org.bluez.Manager.GetProperties

希望这可以帮助.

  • 因为 A2DP 是一种标准,默认情况下在每部手机中都使用(即它不需要任何应用程序在客户端工作)。如果您决定使用 RFCOMM,我猜您还必须提供一个客户端应用程序,该应用程序将从远程设备流式传输音频。如果您决定这样做,您还可以使用 wifi 通过常规套接字流式传输音频。Play 商店中的许多应用程序都提供了这样的功能。 (2认同)
  • 在姜饼上并不代表一个问题.您需要UNIX权限才能修改此文件并列出包含`/ system`的分区的内容,是.此外,您即将应用的更改必须在`root`中执行,因此需要为手机生根. (2认同)