2012-02-27 09:15
10413人阅读
评论(13)
收藏
举报
分类:
因为上一篇博客代码有点太多,就单开了,这两天主要在看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);
- }
- }
- 猜你在找
- 13楼 我想我还有梦 2015-04-22 10:45发表 [回复]
 - 现在这个还有人关注吗 ,少类库,跑步起来。
- 12楼 z0810 2014-07-14 09:53发表 [回复]
 - 最近也在研究这个,求demo,QQ:1467581753 . 感谢。
- 11楼 shengfakun1234 2014-06-10 21:51发表 [回复]
 - media_jni这个类库可以发一个吗?1002168636@qq.com
- 10楼 util_c 2014-06-10 21:44发表 [回复]
 - 发个DEMO给我行吗?605858069@qq.com
- 9楼 u011355656 2014-03-11 16:20发表 [回复]
 - 求“media_jni”内库感激不尽!!
- 8楼 cool_wuli 2014-02-27 21:45发表 [回复]
 - 同求demo576660144@qq.com
- 7楼 zyayy 2014-01-06 15:43发表 [回复]
 - 兄弟,android初学者 最近遇到音频压缩的问题 能否发个demo学习下啊 450459217@qq.com
- 6楼 yuanxiaodon 2013-12-10 16:46发表 [回复]
 - 求Demo1269396188@qq.com
- 5楼 tangshengji 2013-11-18 15:17发表 [回复]
 - 朋友,把这个Demo发给我呗,谢谢了:
393019384@qq.com
- 4楼 parrzhang 2013-07-11 22:09发表 [回复]
 - System.loadLibrary("media_jni");
这个类库是在哪里的
- 3楼 gene 2013-04-18 17:32发表 [回复]
 - 朋友你好,你给我一个demo嘛
genehang@163.com
- 2楼 devin_sz 2013-02-02 17:47发表 [回复]
 - 兄弟,遇到了声音压缩的问题,能否发个demo给我
devin_sz@yeah.net
- 1楼 buaakuan 2012-03-19 20:55发表 [回复]
 - 你好,我是android初学者,24行的"media_jni"是什么呢,这个在本地有默认的吗?需要编写它的代码吗?
|