Получать аудио через Bluetooth в Android

Я хочу создать приложение для Android, которое может принимать аудиопоток. Я думал об использовании профиля A2DP, но похоже, что Android не поддерживает A2DP-приемник. Похоже, что есть много людей, которые ищут решение этой проблемы. Но как насчет приема обычного битового потока, а затем преобразовать данные в аудио в приложении? Я подумывал получить поток данных PCM или Mp3 через RFCOMM (профиль Bluetooth SPP), а затем воспроизвести его с помощью AudioTrack.

Во-первых, как мне получить бит-поток на моем телефоне Android через RFCOMM? И можно ли получить бит-поток через RFCOMM в качестве PCM или Mp3-потока?

Во-вторых, если невозможно получить бит-поток через RFCOMM в качестве PCM или Mp3-потока, как преобразовать полученный бит-поток в аудио?

В-третьих, как преобразовать полученные данные в аудио и воспроизводить аудио одновременно, в режиме реального времени? Можно ли использовать onDataReceived?

Чтобы быть ясным, мне не интересно использовать профиль A2DP! Я хочу передавать данные через RFCOMM (профиль Bluetooth SPP). Полученный поток данных будет в PCM или Mp3. Я думал написать собственное приложение, но если кто-нибудь знает о приложении, чтобы решить это, я был бы рад услышать об этом! Я использую Android 2.3 Gingerbread.

/Джонни

Solutions Collecting From Web of "Получать аудио через Bluetooth в Android"

Нет. Попытка написать приложение для Android, которое обрабатывает это, не будет решением. По крайней мере, если вы хотите использовать роль A2DP Sink .

Дело в том, что Android, как вы уже упоминали, не реализует вызовы API BlueZ (стек Android bluetooth использует до Jelly Bean 4.1) в отношении возможностей A2DP sink . Вы должны реализовать их самостоятельно. Я постараюсь направить вас, поскольку мне также было интересно это сделать в ближайшем прошлом.

Ваш Android-устройство с поддержкой bluetooth рекламирует себя как A2DP source устройство A2DP source по умолчанию. Сначала вы должны изменить это, поэтому поблизости устройства могут распознать ваше устройство как приемник. Чтобы сделать это, вы должны изменить файл audio.conf (обычно расположенный в / etc / bluetooth / ) и убедиться, что ключ Enable существует, и значение Source привязано к этому ключу, поэтому вы получите что-то вроде:

 Enable=Source 

Перезагрузите, находящиеся поблизости устройства должны теперь распознать ваше устройство как A2DP sink .

Теперь вам нужно будет взаимодействовать с BlueZ, чтобы реагировать соответствующим образом, когда исходное устройство A2DP начнет передавать аудио на ваш телефон.

Android и BlueZ разговаривают друг с другом через D-BUS . Фактически, Android подключается к каналу DBUS_SYSTEM и слушает каждую рекламу BlueZ, такую ​​как события, дескрипторы файлов …

Я помню, что успешно связал себя, используя собственное приложение к этому каналу d-bus и получил доступ к различным событиям, которые BlueZ публиковал. Это относительно легко достичь, используя в качестве ссылки BlueZ API, доступный здесь . Если вы пойдете так, вам придется создать собственное приложение (C / C ++) и скомпилировать его для вашей платформы. Вы должны быть в состоянии сделать это, используя Android NDK .

Если вам сложно использовать D-BUS , вы можете попробовать эту библиотеку Java, которую я только что нашел, которая обрабатывает связь с D-BUS для вас: http://jbluez.sourceforge.net/ . Я никогда не использовал его, но, на мой взгляд, стоит попробовать.

Что вам действительно нужно сделать, так это узнать, когда исходное устройство A2DP сопряжено с вашим телефоном и когда он начинает передавать музыку. Вы можете получить эти события через D-BUS. Когда кто-то попытается передать музыку, вам нужно сказать BlueZ, что ваше родное приложение будет обрабатывать его. Существует довольно хороший документ, который объясняет поток событий, с которыми вам нужно справиться. Этот документ доступен здесь . Часть, которую вас интересует, приведена на странице 7. Приложение-приемник в данном примере – PulseAudio но это может быть ваше приложение.

BlueZ отправит вам UNIX-сокет, когда вы org.bluez.MediaTransport.Acquire метод org.bluez.MediaTransport.Acquire . Чтение этого сокета даст вам данные, которые в настоящее время передаются удаленным устройством. Но я помню, что парень, работающий над стеклом BlueZ, сказал, что данные, прочитанные в этом сокете, не являются чистым звуком PCM, а закодированным аудиоконтентом. Данные, как правило, кодируются в формате SBC (низкоуровневое поддиапазонное кодирование) .

Декодирование SBC не очень сложно, вы можете найти декодер прямо здесь .

Конечным шагом будет передача звука PCM вашим динамикам.

Чтобы вы не застряли и чтобы легче протестировать ваше приложение, вы можете использовать двоичный файл d-bus который должен быть доступен в вашей системе Android. Он находится в / system / bin .

Быстрые тесты, которые вы можете сделать, прежде чем делать что-либо из вышеизложенного, могут быть следующими:

Список устройств:

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

Это возвращает массив адаптеров с их путями. После того, как у вас есть эти пути, вы можете получить список всех Bluetooth-устройств в паре с вашим адаптером (ами).

Получить сопряженные устройства:

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

Это дает вам список парных устройств в поле «Устройства».

Когда у вас есть список устройств, соединенных с вашим адаптером Bluetooth, вы можете узнать, подключен ли он к интерфейсу 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

Надеюсь это поможет.

Другая работа вокруг – использование HandsFreeProfile.

В Android, BluetoothHeadset работает над этим. Подождите, пока статус не изменится на BluetoothHeadset.STATE_AUDIO_CONNECTED.

То вы можете записывать звук с 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(); 

[Irrelevant but works] Этот хак служит только для потоковой передачи mp3 через точку доступа WIFI (я использую его в своем автомобиле, который имеет только вход AUX):

  1. Установите приложение AirSong ,
  2. Включите Wi-Fi точку доступа,
  3. Подключите другое устройство к этой точке доступа,
  4. Войдите в браузер 192.168.43.1:8088 и включите его.

(Интересно, почему «192.168.43.1» только? Потому что это шлюз по умолчанию любого устройства, подключенного к Hotspot Android)

Audio.conf, кажется, отсутствует в Android 4.2.2?

Чтобы получить поток аудио pcm через rfcomm, вы можете использовать поток кода в качестве пояснения ( чтение аудиофайла на C и пересылка по Bluetooth для воспроизведения на треке Android Audio ) с изменением. Частота изменения используется при инициализации от 44100 до 22050

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

Примечание. Эта потоковая передача по-прежнему содержит некоторый шум, но

«Получение потока данных PCM через профиль RFCOMM (профиль SPP Bluetooth), а затем воспроизведение его с помощью AudioTrack».

будет работать.