通过蓝牙在Android中接收音频蓝牙、音频、Android

2023-09-12 03:56:52 作者:遥不可及的梦

我想创建一个Android应用程序,它能够接收音频流。我想到了使用A2DP规范的,但好像Android不支持A2DP片。貌似有很多人多数民众赞成寻找这个问题的解决方案。但是,我们收到一个普通的比特流,然后将数据转换成音频的应用程序?我想通过RFCOMM(SPP蓝牙配置文件)接收PCM或MP3数据流,然后使用AudioTrack玩。

I want to create an Android application that is capable of receiving an audio stream. I thought of using the A2DP profile, but is seems as if Android doesn't support A2DP sink. Looks like there are a lot of people that's searching for a solution for this problem. But what about receiving an ordinary bit stream, and then convert the data into audio in the application? I was thinking of receiving an PCM or Mp3 data stream via the RFCOMM (SPP Bluetooth profile), and then play it using AudioTrack.

首先,我怎么通过RFCOMM收到我的Andr​​oid手机的比特流?而且有可能通过RFCOMM接收比特流为PCM或MP3流?

First, how do I receive a bit stream on my Android phone via the RFCOMM? And is it possible to receive a bit stream via RFCOMM as a PCM or Mp3 stream?

其次,如果这是不可能通过RFCOMM接收的位流作为一个PCM或MP3播放流,如何将接收到的比特流为音频?

Second, if it isn't possible to receive a bit stream via RFCOMM as a PCM or Mp3 stream, how do I convert the received bit stream into audio?

三,如何将接收到的数据转换成声音并同时播放音频,在实时?我可以只使用onDataReceived?

Third, how do I convert the received data into audio AND play the audio simultaneously, in "real time"? Can I just use onDataReceived?

需要明确的是,我没兴趣使用A2DP模式的!我希望通过RFCOMM(SPP蓝牙配置文件)以流数据。所接收的数据流将在PCM或MP3播放。我觉得写我自己的应用程序,但如果有谁知道一个应用程序来解决这个我会很高兴听到它!我使用了Android 2.3姜饼。

To be clear, I'm not interested of using the A2DP profile! I want to stream the data via the RFCOMM (SPP Bluetooth profile). The received data stream will be in PCM or Mp3. I thought of writing my own app, but if anyone knows of an app to solve this I'd be glad to hear about it! I'm using Android 2.3 Gingerbread.

/约翰尼

推荐答案

否。的尝试编写处理这不会成为解决方案的Andr​​oid应用程序。至少,如果你想使用 A2DP汇的作用。

事实是,Android的,正如你所说的,没有实现的API调用来 的BlueZ (蓝牙堆栈Android使用到果冻豆4.1)关于 A2DP汇的能力。你必须自己实现这些功能。我会尽力来指导你,因为我也有兴趣在这样做我自己,在不久的过去。

The fact is that Android, as you mentioned it, does not implement the API calls to BlueZ (the bluetooth stack Android uses till Jelly Bean 4.1) regarding A2DP sink capabilities. You have to implement them yourself. I will try to guide you, as I was also interested in doing this my self in the near past.

您具有蓝牙功能的Andr​​oid设备默认情况下,广告本身作为一个 A2DP源设备。你必须首先改变这一点,因此附近的设备可以识别您的设备作为接收器。要做到这一点,你必须修改的的 audio.conf 的文件(usally位于 的/ etc /蓝牙/ 的)并确保启用键存在和值来源连接到这个键,所以你会得到这样的:

Your bluetooth-enabled Android device is advertising itself as an A2DP source device by default. You have to change this first, so nearby devices may recognize your device as a sink. To do this, you must modify the audio.conf file (usally located in /etc/bluetooth/) and make sure the Enable key exists and the value Source is attached to this key, so you will get something like :

Enable=Source

重启,附近的设备现在应该认识到您的设备作为 A2DP汇

现在,你将不得不与互动的BlueZ以做出适当的反应,当一个A2DP源设备将开始传输音频到您的手机。

Now you will have to interact with BlueZ to react appropriately when an A2DP source device will start to stream audio to your phone.

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

Android and BlueZ are talking to each other via D-BUS. In fact, Android connects to the DBUS_SYSTEM channel and listens to every BlueZ advertisement, such as events, file descriptors ...

我记得有成功绑定我自己使用的是本机应用程序这个D-BUS渠道,得到了访问各种事件中的BlueZ张贴。这是比较容易实现利用作为参考,的BlueZ API可用此处。如果你走这条路,你就必须建立一个本地应用程序(C / C ++),并编译它为您的平台。你必须能够使用要做到这一点的的Andr​​oid NDK

I remember having successfully bound my self using a native application to this d-bus channel and got access to the various events BlueZ was posting. This is relatively easy to achieve using as reference, the BlueZ API available here. If you go this way, you will have to build a native application (C/C++) and compile it for your platform. You must be able to do this using the Android NDK.

如果您发现很难使用 D-BUS ,你可以尝试处理您的沟通,D-BUS这个Java库我刚刚发现:的 http://jbluez.sourceforge.net/ 。我从来没有使用它,但它是值得在我看来一试。

If you find it difficult to use D-BUS, you can try this Java library I just found that handles the communication to D-BUS for you : http://jbluez.sourceforge.net/. I have never used it but it is worth a try in my opinion.

你真正需要做的是找出当一个A2DP源装置配对到您的手机,当他开始串流音乐。你可以检索到D-BUS这些事件。一旦有人会尝试将音乐,你需要告诉的BlueZ你的本机应用程序要处理它。有一个pretty的好文件,解释事件,您应该处理要做到这一点的流量。该文件是可访问的here.你感兴趣的一部分来自第7页上面例子中的接收器应用程序的的PulseAudio 上,但它可能是您的应用程序也是如此。

What you really have to do is find out when an A2DP source device is paired to your phone and when he starts to stream music. You can retrieve these events through D-BUS. Once somebody will try to stream music, you need to tell BlueZ that your native application is going to handle it. There is a pretty good document that explains the flow of events that you should handle to do this. This document is accessible here. The part you're interested in comes on page 7. The sink application in the given example is PulseAudio but it could be your application as well.

会的BlueZ转发在UNIX插座时,你会调用 org.bluez.MediaTransport.Acquire 方法。阅读此套接字上会给你被远程设备目前传出的所有数据。但我记得已经告诉一个人工作的堆栈的BlueZ读此套接字上的数据是不是PCM纯音频,但EN codeD音频内容,而不是。这些数据一般都设有codeD在一个名为 SBC 的(低复杂度的子带编码)的。

BlueZ will forward you a UNIX socket when you will call the org.bluez.MediaTransport.Acquire method. Reading on this socket will give you the data that are currently streamed by the remote device. But I remember having been told by a guy working on the BlueZ stack that the data read on this socket are not PCM pure audio, but encoded audio content instead. The data are generally encoded in a format called SBC (Low Complexity Subband Coding).

解码SBC是不是很困难,你可以找到一个去codeR 这里。

Decoding SBC is not very difficult, you can find a decoder right here.

最终的步骤是将PCM音频转发给您的扬声器。

The ultimate step would be to forward the PCM audio to your speakers.

为prevent你,你可以使用 D-BUS 二进制文件应该在可你的Andr​​oid系统。他位于 /系统/斌的

To prevent you from getting stuck and in order to test your application in an easier manner, you can use the d-bus binary that should be available on your Android system. He is located in /system/bin.

快速测试,你可以做任何事情之前作出上述可能是:

Quick tests you can make before doing anything of the above might be :

获取设备列表:

DBUS-发送--system --dest = org.bluez --print回复/   org.bluez.Manager.GetProperties

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

这将返回适配器与它们的路径的数组。一旦你有这些路径(S),您可以检索所有搭配适配器(S)的蓝牙设备列表。

This returns an array of adapters with their paths. Once you have these path(s) you can retrieve the list of all the bluetooth devices paired with your adapter(s).

获取配对设备:

DBUS-发送--system --print回复--dest = org.bluez   /组织/的bluez / {PID} / hci0 org.bluez.Adapter.GetProperties

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

这让你whithin的设备阵列现场配对的设备列表。

This gives you the list of paired devices whithin the Devices array field.

一旦你有配对到您的蓝牙适配器的设备列表,你可以知道,如果它连接到AudioSource接口。

Once you have the list of devices paired to your Bluetooth Adapter, you can know if it is connected to the AudioSource interface.

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

DBUS-发送--system --print回复--dest = org.bluez   /组织/的bluez / {PID} / hci0 / dev_XX_XX_XX_XX_XX_XX   org.bluez.AudioSource.GetProperties   org.bluez.Manager.GetProperties

PS5暂不支持蓝牙音频设备 索尼自家耳机也无法使用

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

希望这有助于。