gpt4 book ai didi

java - 如何将麦克风音频流式传输到同一设备 throw 扬声器

转载 作者:行者123 更新时间:2023-12-02 01:06:48 26 4
gpt4 key购买 nike

我正在尝试从麦克风获取音频并通过连接到辅助设备的扬声器进行流式传输我使用了此代码,但它在录音机的初始化中不起作用但我真正的问题是“这是正确的方法还是有更好的方法”以及如何解决初始化音频的问题

public class MainActivity extends AppCompatActivity {


private static final String TAG = "MainActivity";
// the buttons for start and Stop BoadCast
Button mStartBoadCast;
Button mStopBoadCast;

// variables for audio recording
AudioRecord recorder;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_DEFAULT;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
private boolean status = true;

// audio instance is meant for playing audio input from stream
private AudioTrack speaker;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//init layout views
initViews();

// init start boadcast method with the button
initStartBoadCast();

// init stop boadcast method with the button
initStartBoadCast();

}

private void initStartBoadCast() {
mStartBoadCast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startBoadCast();
}
});
}

private void initStopBoadCast() {
mStartBoadCast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopBoadCast();
}
});
}

private void stopBoadCast() {
//todo: add the function to stop boad casr
status = false;
recorder.release();
speaker.release();

}

private void startPlayingAudio(byte[] buffer, int minBufSize) {

status = true;


speaker = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, minBufSize, AudioTrack.MODE_STREAM);

speaker.play();

while (status) {

speaker.write(buffer, 0, minBufSize);
Log.d("VR", "Writing buffer content to speaker");


}


}

private void startBoadCast() {


status = true;


Log.d("VS", "Socket Created");

byte[] buffer = new byte[minBufSize];


recorder = findAudioRecord();
Log.d("VS", "Recorder initialized");


recorder.startRecording();


while (status) {


//reading data from MIC into buffer
minBufSize = recorder.read(buffer, 0, buffer.length);

/**
* here we finished recording then we will start to play the recorded audio
*/
startPlayingAudio(buffer, minBufSize);

System.out.println("MinBufferSize: " + minBufSize);
}


}

private void initViews() {
mStartBoadCast = findViewById(R.id.start_boadcast);
mStopBoadCast = findViewById(R.id.stop_boadcast);
}


private static int[] mSampleRates = new int[]{8000, 11025, 22050, 44100};

public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[]{AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT}) {
for (short channelConfig : new short[]{AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO}) {
try {
Log.d(TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
+ channelConfig);
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);

if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);

if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
return recorder;
}
} catch (Exception e) {
Log.e(TAG, rate + "Exception, keep trying.", e);
}
}
}
}
return null;
}


}

最佳答案

交易是在细节上的,你没有告诉我们这怎么行不通或者它会给出什么样的错误。我必须做一个类似的程序,这就是我所做的。

首先是音频类:

class audio {

AudioRecord arec;
AudioTrack atrack;
private volatile boolean isRecording= false;

private static int buffer_size;
//final short[] buffer = new short[buffersize];
//short[] readbuffer = new short[buffersize];


private int sample_rate;//the rate of recording used to initialise AudioRecord
private int[] msample_rates = new int[]{44100, 22050, 11025, 8000};

private short audio_format;
private short[] audio_formats = new short[]{AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT};

private short channel_config;
private short[] channel_configs = new short[]{AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO};
private short channelOutConfig;

public AudioRecord findAudioRecord(){
for (int rate_f : msample_rates){
for (short audioformat_f : audio_formats){
for (short channelconfig_f : channel_configs){

try {
Log.i("AudioC", "Attempting rate : "+ rate_f + "Hz, bits: " + audioformat_f + ", Channel: " + channelconfig_f);
int buffersize_f = AudioRecord.getMinBufferSize(rate_f, channelconfig_f, audioformat_f);

Log.i("AudioC", "Buffersize: " + buffersize_f);
if (buffersize_f != AudioRecord.ERROR_BAD_VALUE){
//Check of we can instantiate and have a success
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, rate_f, channelconfig_f, audioformat_f, buffersize_f);

Log.i("AudioC", "Recorder State Value: " + recorder.getState());
if(recorder.getState() == AudioRecord.STATE_INITIALIZED){
Log.i("Audio", "Success");
//global values
buffer_size = buffersize_f;
sample_rate = rate_f;
audio_format = audioformat_f;
channel_config = channelconfig_f;

if (channelconfig_f == AudioFormat.CHANNEL_IN_MONO) channelOutConfig = AudioFormat.CHANNEL_OUT_MONO;
else channelOutConfig = AudioFormat.CHANNEL_OUT_STEREO;
return recorder;
}

}
}catch (Exception e){
Log.i("AudioC", rate_f + " Exception, keep trying." + e);
}
}
}
}
Log.i("AudioC", "Failed to initialise the audio record state");
return null;

}

public void run(){

isRecording = true;
//initialization
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);

//getValidSampleRates();
// int buffersize = AudioRecord.getMinBufferSize(sample_rate,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
// arec = new AudioRecord(MediaRecorder.AudioSource.MIC,sample_rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize);
//The above lines were replaced by a looping function in order to test every occurrence of rate,audioformat and channelconfig which is usually different for different adroid devices
arec = findAudioRecord();//Still failed to initialize the Audio Recorder


atrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
sample_rate,
channelOutConfig,
audio_format,
buffer_size,
AudioTrack.MODE_STREAM);
atrack.setPlaybackRate(sample_rate);
//run
byte[] buffer = new byte[buffer_size];
arec.startRecording();
atrack.play();

while (isRecording){
arec.read(buffer, 0, buffer_size);
atrack.write(buffer, 0,buffer.length);
}
arec.release();
atrack.release();
}


public void stop(){
isRecording= false;
arec.stop();
atrack.stop();
arec.release();
atrack.release();
}

}

然后从 Activity (主 Activity )的线程或 Intent 服务中调用它,以避免应用程序卡住。线程示例:

class playerTask implements Runnable{

public audio mic_player = new audio(); //The audio class we declared above
private Thread t;

public playerTask(){

}
public void execTask(){

t = new Thread(this,"playing_Thread");
t.start();

}
public void abortTask(){

mic_player.stop();
}

public void run(){
mic_player.run();

}

}

然后根据您的 Activity ,

public class YourActivity extends AppCompatActivity {

ToggleButton onOff;
boolean playing = false;


// Once the app start recording, the recording thread freezes the screen because of the while loop, the it works
//directly with the main thread hence doesnt release the hand until forced to stop
//For that we need to create it's own thread hence being able to play sound without freezing the remaining of the app
//private Handler myHandler


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_main);

//Handler

//Route the sound to the AUX only and always
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(false);
audioManager.setWiredHeadsetOn(true);
audioManager.setBluetoothScoOn(false);

final playerTask pl_task = new playerTask();
/////Use a toggle button to start or stop the recording///You could use anything
onOff = (ToggleButton)findViewById(R.id.OnOff);
onOff.setTextOff("PLAY");
onOff.setTextOn("STOP");
onOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonview, boolean isCheked){
//Running thread

if (isCheked){
messagefield.setText("Playing");
pl_task.execTask(); ///Start streaming

}
else{
messagefield.setText("Not Playing");
pl_task.abortTask(); ///Stop streaming

}
}
});

}

以下是您需要请求的权限:

   <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

关于java - 如何将麦克风音频流式传输到同一设备 throw 扬声器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57722744/

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