我决定用AudioRecord
而不是MediaRecorder
录制音频,以达到最高质量。问题是,应用程序因某些原因无法运行。有2个按钮:记录和播放,记录用于开始和停止录制(使用新线程),播放应该使用MediaPlayer
播放文件。
码:
public class MyActivity extends Activity {
AudioRecord recorder = null;
int SAMPLE_RATE = 44100;
int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
int SOURCE = MediaRecorder.AudioSource.MIC;
int CONFIG = AudioFormat.CHANNEL_IN_MONO;
int BUFFER_SIZE;
boolean isRecording = false;
boolean isPlaying = false;
String currentFileDir;
byte[] b;
File file;
OutputStream FOS;
int count =0;
MediaPlayer mediaPlayer;
Thread recordThread;
private Button recordButton;
private Button playButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
currentFileDir = getFilesDir().getAbsolutePath() + "Record.pcm";
recordButton = (Button)findViewById(R.id.RecordButton);
recordButton.setOnClickListener(new MyOCL());
playButton = (Button)findViewById(R.id.PlayButton);
playButton.setOnClickListener(new MyOCL());
}
protected void record(){
file = new File(currentFileDir);
BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE, CONFIG, ENCODING);
recorder = new AudioRecord(SOURCE, SAMPLE_RATE, CONFIG, ENCODING, BUFFER_SIZE);
isRecording = true;
b = new byte[BUFFER_SIZE];
try{
FOS = new FileOutputStream(file);
}
catch (Exception e){Log.e("Open FOS", "new failed");}
while (isRecording){
recorder.read(b, 0, BUFFER_SIZE);
try{
FOS.write(b, count * BUFFER_SIZE, BUFFER_SIZE);
count++;
}
catch (Exception e){Log.e("write FOS", "write failed");}
}
try {
FOS.close();
}
catch (Exception e){Log.e("close FOS", "close failed");}
}
private class MyOCL implements View.OnClickListener{
@Override
public void onClick(View view){
switch(view.getId()){
case R.id.PlayButton:
if(isPlaying == false){
playButton.setText("Stop Playing");
setPlaying();
mediaPlayer.start();
}
else {
playButton.setText("Start Playing");
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer.reset();
}
break;
case R.id.RecordButton:
if(isRecording == false) {
recordThread = new Thread(new Runnable() {
@Override
public void run() {
record();
}
});
recordThread.start();
recordButton.setText("Stop Recording");
}
else{
recordButton.setText("Start recording");
isRecording = false;
}
break;
}
}
}
protected void setPlaying(){
try{
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
mediaPlayer.setDataSource(currentFileDir);
mediaPlayer.prepare();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//mediaPlayer.start();
}
catch (Exception e){
Log.e("Play initialize", "Can't call prepare function" + e.getMessage());
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
这是我的代码,对我有用:
public class MainActivity extends Activity
{
AudioRecord record = null;
AudioTrack track = null;
boolean isRecording;
int sampleRate = 44100;
Button startRecord, stopRecord, playRecord = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
startRecord = (Button) findViewById(R.id.start_recording);
stopRecord = (Button) findViewById(R.id.stop_recording);
playRecord = (Button) findViewById(R.id.play_recording);
startRecord.setOnClickListener(new StartRecordListener());
stopRecord.setOnClickListener(new StopRecordListener());
playRecord.setOnClickListener(new PlayRecordListener());
stopRecord.setEnabled(false);
}
private void startRecord()
{
File recordFile = new File(Environment.getExternalStorageDirectory(), "Record.pcm");
try
{
recordFile.createNewFile();
OutputStream outputStream = new FileOutputStream(recordFile);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
record = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
record.startRecording();
while (isRecording)
{
int numberOfShort = record.read(audioData, 0, minBufferSize);
for (int i = 0; i < numberOfShort; i++)
{
dataOutputStream.writeShort(audioData[i]);
}
}
record.stop();
dataOutputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void playRecord()
{
File recordFile = new File(Environment.getExternalStorageDirectory(), "Record.pcm");
int shortSizeInBytes = Short.SIZE / Byte.SIZE;
int bufferSizeInBytes = (int) (recordFile.length() / shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try
{
InputStream inputStream = new FileInputStream(recordFile);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int i = 0;
while (dataInputStream.available() > 0)
{
audioData[i] = dataInputStream.readShort();
i++;
}
dataInputStream.close();
track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes, AudioTrack.MODE_STREAM);
track.play();
track.write(audioData, 0, bufferSizeInBytes);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public class StartRecordListener implements View.OnClickListener
{
@Override
public void onClick(View v)
{
Thread recordThread = new Thread(new Runnable()
{
@Override
public void run()
{
isRecording = true;
MainActivity.this.startRecord();
}
});
recordThread.start();
startRecord.setEnabled(false);
stopRecord.setEnabled(true);
}
}
public class StopRecordListener implements View.OnClickListener
{
@Override
public void onClick(View v)
{
isRecording = false;
startRecord.setEnabled(true);
stopRecord.setEnabled(false);
}
}
public class PlayRecordListener implements View.OnClickListener
{
@Override
public void onClick(View v)
{
MainActivity.this.playRecord();
}
}
}
XML布局包含3个按钮,其中包含以下ID:start_recording,stop_recording,play_recording
并添加以下权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
祝你好运,我希望你没关系,我在上面的代码中使用了3个按钮。