使用android设备录音,以及将音频插入MediaStore

最简单的是使用Intent  简单、不灵活

Intent intent=new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);

startActivityForResult(intent,REQUESTCODE);


使用MediaRecord  灵活、难用


录制音频:初始化MediaRecorder后,有四个方法必须按顺序调用,不然会产生大作用
  1. setAudioSource():设置录制资源,默认参数一般为  MediaRecorder.AudioSource.MIC
  2. setOutPutFormat():设置录制文件的格式,有三个可选参数
    • MediaRecorder.OutPutFormat.MPEG_4---->包含音频、视频轨道
    • MediaRecorder.OutPutFormat.RAW_AMR---->纯音频,且音频编码器为AMR_NB时,才使用
    • MediaRecorder.OutPutFormat.THREE_GPP---->保存成.3gp文件 包含音频、视频轨道

  3. setAudioEncorder():设置录制的编解码格式,默认的可选参数
    • MediaRecorder.AudioEncorder.DEFAULT--???
    • MediaRecorder.AudioEncorder.AMR_NB--->自适应多速率窄带编解码器,针对语音优化,android录音唯一选择
  4. setOutPutFile():设置录制完成的保存位置
  5. 配置完成调用prepare()
  6. 开始录音start()
  7. 停止录音stop()
录制视频:和录制音频流程一样
  1. setVideoEncoder()
  2. setVideoSource()

代码示例:

录音加播放

package com.example.day606;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

public class MainActivity extends AppCompatActivity implements MediaPlayer.OnCompletionListener, View.OnClickListener {
    private Button start, stop, play, finish;   //四个按钮
    private TextView status;    //显示当前状态
    private MediaPlayer mediaPlayer;    //播放录音
    private MediaRecorder mediaRecorder;    //录音
    private File audioFile;     //保存文件路径

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        start = (Button) findViewById(R.id.start);
        stop = (Button) findViewById(R.id.stop);
        play = (Button) findViewById(R.id.play);
        finish = (Button) findViewById(R.id.finish);
        status = (TextView) findViewById(R.id.status);
        status.setText("ready");

        start.setOnClickListener(this);
        stop.setOnClickListener(this);
        play.setOnClickListener(this);
        finish.setOnClickListener(this);

        stop.setEnabled(false);
        play.setEnabled(false);
    }

    /**
     * @param mp
     * 当播放完成时调用
     */
    @Override
    public void onCompletion(MediaPlayer mp) {
        play.setEnabled(true);
        stop.setEnabled(false);
        start.setEnabled(false);
        status.setText("ready");
    }

    @Override
    public void onClick(View v) {
        if (v == finish) {
            finish();
        }
        if (v == stop) {
            //点击停止按钮后,停止录音,并释放录音组件
            mediaRecorder.stop();
            mediaRecorder.release();
            //实例化播放组件,并将录制的文件提交给MediaPlayer
            mediaPlayer=new MediaPlayer();
            mediaPlayer.setOnCompletionListener(this);
            try {
                mediaPlayer.setDataSource(audioFile.getAbsolutePath());
                mediaPlayer.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
            status.setText("ready to play");
            play.setEnabled(true);
            stop.setEnabled(false);
            start.setEnabled(true);
        }
        if (v == start) {
            //点击开始按钮后,开始做得录音准备,实例化MediaRecorder、设置所需条件、准备完成、开始录音
            mediaRecorder=new MediaRecorder();
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            File path=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Audio");
            path.mkdir();
            try {
                audioFile=File.createTempFile("recording",".3gp",path);
                mediaRecorder.setOutputFile(audioFile.getAbsolutePath());
                mediaRecorder.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mediaRecorder.start();
            status.setText("Recording...");

            play.setEnabled(false);
            stop.setEnabled(true);
            start.setEnabled(false);
        }
        if (v == play) {
            //点击开始按钮后,将开始、停止、播放按钮禁止
            mediaPlayer.start();
            status.setText("playing");
            play.setEnabled(false);
            stop.setEnabled(false);
            start.setEnabled(false);
        }
    }
}



将音频插入MediaStore:可将其用于其他应用程序

步骤:上述的存储录音文件的路径path,创建一个ContentValues对象,用键、值对存储,

使用ContentResolver的insert方法,将path指向uri,包含ContentRelover对象,作为其参数,uri的值对应的MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

代码示例:

ContentValues values=new ContentValues();

values.put(MediaStore.MediaColums.TITLE,"this is music");

values.put(MediaStore.MediaColums.DATE_ADDED,System.currentTimeMillis());

values.put(MediaStore.MediaColums.DATA,path.getAbsolutePath());    //存储路径必备键值对

Uri uri=getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,contentValues);


将以上代码放入start按钮的方法内即可。


使用AudioRecorder录制音频,

步骤:使用设备录制---> int audioSource = MediaRecorder.AudioSource.MIC

设置录制的采样率 8kHz 或者 8000Hz   CD质量的音频采样率通常是44.1kHz 或者 44100Hz ------>int sampleRateInHz=11025

指定捕获的音频的通道数 参数如下:int channel=

AudioFormat.CHANNEL_CONFIGURATION_MONO  单通道

AudioFormat.CHANNEL_CONFIGURATION_STREAM

AudioFormat.CHANNEL_CONFIGURATION_INVALD

AudioFormat.CHANNEL_CONFIGURATION_DEFAULT

指定所需的音频各格式:int  audioEncoding=---->

AudioFormat.ENCODING_DEFAULT

AudioFormat.ENCODING_INVALID

AudioFormat.ENCODING_PCM_16BIT

AudioFormat.ENCODING_PCM_8BIT

指定创建的缓冲区大小

int bufferSize=AudioRecorder.getMinBufferSize(sampleRateInHz,channel,audioEncoding)

创建AudioRecorder对象

AudioRecorder audio=new AudioRecorder(audioSource,sampleRateInHz,channel,audioEncoding,bufferSize)

File path=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Audio");
path.mkdir();
audioFile=File.createTempFile("recording",".pcm",path);
DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(audioFile)))

short[] buffer=new short[bufferSize/4]

audioRecorder.startRecordering();

while(true){

int bufferResult=audioRecordor.read(buffer,0,bufferSize)

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

dos.writeShort(buffer[i]);

}

}


使用AudioTrack播放AudioRecorder录制的音频文件

注:原始音频用MediaPlayer是播放不了的

步骤:设置流类型--->AudioManager.STREAM_MUSIC

设置采样率,和AudioRecorder相同

通道配置,和AudioRecorder相同

设置音频格式,和AudioRecorder相同

定义缓冲区大小

int bufferSize=AudioTrack.getMinBufferSize(sampleRateInHz,channel,audioEncoding)

设置模式

AudioTrack.MODE_STATIC  或者AudioTrack.MODE_TREAM


配置AudioTrack

AudioTrack audioTrack=newAudioTrack(AudioManager.STREAM_MUSIC,sampleRateInHz,channel,audioEncoding,bufferSize,AudioTrack.MODE_TREAM)


打开音频源将数据读到缓冲区并送给audioTrack

DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputSteam(audioFile)))

audioTrack.play()

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

int i=0;

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

audioDta[i]=dis.readShort();

i++;

}

audioTrack.write(audioData,0,audioData.length)

}



完整代码示例:

package com.example.day607;

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.os.AsyncTask;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

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;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private RecordAudio recordTask;
    private PlayAudio playTask;
    private Button startRec, stopRec, startPlay, stopPlay;
    private TextView status;
    private File recodringFile;
    private boolean isRecording = false, isPlaying = false; //判断是否
    private static final int SAMPLE_SIZE_IN_HZ = 11025;       //采样率
    private static final int CHANNEL_CONFIGURATION = AudioFormat.CHANNEL_CONFIGURATION_MONO;   //设置为单通道
    private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;     //音频格式,16位编码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    public void init() {
        startRec = (Button) findViewById(R.id.startRec);
        stopRec = (Button) findViewById(R.id.stopRec);
        startPlay = (Button) findViewById(R.id.startPlay);
        stopPlay = (Button) findViewById(R.id.stopPlay);
        status = (TextView) findViewById(R.id.status);

        try {
            File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/apacheTTSS");
            path.mkdir();
            recodringFile = File.createTempFile("recording", ".pcm", path);
        } catch (IOException e) {
            e.printStackTrace();
        }

        startRec.setOnClickListener(this);
        stopRec.setOnClickListener(this);
        startPlay.setOnClickListener(this);
        stopPlay.setOnClickListener(this);

        stopRec.setEnabled(false);
        startPlay.setEnabled(false);
        stopPlay.setEnabled(false);
    }

    /**
     * @param v 单个if  和 else if区别就是单个的如果满足了还是会执行下面的if判断
     *          else if是只要满足了就不再进行其他的操作了,执行速度上快了
     */
    @Override
    public void onClick(View v) {
        if (v == startRec) {    //开始录音
            record();
        } else if (v == stopRec) {      //停止录音
            stopRecording();
        } else if (v == startPlay) {    //开始播放
            play();
        } else if (v == stopPlay) {     //停止播放
            stopPlaying();
        }
    }
    
    /**
     * 定义一个录音的内部类,继承AsyncTask
     */
    public class RecordAudio extends AsyncTask<Void, Integer, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            isRecording = true;
            try {
                DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(recodringFile)));
                int bufferSiz = AudioRecord.getMinBufferSize(SAMPLE_SIZE_IN_HZ, CHANNEL_CONFIGURATION, AUDIO_ENCODING);
                AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_SIZE_IN_HZ,
                        CHANNEL_CONFIGURATION, AUDIO_ENCODING, bufferSiz);
                short[] buffer = new short[bufferSiz];
                audioRecord.startRecording();
                int r = 0;
                while (isRecording) {
                    int audioBufferResult = audioRecord.read(buffer, 0, buffer.length);
                    for (int i = 0; i < audioBufferResult; i++) {
                        dos.writeShort(buffer[i]);
                    }
                    publishProgress(new Integer(r));
                    r++;
                }
                audioRecord.stop();
                dos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }//doInBackground

        @Override
        protected void onProgressUpdate(Integer... values) {
            status.setText(values[0].toString());
        }//onProgressUpdate

        @Override
        protected void onPostExecute(Void aVoid) {
            startRec.setEnabled(true);
            stopRec.setEnabled(false);
            startPlay.setEnabled(true);
        }//onPostExecute
    }

    /**
     * 定义一个播放的内部类,继承AsyncTask
     */
    public class PlayAudio extends AsyncTask<Void, Integer, Void> {
        AudioTrack audioTrack;

        @Override
        protected Void doInBackground(Void... params) {
            isPlaying = true;
            int bufferSize = AudioTrack.getMinBufferSize(SAMPLE_SIZE_IN_HZ, CHANNEL_CONFIGURATION, AUDIO_ENCODING);
            try {
                short[] audiodata = new short[bufferSize / 4];
                DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(recodringFile)));
                audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                        SAMPLE_SIZE_IN_HZ, CHANNEL_CONFIGURATION,
                        AUDIO_ENCODING, bufferSize, AudioTrack.MODE_STREAM);
                audioTrack.play();
                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();
                audioTrack.stop();
                audioTrack.release();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }//doInBackground

        @Override
        protected void onPostExecute(Void aVoid) {
            if (audioTrack != null) {
                startPlay.setEnabled(false);
                if (audioTrack.getState() != AudioTrack.PLAYSTATE_STOPPED) {
                    Log.i("PlayAudio 判断", "played ...");
                    stopPlay.setEnabled(false);
                }
            }
        }//onPostExecute
    }

    /**
     * 播放录音文件
     */
    public void play() {
        if (startRec != null) {
            startRec.setEnabled(true);
        }
        startPlay.setEnabled(false);
        playTask = new PlayAudio();
        playTask.execute();
        if (stopPlay != null) {
            stopPlay.setEnabled(true);
        }
    }

    /**
     * 停止播放
     */
    public void stopPlaying() {
        isPlaying = false;
        if (stopPlay != null) {
            stopPlay.setEnabled(false);
        }
        if (startPlay != null) {
            startPlay.setEnabled(true);
        }
    }

    /**
     * 停止录音
     */
    public void stopRecording() {
        isRecording = false;
    }

    /**
     * 开始录音
     */
    public void record() {
        startRec.setEnabled(false);
        stopRec.setEnabled(true);
        startPlay.setEnabled(true);
        recordTask = new RecordAudio();
        recordTask.execute();
    }
}






发布了112 篇原创文章 · 获赞 33 · 访问量 14万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览