录音与播放——(AudioRecord & AudioTrack)

作者:追风剑情 发布于:2016-6-13 17:55 分类:Android

添加权限


<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />


1、新建活动

fragment_audio_main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.test.androidtest.AudioMainActivity$PlaceholderFragment" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始录音"
        android:onClick="startRecording" />
    
     <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止录音"
        android:onClick="stopRecording" />
     
     <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="播放录音"
        android:onClick="playRecording" />

</LinearLayout>


代码


package com.test.androidtest;

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 java.io.InputStream;
import java.io.OutputStream;

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.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;

public class AudioMainActivity extends Activity {
        //以下值会影响所录制音频的大小和质量
	//采样频率
	private int frequency = 11025;
	//声道配置
	private int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
	//音频编码
	private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
	
	private boolean isRecording = false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.fragment_audio_main);
	}
	
	public void startRecording(View view)
	{
		Log.d("test", "开始录音");
		Thread thread=new Thread(new Runnable()  
        {  
            @Override  
            public void run()  
            {  
                File file = new File(Environment.getExternalStorageDirectory(), "raw.pcm");//保存在SD卡上
                try{
                	file.createNewFile();
                }catch(IOException e){
                	Log.e("test", "IO Exception", e);
                }
                
                try{
                	OutputStream os = new FileOutputStream(file);
                	BufferedOutputStream bos = new BufferedOutputStream(os);
                	DataOutputStream dos = new DataOutputStream(bos);
                	
                	int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
                	short[] buffer = new short[bufferSize];
                	
                	//创建一个新的AudioRecord对象来录制音频
                	AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,//从麦克风录制原始音频
                			frequency,
                			channelConfiguration,
                			audioEncoding, bufferSize);
                	audioRecord.startRecording();//开始异步录制
                	
                	isRecording = true;
                	while(isRecording){
                		int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
                		Log.d("test", "bufferReadResult="+bufferReadResult);
                		for(int i=0; i<bufferReadResult; i++)
                			dos.writeShort(buffer[i]);
                	}
                	
                	audioRecord.stop();
                	dos.flush();
                	dos.close();
                }catch(Throwable t){
                	Log.e("test", "An error occurred during recording", t);
                }
            }  
        });  
        thread.start();
	}
	
	public void stopRecording(View view)
	{
		Log.d("test", "停止录音");
		isRecording = false;
	}
	
	public void playRecording(View view)
	{
		Log.d("test", "播放录音");
		File file = new File(Environment.getExternalStorageDirectory(), "raw.pcm");
		
		//用于存储音轨的short数组(每个short占用16位,即2个字节)
		int audioLength = (int)(file.length()/2);
		short[] audio = new short[audioLength];
		
		try{
			InputStream is = new FileInputStream(file);
			BufferedInputStream bis = new BufferedInputStream(is);
			DataInputStream dis = new DataInputStream(bis);
			
			int i = 0;
			while(dis.available() > 0){
				audio[i] = dis.readShort();
				i++;
			}
			
			//关闭输入流
			dis.close();
			
			//创建和播放新的AudioTrack对象
                        //由于录制的原始音频没有关联元数据,因此必须将音频的数据属性设为与录制时相同
			AudioTrack audioTrack = new AudioTrack(
					AudioManager.STREAM_MUSIC,//流模式
					frequency,//频率
					channelConfiguration,//声道配置
					audioEncoding,//音频编码类型
					audioLength,//要播放的音频的长度
					AudioTrack.MODE_STREAM);
			
			audioTrack.play();//异步播放
			audioTrack.write(audio, 0, audioLength);//将原始音频数据添加到播放缓冲区
			
		}catch(Throwable t){
			Log.d("test", "An error occurred during playback", t);
		}
	}
}


运行效果

111111.png

标签: Android

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号