3种音频捕获方式——Android开发

(一)通过意图捕获音频

适合录制无须过多处理的音频,其中很少有或没有编程控制的需要

package fly.fei;

 

import android.media.MediaPlayer;

import android.media.MediaPlayer.OnCompletionListener;

import android.net.Uri;

import android.os.Bundle;

import android.provider.MediaStore;

import android.app.Activity;

import android.content.DialogInterface;

import android.content.DialogInterface.OnClickListener;

import android.content.Intent;

import android.view.Menu;

import android.view.View;

import android.widget.Button;

 

public class IntentAudioRecorder extends Activity implements

android.view.View.OnClickListener, OnCompletionListener {

 

public static int RECODE_REQUEST = 77;// 传递给StartActivityForResult函数,从而确定任何OnActivityResult调用

 

Button createRecording, playRecording;// 两个按丢

 

Uri audioFileUri;// Uri同一资源标记符。一个Uri对象包含将由录音器活动录制的音频文件的URI

 

/**

 * 构造器

 */

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_intent_audio_recorder);

 

createRecording = (Button) this.findViewById(R.id.RecordButton);

createRecording.setOnClickListener(this);

 

playRecording = (Button) this.findViewById(R.id.PlayButton);

playRecording.setOnClickListener(this);

playRecording.setEnabled(false);

}

 

/**

 * 菜单

 */

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.activity_intent_audio_recorder, menu);

return true;

}

 

/**

 * MediaPlayer结束回调函数

 */

public void onCompletion(MediaPlayer mp) {

playRecording.setEnabled(true);

}

 

/**

 * 点击事件监听器

 */

 

public void onClick(View v) {

if (v == createRecording) {

Intent intent = new Intent(

MediaStore.Audio.Media.RECORD_SOUND_ACTION);

startActivityForResult(intent, RECODE_REQUEST);

 

} else if (v == playRecording) {

MediaPlayer mediaPlayer = MediaPlayer.create(this, audioFileUri);

mediaPlayer.setOnCompletionListener(this);

mediaPlayer.start();

playRecording.setEnabled(false);

}

}

 

/**

 * Activity结果回调函数

 */

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK && requestCode == RECODE_REQUEST) {

audioFileUri = data.getData();

playRecording.setEnabled(true);

}

}

}

 

 

 

 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent" >

 

        <Button

            android:id="@+id/RecordButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="录制" />

 

        <Button

            android:id="@+id/PlayButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="播放" />

 

    </LinearLayout>

(二)MediaRecordMediaPlayer

定制音频捕获

能够获得更大的灵活性,允许控制录制媒体的时间长度以及其他要素,但是将界面留给我们来实现

package fly.fei;

 

import java.io.File;

import java.io.IOException;

 

import android.media.MediaPlayer;

import android.media.MediaRecorder;

import android.media.MediaPlayer.OnCompletionListener;

import android.net.Uri;

import android.os.Bundle;

import android.os.Environment;

import android.provider.MediaStore;

import android.app.Activity;

import android.content.DialogInterface;

import android.content.DialogInterface.OnClickListener;

import android.content.Intent;

import android.view.Menu;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

 

public class IntentAudioRecorder extends Activity implements

android.view.View.OnClickListener, OnCompletionListener {

 

TextView statusTextView;// 状态显示

 

Button startRecording, stopRecording, playRecording, finishButton;// 录制,完成,播放,结束按钮

 

MediaRecorder recorder;// 媒体录制器

MediaPlayer player;// 媒体播放器

 

File audioFile;// 音频文件

 

/**

 * 构造器

 */

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_intent_audio_recorder);

 

init();// 初始化

}

 

/**

 * 初始化控件

 */

private void init() {

statusTextView = (TextView) this.findViewById(R.id.StatusTextView);

 

startRecording = (Button) this.findViewById(R.id.StartRecording);

stopRecording = (Button) this.findViewById(R.id.StopRecording);

playRecording = (Button) this.findViewById(R.id.PlayRecording);

finishButton = (Button) this.findViewById(R.id.FinishButton);

 

startRecording.setOnClickListener(this);

stopRecording.setOnClickListener(this);

playRecording.setOnClickListener(this);

finishButton.setOnClickListener(this);

 

stopRecording.setEnabled(false);

playRecording.setEnabled(false);

}

 

/**

 * mediaplay结束回调函数

 */

public void onCompletion(MediaPlayer mp) {

playRecording.setEnabled(true);

stopRecording.setEnabled(false);

startRecording.setEnabled(false);

statusTextView.setText("准备");

}

 

/**

 * 点击监听事件

 */

public void onClick(View v) {

if (v == finishButton) {// 结束

finish();

 

} else if (v == stopRecording) {// 完成

recorder.stop();// 停止录制

recorder.release();// 释放媒体录制器资源

 

player = new MediaPlayer();// 新建媒体播放器

player.setOnCompletionListener(this);// 回调

 

try {

player.setDataSource(audioFile.getAbsolutePath());// 要播放的媒体资源,文件的绝对路径

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

 

try {

player.prepare();// 播放器准备好,等待播放

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

 

statusTextView.setText("准备录制");

 

playRecording.setEnabled(true);

stopRecording.setEnabled(false);

startRecording.setEnabled(true);

 

} else if (v == startRecording) {

recorder = new MediaRecorder();// 新建媒体录制器

// 录制器相关设置

 

// 录制器的音频源

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);

// 录制器输出格式。THREE_GPP.3gp 可能同时包含音频和视频轨

recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

// 设置编解码器。AMR_NB自适应多速率窄带编解码器,只针对语音进行优化,采样率8kHz,码率4.75-12.2kbps

recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

 

File path = new File(Environment.getExternalStorageDirectory()// 新建路径

.getAbsolutePath() + "/Android/data/fly/fei/files/");

path.mkdirs();// 创建路径

 

try {

audioFile = File.createTempFile("recording", ".3gp", path);// 创建指定路径下的文件

} catch (IOException e) {

e.printStackTrace();

}

 

recorder.setOutputFile(audioFile.getAbsolutePath());// 指定录制器输出的文件

 

try {

recorder.prepare();// 录制器准备好录制

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

 

recorder.start();// 开始录制

statusTextView.setText("录制中");

 

playRecording.setEnabled(false);

stopRecording.setEnabled(true);

startRecording.setEnabled(false);

 

} else if (v == playRecording) {// 播放

player.start();

statusTextView.setText("播放中");

playRecording.setEnabled(false);

stopRecording.setEnabled(false);

startRecording.setEnabled(false);

}

}

 

}

 

 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent" >

 

        <TextView

            android:id="@+id/StatusTextView"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="TextView" />

 

        <Button

            android:id="@+id/StartRecording"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="录制" />

 

        <Button

            android:id="@+id/StopRecording"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="完成" />

 

        <Button

            android:id="@+id/PlayRecording"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="播放" />

 

        <Button

            android:id="@+id/FinishButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="结束" />

 

    </LinearLayout>

 

(三)AudioRecordAudioTrack

录制原始样本

可获得最大的控制性和灵活性,但是需要完成捕获和使用音频的大部分工作,可实现任何类型的音频处理或者需要合成音频

 

package fly.fei;

 

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.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

 

import android.media.AudioFormat;

import android.media.AudioManager;

import android.media.AudioRecord;

import android.media.AudioTrack;

import android.media.MediaPlayer;

import android.media.MediaRecorder;

import android.media.MediaPlayer.OnCompletionListener;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Environment;

import android.provider.MediaStore;

import android.R.integer;

import android.app.Activity;

import android.content.DialogInterface;

import android.content.DialogInterface.OnClickListener;

import android.content.Intent;

import android.util.Log;

import android.view.Menu;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

 

public class IntentAudioRecorder extends Activity implements

android.view.View.OnClickListener {

 

TextView statusTextView;// 状态显示

 

Button startRecordingButton, stopRecordingButton, startPlaybackButton,

stopPlaybackButton;// 录制,完成,播放,结束按钮

 

RecordAudio recordTask;// 内部类 --录制

PlayAudio playTask;// 内部类 ------播放

 

File recordingFile;// 音频文件

// 布尔跟踪

boolean isRecording = false;// 是否录制

boolean isPlaying = false;// 是否播放

// Audio对象配置设置

int frequency = 11025;

int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;

int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

 

/**

 * 构造器

 */

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_intent_audio_recorder);

 

init();// 初始化

}

 

/**

 * 初始化控件

 */

private void init() {

statusTextView = (TextView) this.findViewById(R.id.StatusTextView);

// 获得按钮

startRecordingButton = (Button) this

.findViewById(R.id.StartRecordingButton);

stopRecordingButton = (Button) this

.findViewById(R.id.StopRecordingButton);

 

startPlaybackButton = (Button) this

.findViewById(R.id.StartPlaybackButton);

stopPlaybackButton = (Button) this

.findViewById(R.id.StopPlaybackButton);

// 设置监听器

startRecordingButton.setOnClickListener(this);

stopRecordingButton.setOnClickListener(this);

startPlaybackButton.setOnClickListener(this);

stopPlaybackButton.setOnClickListener(this);

// 设置按钮状态

stopRecordingButton.setEnabled(false);

startPlaybackButton.setEnabled(false);

stopPlaybackButton.setEnabled(false);

// 新建路径

File path = new File(Environment.getExternalStorageDirectory()

.getAbsolutePath() + "/Android/data/fly/fei/files/");

path.mkdirs();

 

try {

recordingFile = File.createTempFile("recording2", ".pcm", path);// 创建pcm文件

} catch (IOException e) {

e.printStackTrace();

}

}

 

/**

 * 点击监听事件

 */

public void onClick(View v) {

if (v == startRecordingButton) {

record();

} else if (v == stopRecordingButton) {

stopRecording();

} else if (v == startPlaybackButton) {

play();

} else if (v == stopPlaybackButton) {

stopPlaying();

}

}

 

private void stopPlaying() {

isPlaying = false;

 

stopPlaybackButton.setEnabled(false);

startPlaybackButton.setEnabled(true);

}

 

private void play() {

startPlaybackButton.setEnabled(true);

 

playTask = new PlayAudio();

playTask.execute();

 

stopPlaybackButton.setEnabled(true);

}

 

private void stopRecording() {

isRecording = false;

}

 

private void record() {

startRecordingButton.setEnabled(false);

stopRecordingButton.setEnabled(true);

 

startPlaybackButton.setEnabled(true);

 

recordTask = new RecordAudio();

recordTask.execute();

}

 

/**

 * 播放内部类

 * 

 * @author Administrator

 * 

 */

private class PlayAudio extends AsyncTask<Void, integer, Void> {

protected Void doInBackground(Void... params) {

isPlaying = true;

 

int bufferSize = AudioTrack.getMinBufferSize(frequency,

channelConfiguration, audioEncoding);

short[] audiodata = new short[bufferSize / 4];

 

try {

DataInputStream dis = new DataInputStream(//PCM数据文件的流对象

new BufferedInputStream(new FileInputStream(

recordingFile)));

 

AudioTrack audioTrack = new AudioTrack(

AudioManager.STREAM_MUSIC, frequency,// 流类型,音频采样率

channelConfiguration, audioEncoding, bufferSize,// 通道配置,音频格式

AudioTrack.MODE_STREAM);// 模式。MODE_STATIC播放前将所有数据转到AudioTrack中;MODE_SRREAM播放时将数据持续转移到AudioTrack

audioTrack.play();

//一旦构造了AudioTrack,就需要打开音频源,将音频数据读取到缓冲区,并将它传递给AudioTrack对象

while (isPlaying && dis.available() > 0) {

int i = 0;

while (dis.available() > 0 && i < audiodata.length) {

audiodata[i] = dis.readShort();

i++;

}

audioTrack.write(audiodata, 0, audiodata.length);

}

dis.close();

 

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

 

return null;

}

 

/**

 * AsyncTask开始前调用

 */

protected void onPreExecute() {

super.onPreExecute();

startPlaybackButton.setEnabled(false);

stopPlaybackButton.setEnabled(true);

}

 

}

 

/**

 * 录制内部类

 * 

 * @author Administrator

 * 

 */

private class RecordAudio extends AsyncTask<Void, integer, Void> {

protected Void doInBackground(Void... params) {

isRecording = true;

 

try {

DataOutputStream dos = new DataOutputStream(

new BufferedOutputStream(new FileOutputStream(

recordingFile)));

 

int bufferSize = AudioRecord.getMinBufferSize(frequency,

channelConfiguration, audioEncoding);

 

AudioRecord audioRecord = new AudioRecord(

MediaRecorder.AudioSource.MIC, frequency,

channelConfiguration, audioEncoding, bufferSize);

 

short[] buffer = new short[bufferSize];//缓冲区

 

audioRecord.startRecording();

// int r = 0;

while (isRecording) {

int bufferReadResult = audioRecord.read(buffer, 0,

bufferSize);

for (int i = 0; i < bufferReadResult; i++) {

dos.writeShort(buffer[i]);

}

 

// publishProgress(new Integer(r));//不能再AsyncTack中改变UI,否则出错

// r++;

 

}

Log.e("record", "stop");

audioRecord.stop();

dos.close();

 

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

 

return null;

}

 

// private void publishProgress(Integer integer) {

// statusTextView.setText(integer.toString());

// }

/**

 * AsyncTack结束后调用

 */

protected void onPostExecute(Void result) {

super.onPostExecute(result);

startRecordingButton.setEnabled(true);

stopRecordingButton.setEnabled(false);

startPlaybackButton.setEnabled(true);

}

}

}

 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent" >

 

        <TextView

            android:id="@+id/StatusTextView"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="TextView" />

 

        <Button

            android:id="@+id/StartRecordingButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="录制" />

 

        <Button

            android:id="@+id/StopRecordingButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="完成" />

 

        <Button

            android:id="@+id/StartPlaybackButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="播放" />

 

        <Button

            android:id="@+id/StopPlaybackButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="停止" />

 

    </LinearLayout>

 

转载于:https://www.cnblogs.com/fly-higher7/archive/2013/03/17/2964214.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值