web-dev-qa-db-de.com

Empfangen Sie Audio über Bluetooth in Android

Ich möchte eine Android Anwendung erstellen, die in der Lage ist, einen Audio-Stream zu empfangen. Ich habe überlegt, das A2DP-Profil zu verwenden, aber es sieht so aus, als ob Android A2DP-Senke wird nicht unterstützt. Es gibt anscheinend viele Leute, die nach einer Lösung für dieses Problem suchen. Aber wie sieht es mit dem Empfang eines normalen Bitstroms und der anschließenden Konvertierung der Daten in Audio in der Anwendung aus? Ich habe überlegt, ein PCM zu empfangen oder Mp3-Daten über das RFCOMM (SPP-Bluetooth-Profil) streamen und dann mit AudioTrack wiedergeben.

Erstens, wie kann ich auf meinem Android= Telefon einen Bit-Stream über RFCOMM empfangen? Und ist es möglich, einen Bit-Stream über RFCOMM als PCM- oder Mp3-Stream zu empfangen?

Zweitens, wenn es nicht möglich ist, einen Bitstrom über RFCOMM als PCM- oder MP3-Stream zu empfangen, wie konvertiere ich den empfangenen Bitstrom in Audio?

Drittens, wie kann ich die empfangenen Daten in Audio konvertieren UND das Audio gleichzeitig in "Echtzeit" abspielen? Kann ich nur onDataReceived verwenden?

Um es klar auszudrücken, ich bin nicht daran interessiert, das A2DP-Profil zu verwenden! Ich möchte die Daten über das RFCOMM (SPP Bluetooth-Profil) streamen. Der empfangene Datenstrom wird in PCM oder Mp3 sein. Ich habe darüber nachgedacht, eine eigene App zu schreiben, aber wenn jemand eine App kennt, um dies zu lösen, würde ich mich freuen, davon zu hören! Ich benutze Android 2.3 Gingerbread.

/ Johnny

30
Johnny

No. Der Versuch, eine Android= Anwendung zu schreiben, die dies erledigt, ist nicht die Lösung. Zumindest wenn Sie möchten die Rolle A2DP Sink verwenden.

Tatsache ist, dass Android, wie Sie bereits erwähnt haben, die API-Aufrufe von BlueZ (dem Bluetooth-Stack Android) nicht implementiert verwendet bis Jelly Bean 4.1) in Bezug auf A2DP sink - Fähigkeiten. Sie müssen sie selbst implementieren. Ich werde versuchen, Sie anzuleiten, da ich auch daran interessiert war, dies in der nahen Vergangenheit selbst zu tun.

Ihr Bluetooth-fähiges Android Gerät wirbt standardmäßig selbst als A2DP source Gerät. Sie müssen dies zuerst ändern, damit in der Nähe befindliche Geräte Ihr Gerät möglicherweise als Senke erkennen Dazu müssen Sie die Datei audio.conf ändern (normalerweise in /etc/bluetooth) /) und stellen Sie sicher, dass der Schlüssel Enable existiert und der Wert Source an diesen Schlüssel angehängt ist.

Enable=Source

Neustart, Geräte in der Nähe sollten Ihr Gerät nun als A2DP sink Erkennen.

Jetzt müssen Sie mit BlueZ interagieren, um angemessen zu reagieren, wenn ein A2DP-Quellgerät beginnt, Audio auf Ihr Telefon zu streamen.

Android und BlueZ unterhalten sich über D-BUS. Tatsächlich stellt Android eine Verbindung zum DBUS_SYSTEM-Kanal her und hört jede BlueZ-Werbung ab, z. B. Ereignisse, Dateideskriptoren ...

Ich erinnere mich, dass ich mich mit einer nativen Anwendung erfolgreich an diesen D-Bus-Kanal gebunden und Zugriff auf die verschiedenen von BlueZ veröffentlichten Ereignisse erhalten habe. Dies ist relativ einfach zu erreichen, wenn als Referenz die BlueZ-API verwendet wird hier . Wenn Sie diesen Weg gehen, müssen Sie eine native Anwendung (C/C++) erstellen und für Ihre Plattform kompilieren. Dies muss mit dem Android NDK Möglich sein.

Wenn Sie Schwierigkeiten haben, D-BUS Zu verwenden, können Sie diese Java Bibliothek verwenden, die die Kommunikation mit D-BUS für Sie übernimmt: http : //jbluez.sourceforge.net/ Ich habe es noch nie benutzt, aber meiner Meinung nach ist es einen Versuch wert.

Was Sie wirklich tun müssen, ist herauszufinden, wann ein A2DP-Quellgerät mit Ihrem Telefon gekoppelt ist und wann er beginnt, Musik zu streamen. Sie können diese Ereignisse über D-BUS abrufen. Sobald jemand versucht, Musik zu streamen, müssen Sie BlueZ mitteilen, dass Ihre native Anwendung damit umgehen wird. Es gibt ein ziemlich gutes Dokument, das den Ablauf von Ereignissen erklärt, mit denen Sie sich befassen sollten, um dies zu tun. Dieses Dokument ist zugänglich hier . Der Teil, an dem Sie interessiert sind, befindet sich auf Seite 7. Die Senkenanwendung im angegebenen Beispiel ist PulseAudio, es könnte sich aber auch um Ihre Anwendung handeln.

BlueZ leitet Sie an einen UNIX-Socket weiter, wenn Sie die Methode org.bluez.MediaTransport.Acquire Aufrufen. Durch Lesen an diesem Socket erhalten Sie die Daten, die aktuell vom Remote-Gerät gestreamt werden. Aber ich erinnere mich, dass mir ein Mitarbeiter des BlueZ-Stacks erzählt hat, dass die an diesem Socket gelesenen Daten kein reines PCM-Audio sind, sondern stattdessen codierte Audioinhalte. Die Daten werden im Allgemeinen in einem Format namens SBC (Low Complexity Subband Coding) codiert.

Das Dekodieren von SBC ist nicht sehr schwierig. Sie finden einen Dekoder hier .

Der ultimative Schritt wäre, das PCM-Audio an Ihre Lautsprecher weiterzuleiten.

Um zu verhindern, dass Sie hängen bleiben, und um Ihre Anwendung einfacher testen zu können, können Sie die Binärdatei d-bus Verwenden, die auf Ihrem Android) System verfügbar sein sollte in /system/bin.

Schnelle Tests, die Sie durchführen können, bevor Sie eine der oben genannten Aktionen ausführen:

Geräteliste abrufen:

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

Dies gibt ein Array von Adaptern mit ihren Pfaden zurück. Sobald Sie über diese Pfade verfügen, können Sie die Liste aller mit Ihren Adaptern gepaarten Bluetooth-Geräte abrufen.

Holen Sie sich gekoppelte Geräte:

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

Dies gibt Ihnen die Liste der gekoppelten Geräte im Feld Geräte-Array.

Sobald Sie die Liste der Geräte mit Ihrem Bluetooth-Adapter gekoppelt haben, können Sie feststellen, ob er mit der AudioSource-Schnittstelle verbunden ist.

Verbinden Sie die Geräte mit der AudioSource-Schnittstelle:

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

Hoffe das hilft.

42
Halim Qarroum

Eine andere Möglichkeit ist die Verwendung von HandsFreeProfile.

in Android arbeitet BluetoothHeadset daran. Warten Sie, bis der Status auf BluetoothHeadset.STATE_AUDIO_CONNECTED geändert wurde.

dann können Sie Audio vom Bluetooth-Headset aufnehmen.

    mMediaRecorder = new MediaRecorder();
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mMediaRecorder.setOutputFile(mFilename);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    mMediaRecorder.start();
2
zxshi

[irrelevant, funktioniert aber] Dieser Hack dient nur zum Streamen von MP3-Dateien über WIFI-Hotspot (ich verwende ihn in meinem Auto, das nur AUX Eingaben hat ):

  1. Installiere die App AirSong ,
  2. WLAN-Hotspot einschalten,
  3. Verbinden Sie das andere Gerät mit diesem Hotspot,
  4. Greifen Sie über den Browser des Geräts auf 192.168.43.1:8088 zu, und Sie sind dabei.

(Ich frage mich, warum nur "192.168.43.1"? Dies ist das Standard-Gateway für alle Geräte, die mit Android Hotspot verbunden sind.)

1
Devaroop

die audio.conf scheint in Android 4.2.2?

0
WoodsLink

Um PCM-Audio-Streams über RFCOMM zu empfangen, können Sie den Code-Flow als erklärten Hinweis verwenden ( Audiodatei in C lesen und über Bluetooth weiterleiten, um in Android Audiotrack zu spielen ), mit a Veränderung . Ändern Sie die beim Initialisieren verwendete Frequenz von 44100 auf 22050

AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,22050,AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_8BIT,10000, AudioTrack.MODE_STREAM);

hinweis: Dieses Streaming enthält außer Ihrem noch einige Geräusche

"Empfangen eines PCM-Datenstroms über RFCOMM (SPP-Bluetooth-Profil) und anschließendes Abspielen mit AudioTrack."

wird funktionieren.

0
sphynx