gpt4 book ai didi

android - 无法从蓝牙麦克风获取音频

转载 作者:搜寻专家 更新时间:2023-11-01 09:21:49 26 4
gpt4 key购买 nike

我想从蓝牙耳机获取音频并在蓝牙耳机上播放。我可以在 lollipop(5.1.1)(Samsung note 3 neo) 上执行此操作,但它不适用于 android(7.0)(Redmi Note 4)。我首先创建一个音轨,然后启动一个新线程以从麦克风读取音频。首先,它开始从音素中读取音频。单击蓝牙按钮后,它会启动蓝牙 SCO。

有人能帮忙吗?


package surya.com.audiorecord;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;

/**
* Sample that demonstrates how to record from a Bluetooth HFP microphone using {@link AudioRecord}.
*/
public class BluetoothRecordActivity extends AppCompatActivity {

private static final String TAG = BluetoothRecordActivity.class.getCanonicalName();

private static final int SAMPLING_RATE_IN_HZ = 16000;

private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;

private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;

/**
* Factor by that the minimum buffer size is multiplied. The bigger the factor is the less
* likely it is that samples will be dropped, but more memory will be used. The minimum buffer
* size is determined by {@link AudioRecord#getMinBufferSize(int, int, int)} and depends on the
* recording settings.
*/
private static final int BUFFER_SIZE_FACTOR = 2;

/**
* Size of the buffer where the audio data is stored by Android
*/
private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLING_RATE_IN_HZ,
CHANNEL_CONFIG, AUDIO_FORMAT) * BUFFER_SIZE_FACTOR;

/**
* Signals whether a recording is in progress (true) or not (false).
*/
private final AtomicBoolean recordingInProgress = new AtomicBoolean(false);


private AudioRecord recorder = null;

private AudioManager audioManager;

private Thread recordingThread = null;

private Button startButton;

private Button stopButton;

private Button bluetoothButton;
AudioTrack mAudioTrack;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth);

audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
try {
outputBufferSize = AudioTrack.getMinBufferSize(16000,
AudioFormat.CHANNEL_IN_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, outputBufferSize, AudioTrack.MODE_STREAM);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mAudioTrack.setVolume(100);
}
mAudioTrack.play();
} catch (Exception e) {
e.printStackTrace();
}


startButton = (Button) findViewById(R.id.btnStart);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startRecording();
}
});

stopButton = (Button) findViewById(R.id.btnStop);
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopRecording();
}
});


bluetoothButton = (Button) findViewById(R.id.btnBluetooth);
bluetoothButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
activateBluetoothSco();
}
});


requestAudioPermissions();


}

int outputBufferSize;

@Override
protected void onResume() {
super.onResume();

ButtonEnableSetters();

registerReceiver(bluetoothStateReceiver, new IntentFilter(
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED));
}

private void ButtonEnableSetters() {
runOnUiThread(new Runnable() {
@Override
public void run() {
bluetoothButton.setEnabled(calculateBluetoothButtonState());
startButton.setEnabled(calculateStartRecordButtonState());
stopButton.setEnabled(calculateStopRecordButtonState());
}
});
}

@Override
protected void onPause() {
super.onPause();

stopRecording();
unregisterReceiver(bluetoothStateReceiver);
}

private void startRecording() {
// Depending on the device one might has to change the AudioSource, e.g. to DEFAULT
// or VOICE_COMMUNICATION
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
SAMPLING_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT, BUFFER_SIZE);

recorder.startRecording();

recordingInProgress.set(true);
try {
recordingThread = new Thread(new RecordingRunnable(), "Recording Thread");
recordingThread.start();

} catch (Exception e) {
e.printStackTrace();
}
ButtonEnableSetters();

}

private void stopRecording() {
if (null == recorder) {
return;
}

recordingInProgress.set(false);

recorder.stop();

recorder.release();

recorder = null;

recordingThread = null;

ButtonEnableSetters();

}

private void activateBluetoothSco() {
if (!audioManager.isBluetoothScoAvailableOffCall()) {
Log.e(TAG, "SCO ist not available, recording is not possible");
return;
}

if (!audioManager.isBluetoothScoOn()) {
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
}
}

private void bluetoothStateChanged(BluetoothState state) {
Log.i(TAG, "Bluetooth state changed to:" + state);

if (BluetoothState.UNAVAILABLE == state && recordingInProgress.get()) {
stopRecording();
}
ButtonEnableSetters();


}

private boolean calculateBluetoothButtonState() {
return !audioManager.isBluetoothScoOn();
}

private boolean calculateStartRecordButtonState() {
return audioManager.isBluetoothScoOn() && !recordingInProgress.get();
}

private boolean calculateStopRecordButtonState() {
return audioManager.isBluetoothScoOn() && recordingInProgress.get();
}

private class RecordingRunnable implements Runnable {

@Override
public void run() {
if (mAudioTrack != null) {
if (mAudioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
mAudioTrack.play();
} else {
mAudioTrack.stop();
mAudioTrack.flush();

mAudioTrack.play();
}
}

// final File file = new File(Environment.getExternalStorageDirectory(), "recording.pcm");
final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);

while (recordingInProgress.get()) {
int result = recorder.read(buffer, BUFFER_SIZE);
if (result 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay!
// recordAudio();
activateBluetoothSco();
startRecording();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "Permissions Denied to record audio", Toast.LENGTH_LONG).show();
}
return;
}
}
}

private final BroadcastReceiver bluetoothStateReceiver = new BroadcastReceiver() {

private BluetoothState bluetoothState = BluetoothState.UNAVAILABLE;

@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
switch (state) {
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
Log.i(TAG, "Bluetooth HFP Headset is connected");
handleBluetoothStateChange(BluetoothState.AVAILABLE);
break;
case AudioManager.SCO_AUDIO_STATE_CONNECTING:
Log.i(TAG, "Bluetooth HFP Headset is connecting");
handleBluetoothStateChange(BluetoothState.UNAVAILABLE);
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
Log.i(TAG, "Bluetooth HFP Headset is disconnected");
handleBluetoothStateChange(BluetoothState.UNAVAILABLE);
break;
case AudioManager.SCO_AUDIO_STATE_ERROR:
Log.i(TAG, "Bluetooth HFP Headset is in error state");
handleBluetoothStateChange(BluetoothState.UNAVAILABLE);
break;
}
}

private void handleBluetoothStateChange(BluetoothState state) {
if (bluetoothState == state) {
return;
}

bluetoothState = state;
bluetoothStateChanged(state);
}
};

}

这是项目源码 https://bitbucket.org/surya945/audiorecord

最佳答案

  • 欢迎使用 stackoverflow
  • 我认为你的问题与
  • 有关
  • build.gardle(module:app) 中的 TargetSdkVersion
  • 检查这个

enter image description here

关于android - 无法从蓝牙麦克风获取音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54492486/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com