33

オーディオ ストリームを受信できる Android アプリケーションを作成したいと考えています。A2DP プロファイルを使用することを考えましたが、Android は A2DP シンクをサポートしていないようです。この問題の解決策を探している人がたくさんいるようです。しかし、通常のビット ストリームを受信し、そのデータをアプリケーションでオーディオに変換する場合はどうでしょうか。RFCOMM (SPP Bluetooth プロファイル) 経由で PCM または Mp3 データ ストリームを受信し、AudioTrack を使用して再生することを考えていました。

まず、Android フォンで RFCOMM 経由でビット ストリームを受信するにはどうすればよいですか? また、ビットストリームを RFCOMM 経由で PCM または Mp3 ストリームとして受信することは可能ですか?

次に、RFCOMM 経由でビット ストリームを PCM または Mp3 ストリームとして受信できない場合、受信したビット ストリームをオーディオに変換するにはどうすればよいですか?

第三に、受信したデータをオーディオに変換し、オーディオを「リアルタイム」で同時に再生するにはどうすればよいですか? onDataReceived だけを使用できますか?

明確にするために、私は A2DP プロファイルを使用することに興味はありません! RFCOMM (SPP Bluetooth プロファイル) 経由でデータをストリーミングしたい。受信したデータ ストリームは、PCM または Mp3 になります。私は自分のアプリを書くことを考えましたが、誰かがこれを解決するアプリを知っていれば、それについて聞いてうれしいです! Android 2.3ジンジャーブレッドを使用しています。

/ジョニー

4

5 に答える 5

43

いいえ。これを処理する Android アプリケーションを作成しようとしても解決にはなりません。A2DP Sink少なくともロールを使用する場合

BlueZ実際のところ、あなたが言及したように、Android は機能に関する API 呼び出し (Android が Jelly Bean 4.1 まで使用する Bluetooth スタック)を実装していませんA2DP sink。それらを自分で実装する必要があります。私も近い過去に自分でこれを行うことに興味があったので、私はあなたを案内しようとします.

Bluetooth 対応の Android デバイスはA2DP source、デフォルトでそれ自体をデバイスとしてアドバタイズしています。近くのデバイスがあなたのデバイスをシンクとして認識できるように、最初にこれを変更する必要があります。これを行うには、audio.confファイル (通常は/etc/bluetooth/Enableにあります) を変更し、キーが存在し、値がこのキーに関連付けられていることを確認する必要がありSourceます。これにより、次のような結果が得られます。

Enable=Source

再起動すると、近くのデバイスがあなたのデバイスをA2DP sink.

ここで、A2DP ソース デバイスが音声を電話にストリーミングし始めたときに適切に対応するために、BlueZ と対話する必要があります。

Android と BlueZ は を介し​​て互いに通信していD-BUSます。実際、Android は DBUS_SYSTEM チャネルに接続し、イベント、ファイル記述子などのすべての BlueZ 広告をリッスンします...

ネイティブ アプリケーションを使用して自分自身をこの d-bus チャネルにバインドすることに成功し、BlueZ が投稿したさまざまなイベントにアクセスできたことを覚えています。これは、こちらから入手できる BlueZ API を参照として使用すると、比較的簡単に実現できます。この方法では、ネイティブ アプリケーション (C/C++) をビルドし、プラットフォーム用にコンパイルする必要があります。を使用してこれを実行できる必要がありますAndroid NDK

使いにくい場合はD-BUS、D-BUS への通信を処理する Java ライブラリを試してみてください: http://jbluez.sourceforge.net/ . 私はそれを使用したことはありませんが、私の意見では試してみる価値があります。

あなたが本当にしなければならないことは、いつ A2DP ソース デバイスがあなたの携帯電話にペアリングされ、いつ彼が音楽のストリーミングを開始するかを調べることです。これらのイベントは、D-BUS を介して取得できます。誰かが音楽をストリーミングしようとすると、ネイティブ アプリケーションがそれを処理することを BlueZ に伝える必要があります。これを行うために処理する必要があるイベントの流れを説明する非常に優れたドキュメントがあります。このドキュメントは、ここからアクセスできます。関心のある部分は 7 ページにあります。この例のシンク アプリケーションは、PulseAudioあなたのアプリケーションである可能性もあります。

メソッドを呼び出すと、BlueZ は UNIX ソケットを転送しますorg.bluez.MediaTransport.Acquire。このソケットを読み取ると、リモート デバイスによって現在ストリーミングされているデータが得られます。しかし、BlueZ スタックに取り組んでいる人から、このソケットで読み取られるデータは PCM の純粋なオーディオではなく、エンコードされたオーディオ コンテンツであると言われたことを覚えています。SBC データは一般に(Low Complexity Subband Coding)と呼ばれる形式でエンコードされます。

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

これにより、Devices 配列フィールド内にペアリングされたデバイスのリストが表示されます。

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

お役に立てれば。

于 2013-03-21T23:11:54.097 に答える
2

もう 1 つの回避策は、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();
于 2014-03-14T00:20:13.490 に答える
1

[無関係だが機能する]このハックは WIFI ホットスポットを介した mp3 ストリーミングのみを提供します (私は AUX 入力しかない車で使用しています):

  1. アプリAirSongをインストールし、
  2. Wi-Fiホットスポットをオンにし、
  3. 他のデバイスをそのホットスポットに接続し、
  4. デバイスのブラウザから 192.168.43.1:8088 にアクセスすると、オンになります。

(なぜ「192.168.43.1」だけなのか疑問に思っていますか?それは、Androidホットスポットに接続されているデバイスのデフォルトゲートウェイだからです)

于 2015-04-17T10:29:38.383 に答える
0

rfcomm 経由で pcm オーディオ ストリームを受信するには、コード フローをヒントとして使用できます ( C でオーディオ ファイルを読み取り、Bluetooth 経由で転送して Android オーディオ トラックで再生します)。初期化中に使用される周波数を 44100 から 22050 に変更

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

注:このストリーミングにはまだノイズが含まれていますが、

「RFCOMM (SPP Bluetooth プロファイル) 経由で PCM データ ストリームを受信し、AudioTrack を使用して再生します。」

動作します。

于 2013-06-28T14:46:23.713 に答える
0

Android 4.2.2 で audio.conf が見つからないようですか?

于 2013-05-27T03:48:12.747 に答える