Android 深入系统完全讲解(24)
Posted 程序员入门进阶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 深入系统完全讲解(24)相关的知识,希望对你有一定的参考价值。
https://blog.csdn.net/weixin_41101173/article/details/80374455
理解了绘制内容,解决了这部分,下来我们来说说关于音视频的其他部分。
所有的文件,都有一个叫做格式的东西存在,MP3,WAV,而处理这个格式的东西,就是解
码器。音频解码器,和视频解码器。
音频解码出来,只需要播放就可以。
视频解码出来,就是一帧帧画面,这时候就需要绘制配合。
AudioRecord 录音
AudioRecord 的主要作用是让 Java 应用方便的管理音频资源,以便通过此类录制平台的声
音,输出声音。
开始录音的时候,需要一个 buffer 进行缓存音频数据,声音会从硬件中独处,数据大小不超
过 buffer 的大小。
采集的过程比较简单,主要分为几部分:
1 麦克风作为音源
2 采样率,这个代表采集的数据大小,采样率越高,质量越好,存储越大。
3 单声道还是双声道
4 PCM 原式格式,可以转化为 WAV,这是最简单的转化
5 缓存区,可以使用 AudioRecord.getMinBufferSize 获取最小的缓冲区
我们看下代码:
//音频输入-麦克风
private final static int AUDIO_INPUT = MediaRecorder.Audiosource.MIC;
//采用频率
//44100 是目前的标准,但是某些设备仍然支持 22050,16000,11025
//采样频率一般共分为 22.05KHz、44.1KHz、48KHz 三个等级
private final static int AUDIO_SAMPLE_RATE = 16000;
//声道 单声道
private final static int AUDIO_CHANNEL = AudioFormat.CHANNEL_IN_MONO;
//编码
private final static int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
// 获得缓冲区字节大小
bufferSizeInBytes = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING);
audioRecord = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING, bufferSizeInBytes);
this.fileName = fileName;
然后进行启动:
audioRecord.startRecording();
监听数据:
readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
将数据存储起来,当前的格式默认是 PCM,也就是麦克输入的原始格式,但是存储的时候
如果存出这个格式,播放器是不识别的,所以需要转化。
默认的转化格式是 WAV,最简单的一种。
/**
- 将一个 pcm 文件转化为 wav 文件
- @param pcmPath pcm 文件路径
- @param destinationPath 目标文件路径(wav) * @param deletePcmFile 是否删除源文件
- @return
/
public static boolean makePCMFileToWAVFile(String pcmPath, String destinationPath, boolean deletePcmFile) byte buffer[] = null;
int TOTAL_SIZE = 0;
File file = new File(pcmPath);
if (!file.exists())
return false;
TOTAL_SIZE = (int) file.length();
// 填入参数,比特率等等。这里用的是 16 位单声道 8000 hz
WaveHeader header = new WaveHeader();
// 长度字段 = 内容的大小(TOTAL_SIZE) +
// 头部字段的大小(不包括前面 4 字节的标识符 RIFF 以及 fileLength 本身的 4 字节)
header.fileLength = TOTAL_SIZE + (44 - 8);
header.FmtHdrLeth = 16;
header.BitsPerSample = 16;
header.Channels = 2;
header.FormatTag = 0x0001;
header.SamplesPerSec = 8000;
header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
header.DataHdrLeth = TOTAL_SIZE;
byte[] h = null;
try
h = header.getHeader();
catch (IOException e1)
Log.e(“PcmToWav”, e1.getMessage());
return false;
if (h.length != 44) // WAV 标准,头部应该是 44 字节,如果不是 44 个字节则不进行转换
文件
return false;
// 先删除目标文件
File destfile = new File(destinationPath);
if (destfile.exists())
destfile.delete();
// 合成的 pcm 文件的数据,写到目标文件
try
buffer = new byte[1024 * 4]; // Length of All Files, Total Size
InputStream inStream = null;
OutputStream ouStream = null;
ouStream = new BufferedOutputStream(new FileOutputStream(
destinationPath));
ouStream.write(h, 0, h.length);
inStream = new BufferedInputStream(new FileInputStream(file));
int size = inStream.read(buffer);
while (size != -1)
ouStream.write(buffer);
size = inStream.read(buffer);
inStream.close();
ouStream.close();
catch (FileNotFoundException e)
Log.e(“PcmToWav”, e.getMessage());
return false;
catch (IOException ioe)
Log.e(“PcmToWav”, ioe.getMessage());
return false;
if (deletePcmFile)
file.delete();
return true;
使用 AudioRecord 操作的是原始的数据,下面我们看下使用 MediaRecorder 进行操作。
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
/ - ② 设 置 输 出 文 件 的 格 式 : THREE_GPP/MPEG-4/RAW_AMR/Default
THREE_GPP(3gp 格式 - ,H263 视频/ARM 音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要
求为 AMR_NB) /
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
/ ②设置音频文件的编码:AAC/AMR_NB/AMR_MB/Default 声音的(波形)的采
样 /
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
fileName = DateFormat.format(“yyyyMMdd_HHmmss”, Calendar.getInstance(Locale.CHINA)) + “.m4a”;
if (!FileUtils.isFolderExist(FileUtils.getFolderName(audioSaveDir))) FileUtils.makeFolders(audioSaveDir);
filePath = audioSaveDir + fileName;
/ ③准备 /
mMediaRecorder.setOutputFile(filePath);
mMediaRecorder.prepare();
/ ④开始 */
mMediaRecorder.start();
MediaRecorder 录音的格式比较固定,同时不能够暂停,相对来说操作简单,但是功能也
比较简单。
完成了录音,我们来说下如何播放。
以上是关于Android 深入系统完全讲解(24)的主要内容,如果未能解决你的问题,请参考以下文章