package com.android.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class TestRecroderFS extends Activity implements OnClickListener{
/** Called when the activity is first created. */
Button startRecording, stopRecording, startPlaying, stopPlaying;
boolean isRecording = false;// 是否录放的标记
boolean isPlaying = false;
RecordAudio recordTask;
PlayAudio playTask;
TextView statusTextView;
File recordingFile;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
statusTextView = (TextView) this.findViewById(R.id.TextView);
startRecording = (Button) this.findViewById(R.id.startRecording);
startRecording.setOnClickListener(this);
stopRecording = (Button) this.findViewById(R.id.stopRecording);
stopRecording.setOnClickListener(this);
startPlaying = (Button) this.findViewById(R.id.startPlaying);
startPlaying.setOnClickListener(this);
stopPlaying = (Button) this.findViewById(R.id.stopPlaying);
stopPlaying.setOnClickListener(this);
stopRecording.setEnabled(false);
startPlaying.setEnabled(false);
stopPlaying.setEnabled(false);
File path = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() );
path.mkdirs();
try {
recordingFile = File.createTempFile("recording", ".pcm", path);
} catch (IOException e) {
throw new RuntimeException("Could not create file on SD card", e);
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == startRecording) {
record();
} else if (v == stopRecording) {
stopRecording();
} else if (v == startPlaying) {
play();
} else if (v == stopPlaying) {
stopPlaying();
}
}
public void play() {
startPlaying.setEnabled(false);
playTask = new PlayAudio();
playTask.execute();
stopPlaying.setEnabled(true);
statusTextView.setText(playTask.getStatus().toString());
}
public void stopPlaying() {
isPlaying = false;
stopPlaying.setEnabled(false);
startPlaying.setEnabled(true);
// playTask.cancel(isPlaying);
statusTextView.setText(playTask.getStatus().toString());
}
public void record() {
startRecording.setEnabled(false);
stopRecording.setEnabled(true);
startPlaying.setEnabled(true);
recordTask = new RecordAudio();
recordTask.execute();
statusTextView.setText(recordTask.getStatus().toString());
}
public void stopRecording() {
isRecording = false;
startRecording.setEnabled(true);
stopRecording.setEnabled(false);
statusTextView.setText(recordTask.getStatus().toString());
}
private class PlayAudio extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
isPlaying = true;
int bufferSize = AudioTrack.getMinBufferSize(8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
byte[] audiodata = new byte[bufferSize];
try {
DataInputStream dis = new DataInputStream( new
BufferedInputStream(new FileInputStream( recordingFile)));
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC, 8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize,
AudioTrack.MODE_STREAM);
/**
* AudioTrack中有MODE_STATIC和MODE_STREAM两种分类。
*
* STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack中。
*
* 这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到PCM数据,
* 然后write到audiotrack。
*
* 这种方式的坏处就是总是在JAVA层和Native层交互,效率损失较大。
*
* 而STATIC的意思是一开始创建的时候,就把音频数据放到一个固定的buffer,然后直接传给audiotrack,
*
* 后续就不用一次次得write了。AudioTrack会自己播放这个buffer中的数据。
*
* 这种方法对于铃声等内存占用较小,延时要求较高的声音来说很适用。
*/
audioTrack.play();
while (isPlaying && dis.available() > 0) {
int i = 0;
while(dis.available() > 0 && i < audiodata.length) {
audiodata[i]= dis.readByte();
i++;
}
//必须经过audioTrack将数据写入混频器才能播放
audioTrack.write(audiodata, 0,audiodata.length);
}
dis.close();
startPlaying.setEnabled(false);
stopPlaying.setEnabled(true);
} catch (Throwable t) {
Log.e("AudioTrack", "Playing failed");
}
return null;
}
}
class RecordAudio extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
isRecording = true;
try {
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(
recordingFile)));
int bufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, 8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize);
byte[] buffer = new byte[bufferSize];
byte[] tmpBuf = null;
audioRecord.startRecording();
int bufferReadResult = 0;
int r = 0;
while (isRecording) {
bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
for (int i = 0; i < bufferReadResult; i++) {
dos.writeByte(buffer[i]);
}
tmpBuf = new byte[bufferReadResult];
System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);
publishProgress(new Integer(r));
r++;
}
audioRecord.stop();
dos.close();
} catch (Throwable t) {
Log.e("AudioRecord", "Recording failed");
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
statusTextView.setText(progress[0].toString());
}
protected void onPostExecute(Void result) {
startRecording.setEnabled(true);
stopRecording.setEnabled(false);
startPlaying.setEnabled(true);
}
}
}
Android AudioRecorderFS Demo.zip
版权申诉
28 浏览量
2022-07-03
11:18:59
上传
评论
收藏 55KB ZIP 举报
reg183
- 粉丝: 1815
- 资源: 1万+
最新资源
- vscode-1.64.1.tar源码文件
- vscode-1.64.0.tar源码文件
- vscode-1.52.0.tar源码文件
- Music-Player +PlayerActivity+ rockplayer+ SeeJoPlayer 播放器JAVA源码
- vscode-1.46.0.tar源码文件
- 最近很火植物大战僵尸杂交版2.08苹果+安卓+PC+防闪退工具V2+修改工具+高清工具+通关存档整合包更新
- 超级好用的截图工具PixPin,可录制Gif图
- Screenshot_2024-05-21-17-06-42-64_2332cb9b27b851b548ba47a91682926c.jpg
- 毕业设计参考 - 基于树莓派、OpenCV及Python的人脸识别
- node-v18.20.2-linux-arm64
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈