参考了一些代码,实现了局域网的实时语音对讲功能,只要同网段局域网即可通话,文字聊天,传输文件等,包含了飞鸽传输的功能。
主要是录音发送和接收播放录音比较重要。录音线程:
- public class AudioSend extends Thread {
- Person person = null;
- public AudioSend(Person person) {
- this.person = person;
- // android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
- }
- @Override
- public void run() {
- super.run();
- Socket socket = null;
- OutputStream os = null;
- AudioRecord recorder = null;
- try {
- socket = new Socket(person.ipAddress, Constant.AUDIO_PORT);
- socket.setSoTimeout(5000);
- os = socket.getOutputStream();
- // 获得录音缓冲区大小
- int bufferSize = AudioRecord.getMinBufferSize(FlyGeonApplication.getInstance().sampRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
- AudioFormat.ENCODING_PCM_16BIT);
- Log.e("", "录音缓冲区大小"+bufferSize);
- // 获得录音机对象
- recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, FlyGeonApplication.getInstance().sampRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
- AudioFormat.ENCODING_PCM_16BIT, bufferSize * 10);
- recorder.startRecording();// 开始录音
- byte[] readBuffer = new byte[640];// 录音缓冲区
- int length = 0;
- while (!isStopTalk) {
- length = recorder.read(readBuffer, 0, 640);// 从mic读取音频数据
- if (length > 0 && length % 2 == 0) {
- os.write(readBuffer, 0, length);// 写入到输出流,把音频数据通过网络发送给对方
- }
- }
- recorder.stop();
- recorder.release();
- recorder = null;
- os.close();
- socket.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
接收播放线程
- public class AudioPlay extends Thread {
- Socket socket = null;
- public AudioPlay(Socket socket) {
- this.socket = socket;
- // android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
- }
- @Override
- public void run() {
- super.run();
- try {
- InputStream is = socket.getInputStream();
- // 获得音频缓冲区大小
- int bufferSize = android.media.AudioTrack.getMinBufferSize(FlyGeonApplication.getInstance().sampRate,
- AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
- Log.e("", "播放缓冲区大小"+bufferSize);
- // 获得音轨对象
- AudioTrack player = new AudioTrack(FlyGeonApplication.getInstance().getVoiceMode(), FlyGeonApplication.getInstance().sampRate,
- AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize,
- AudioTrack.MODE_STREAM);
- // 设置喇叭音量
- player.setStereoVolume(1.0f, 1.0f);
- // 开始播放声音
- player.play();
- byte[] audio = new byte[160];// 音频读取缓存
- int length = 0;
- while (!isStopTalk) {
- length = is.read(audio);// 从网络读取音频数据
- byte[] temp = audio.clone();
- if (length > 0 && length % 2 == 0) {
- // for(int
- // i=0;i<length;i++)audio[i]=(byte)(audio[i]*2);//音频放大1倍
- player.write(audio, 0, temp.length);// 播放音频数据
- }
- }
- player.stop();
- player.release();
- player = null;
- is.close();
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
AudioTrack player = new AudioTrack(FlyGeonApplication.getInstance().getVoiceMode(), FlyGeonApplication.getInstance().sampRate,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize,
AudioTrack.MODE_STREAM);
其中第二个参数与机器有关,一般为8000。我在解决这个问题时 就是遍历一遍常见的可能数值,直到正确为止。
第一个参数是声音的播放模式,可以为听筒模式和扬声器模式。由于扬声器模式会有回音,所以一般用听筒模式即可。