android语音录制和压缩
来源:互联网 发布:万能网络监控客户端 编辑:程序博客网 时间:2024/06/05 06:18
http://blog.csdn.net/acu/article/details/7296998
这两天主要在看android语音录制和压缩转码相关知识,前端时间看见腾讯官方微博宣布,已经开放出即使聊天软件正在等待审批,但这个直接影响电话运营商,能通过的可能性应该不大,但我对这方面的技术很有兴趣,所以就试试看。其中涉及到很多声音方面的处理问题,在android中有两个类可以录制语音:AudioRecord和MediaRecorder,MediaRecorder主要是录制音频并写入文件,而AudioRecord主要是录制音频流,录制的音频流为pcm格式,关于pcm格式可以自行搜索一下,在传输过程中可以转换为amr格式,但没有相关可以类库有点麻烦,另外iphone不支持播放amr格式音频,如果需要跨两个平台可以使用AAC,压缩比也不错,音质也很好,我还没有测试过,网上评议而已。编码方面大家都推荐speex,我看了一下,需要是用System.loadLibrary加载进speex提供的类库。下面记录一下写的一个边录制边播放的一段代码吧
- package voice.hcent.com;
- import java.io.IOException;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Looper;
- import android.os.Process;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.View;
- import android.widget.Button;
- import android.widget.Toast;
- import android.media.AudioFormat;
- import android.media.AudioManager;
- import android.media.AudioRecord;
- import android.media.AudioTrack;
- import android.media.MediaRecorder;
- public class VoiceHcentActivity extends Activity {
- static {
- System.loadLibrary("media_jni");
- }
- public int frequency = 8000;
- private int rBufferSize, pBufferSize;
- private Button startSpeech;
- private AudioRecord recorder;
- private VoiceSpeech vspeech;
- private AudioTrack player;
- private boolean stopSpeech = false;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- init();
- test();
- }
- public void init(){
- try{
- startSpeech = (Button)findViewById(R.id.StartSpeech);
- //设置播放器缓冲区大小
- pBufferSize = AudioTrack.getMinBufferSize(frequency, AudioFormat.CHANNEL_CONFIGURATION_MONO,
- AudioFormat.ENCODING_PCM_16BIT);
- //获取播放器对象
- player = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
- AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
- pBufferSize, AudioTrack.MODE_STREAM);
- //设置录音缓冲区大小
- rBufferSize = AudioRecord.getMinBufferSize(frequency,
- AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
- //获取录音机对象
- recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
- frequency, AudioFormat.CHANNEL_CONFIGURATION_MONO,
- AudioFormat.ENCODING_PCM_16BIT, rBufferSize);
- }catch (Exception e) {
- String msg = "ERROR init: "+e.getStackTrace();
- VoiceHcentActivity.this.toastMsg(msg);
- }
- }
- /**
- * 开始录音
- */
- public void startRecord(){
- stopSpeech = false;
- vspeech = new VoiceSpeech();
- vspeech.start();
- }
- /**
- * 结束录音
- */
- public void stopRecord() {
- stopSpeech = true;
- }
- /**
- * 开始播放录音
- */
- public void startPlay(){
- //设置播放器音量
- player.setStereoVolume(0.7f, 0.7f);
- player.play();
- }
- /**
- * 结束播放录音
- */
- public void stopPlay(){
- player.stop();
- }
- public void test(){
- startSpeech.setOnTouchListener(new View.OnTouchListener() {
- public boolean onTouch(View arg0, MotionEvent arg1) {
- switch (arg1.getAction()) {
- case MotionEvent.ACTION_DOWN: //开始说话
- startPlay();
- startRecord();
- toastMsg("starting record!");
- break;
- case MotionEvent.ACTION_UP: //停止说话
- Log.i("hcent", "111");
- stopPlay();
- Log.i("hcent", "222");
- stopRecord();
- toastMsg("stoped record!");
- break;
- default:
- break;
- }
- return false;
- }
- });
- }
- public class VoiceSpeech extends Thread{
- @Override
- public void run() {
- super.run();
- try {
- byte[] tempBuffer, readBuffer = new byte[rBufferSize];
- int bufResult = 0;
- recorder.startRecording();
- while(!stopSpeech){
- bufResult = recorder.read(readBuffer, 0, rBufferSize);
- if(bufResult>0 && bufResult%2==0){
- tempBuffer = new byte[bufResult];
- System.arraycopy(readBuffer, 0, tempBuffer, 0, rBufferSize);
- player.write(tempBuffer, 0, tempBuffer.length);
- }
- Log.d("hcent", "get read:"+bufResult+"___"+readBuffer.length);
- }
- recorder.stop();
- Looper.prepare();
- VoiceHcentActivity.this.toastMsg("AudioSpeech have ended!");
- Looper.loop();
- } catch (Exception e) {
- String msg = "ERROR AudioRecord: "+e.getStackTrace();
- Looper.prepare();
- VoiceHcentActivity.this.toastMsg(msg);
- Looper.loop();
- }
- }
- }
- @Override
- protected void onDestroy(){
- player.release();
- recorder.release();
- super.onDestroy();
- Process.killProcess(Process.myPid());
- }
- public void toastMsg(String msg){
- Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
- Log.e("hcent", msg);
- }
- }
0 0
- android语音录制和压缩
- android语音录制和压缩
- Android语音录制和播放
- Android仿微信语音录制和播放
- Android和IOS录制mp3语音文件的方法
- Android和IOS录制mp3语音文件的方法
- android语音录制与播放
- android语音录制与播放
- Android || IOS录制mp3语音文件方法
- Android || IOS录制mp3语音文件方法
- Android 语音录制那点事
- 语音信号的录制和处理
- 仿微信语音消息的录制和播放
- Android 语音播放和录制以及转换mp3,上传服务器,ios亲测可用
- android音视频系列操作,录制,压缩
- Android 图片单选/多选、拍照、裁剪、压缩。视频选择和录制
- galleryfinal 实现Android图片单选/多选、拍照、裁剪、压缩。视频选择和录制。
- android 使用服务来窃听电话,并且通过语音录制
- Eclipse搜索快捷键
- C#如何修改List中的结构体
- 多线程与原子操作
- IOS应用开发03——自定义Cell的AccessoryButton及事件源被点击的cell行
- 嵌入式 jffs2问题“ jffs2_scan_eraseblock(): Magic和Empty Flash at”
- android语音录制和压缩
- iframe异步加载技术及性能
- mmap函数
- 二叉树的递归遍历和非递归遍历
- DICOM3.0影像文件中的平面和立体坐标信息
- mahout入门
- java对byte数组解压缩(zip,gzip,bzip2,jzlib)
- PHP 高级教程
- MySQL中使用INNER JOIN来实现Intersect并集操作