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)的主要内容,如果未能解决你的问题,请参考以下文章

Android 深入系统完全讲解(33)

Android 深入系统完全讲解(33)

Android 深入系统完全讲解(31)

Android 深入系统完全讲解(31)

Android深入系统完全讲解(38)

Android深入系统完全讲解(38)