为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

小怪兽爱吃肉 2023-06-28 15:28:54
我正在尝试从麦克风获取音频并通过连接到辅助设备的扬声器进行流式传输我使用了此代码,但它在录音机的初始化中不起作用,但我真正的问题是“这是正确的方法还是有更好的方法来做到这一点“如果是如何解决初始化音频的问题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();    }
查看完整描述

1 回答

?
FFIVE

TA贡献1797条经验 获得超6个赞

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


首先是音频类:


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();

}

}


然后从活动(主活动)的线程或意图服务中调用它,以避免应用程序冻结。线程示例:


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();


}

}


然后从你的活动来看,


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" />


查看完整回答
反对 回复 2023-06-28
  • 1 回答
  • 0 关注
  • 123 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信