web-dev-qa-db-fra.com

Recevez de l'audio via Bluetooth en Android

Je veux créer une application Android qui est capable de recevoir un flux audio. J'ai pensé à utiliser le profil A2DP, mais il semble que Android doesn 'Android t prend en charge le récepteur A2DP. Il semble que beaucoup de gens recherchent une solution à ce problème. Mais qu'en est-il de la réception d'un flux binaire ordinaire, puis de convertir les données en audio dans l'application? Je pensais recevoir un PCM ou Flux de données MP3 via le RFCOMM (profil Bluetooth SPP), puis lecture à l'aide d'AudioTrack.

Tout d'abord, comment puis-je recevoir un flux binaire sur mon Android via le RFCOMM? Et est-il possible de recevoir un flux binaire via RFCOMM en tant que flux PCM ou Mp3?

Deuxièmement, s'il n'est pas possible de recevoir un flux binaire via RFCOMM en tant que flux PCM ou MP3, comment puis-je convertir le flux binaire reçu en audio?

Troisièmement, comment convertir les données reçues en audio ET lire l'audio simultanément, en "temps réel"? Puis-je simplement utiliser onDataReceived?

Pour être clair, je ne suis pas intéressé à utiliser le profil A2DP! Je souhaite diffuser les données via le RFCOMM (profil Bluetooth SPP). Le flux de données reçu sera en PCM ou en Mp3. J'ai pensé à écrire ma propre application, mais si quelqu'un connaît une application pour résoudre ce problème, je serais heureux d'en entendre parler! J'utilise Android 2.3 Gingerbread.

/ Johnny

30
Johnny

Non. Essayer d'écrire une Android application qui gère cela ne sera pas la solution. Au moins si vous souhaitez utiliser A2DP Sink rôle.

Le fait est qu'Android, comme vous l'avez mentionné, n'implémente pas les appels d'API à BlueZ (la pile Bluetooth Android utilise jusqu'à Jelly bean 4.1 ) En ce qui concerne A2DP sink capacités. Vous devez les mettre en œuvre vous-même. Je vais essayer de vous guider, car j'étais également intéressé à le faire moi-même dans un passé proche.

Votre appareil compatible Bluetooth Android appareil se présente comme A2DP source périphérique par défaut. Vous devez d'abord changer cela, afin que les appareils à proximité puissent reconnaître votre appareil comme un puits. Pour ce faire, vous devez modifier le fichier audio.conf (généralement situé dans /etc/bluetooth /) et assurez-vous que la clé Enable existe et que la valeur Source est attachée à cette clé, vous obtiendrez donc quelque chose comme:

Enable=Source

Redémarrez, les appareils à proximité devraient désormais reconnaître votre appareil comme A2DP sink.

Vous devrez maintenant interagir avec BlueZ pour réagir de manière appropriée lorsqu'un périphérique source A2DP commencera à diffuser de l'audio sur votre téléphone.

Android et BlueZ se parlent via D-BUS. En fait, Android se connecte au canal DBUS_SYSTEM et écoute toutes les publicités BlueZ, telles que les événements, les descripteurs de fichiers ...

Je me souviens avoir réussi à me lier avec une application native à ce canal d-bus et avoir eu accès aux différents événements que BlueZ publiait. Ceci est relativement facile à réaliser en utilisant comme référence, l'API BlueZ disponible ici . Si vous procédez de cette façon, vous devrez créer une application native (C/C++) et la compiler pour votre plate-forme. Vous devez pouvoir le faire en utilisant le Android NDK.

Si vous avez du mal à utiliser D-BUS, vous pouvez essayer ceci Java que je viens de trouver et qui gère la communication avec D-BUS pour vous: http://jbluez.sourceforge.net/ . Je ne l'ai jamais utilisé mais ça vaut le coup d'essayer à mon avis.

Ce que vous devez vraiment faire, c'est savoir quand un appareil source A2DP est couplé à votre téléphone et quand il commence à diffuser de la musique. Vous pouvez récupérer ces événements via D-BUS. Une fois que quelqu'un essaiera de diffuser de la musique, vous devez dire à BlueZ que votre application native va la gérer. Il existe un très bon document qui explique le flux d'événements que vous devez gérer pour ce faire. Ce document est accessible ici . La partie qui vous intéresse se trouve à la page 7. L'application réceptrice dans l'exemple donné est PulseAudio mais elle pourrait aussi être votre application.

BlueZ vous transmettra un socket UNIX lorsque vous appellerez le org.bluez.MediaTransport.Acquire méthode. La lecture sur cette prise vous donnera les données actuellement diffusées par le périphérique distant. Mais je me souviens avoir été informé par un gars travaillant sur la pile BlueZ que les données lues sur cette prise ne sont pas du son pur PCM, mais du contenu audio codé à la place. Les données sont généralement codées dans un format appelé SBC (codage de sous-bande à faible complexité).

Le décodage SBC n'est pas très difficile, vous pouvez trouver un décodeur ici .

L'ultime étape serait de transmettre l'audio PCM à vos haut-parleurs.

Pour vous éviter de rester coincé et pour tester votre application plus facilement, vous pouvez utiliser le d-bus binaire qui devrait être disponible sur votre Android. Il se trouve dans /system/bin.

Les tests rapides que vous pouvez effectuer avant de faire quoi que ce soit ci-dessus peuvent être:

Liste Obtenir les appareils:

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

Cela renvoie un tableau d'adaptateurs avec leurs chemins. Une fois que vous disposez de ces chemins, vous pouvez récupérer la liste de tous les appareils Bluetooth associés à votre ou vos adaptateurs.

Obtenez les appareils jumelés:

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

Cela vous donne la liste des appareils couplés dans le champ Tableau des appareils.

Une fois que vous avez la liste des appareils couplés à votre adaptateur Bluetooth, vous pouvez savoir s'il est connecté à l'interface AudioSource.

Connectez les appareils à l'interface 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

J'espère que cela t'aides.

42
Halim Qarroum

Une autre solution consiste à utiliser HandsFreeProfile.

dans Android, BluetoothHeadset y travaille. Attendez que l'état passe à BluetoothHeadset.STATE_AUDIO_CONNECTED.

alors vous pouvez enregistrer de l'audio à partir d'un casque Bluetooth.

    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

[Non pertinent mais fonctionne] Ce hack ne sert que le streaming mp3 via le hotspot WIFI (Je l'utilise dans ma voiture qui n'a que AUX entrée ):

  1. Installez l'application AirSong ,
  2. Activez le point d'accès wifi,
  3. Connectez l'autre appareil à ce point d'accès,
  4. Accédez à 192.168.43.1:8088 à partir du navigateur de l'appareil et vous y êtes.

(vous vous demandez pourquoi "192.168.43.1" uniquement? car c'est la passerelle par défaut de tout appareil connecté à Android Hotspot)

1
Devaroop

audio.conf semble être manquant dans Android 4.2.2?

0
WoodsLink

Pour recevoir le flux audio pcm via rfcomm, vous pouvez utiliser le flux de code comme une explication expliquée ( Lecture du fichier audio en C et transfert via Bluetooth pour jouer en Android Piste audio ) , avec un changement. change freq utilisé lors de l'initialisation de 44100 à 22050

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

remarque: ce streaming contient toujours du bruit mais votre

"recevoir un flux de données PCM via le RFCOMM (profil Bluetooth SPP), puis le lire à l'aide d'AudioTrack."

marchera.

0
sphynx