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

news/2023/6/9 18:18:29

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 录音的格式比较固定,同时不能够暂停,相对来说操作简单,但是功能也
    比较简单。
    完成了录音,我们来说下如何播放。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4564132.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

不允许使用抽象类类型的对象怎么办_什么是抽象类?

抽象类概述分析事物时, 发现了共性的内容,就出现向上抽取,但是如果父类 的方法功能与子类不同,那么这时就不抽取方法主体,这样抽取出来的方法 就是抽象方法什么是抽象类有抽象方法的类抽象类和普通的父类有什么区别?有抽象方法抽象方法又是什么?使用 abstract 关键字修饰方法…

【C# 教程系列第 11 篇】什么是抽象类、抽象方法

这是【C# 教程系列第 11 篇】,如果觉得有用的话,欢迎关注专栏。 文章目录一:什么是抽象类、抽象方法二:抽象类的特性1:抽象类不能实例化2:抽象类可以包含抽象方法和抽象访问器3:不能用 sealed 关…

什么是纯虚函数?什么是抽象类?

在设计时,常常希望基类仅仅作为其派生类的一个接口。这就是说,仅想对基类进行向上类型转换,使用它的接口,而不希望用户实际的创建一个基类的对象。同时创建一个纯虚函数允许接口中放置成员原函数,而不一定要提供一段可…

什么是抽象类,接口?他们的区别?(详解)

目录 1.抽象类 2.接口 3.抽象类与接口的联系与区别 1.抽象类 定义: 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类 这么说可能不好理解,我们来换个说法: 抽象类无法被实例化,也就是我们不能去创建它的对象 例 : 动物类就是一个抽象…

什么是抽象方法 java_java抽象类和抽象方法

一、什么是抽象类和抽象方法没有具体功能的实现,通过子类继承后重写方法来实现一定约束的类称之为抽象类,抽象类必须被abstract修饰。抽象方法就是只有方法声明,没有方法体的方法。抽象类的使用一般通过继承来实现二、为什么需要抽象类和抽象…

什么是抽象类?怎么定义?

什么是抽象类?怎么定义?这是属于java技术里面的一个知识点,本期教程就是围绕这个问题做的相关介绍,当定义一个类时,常常需要定义一些成员方法描述类的行为特征,但有时这些方法的实现方式是无法确定的。例如,在定义An…

企业业务单骑救主,华为连取两项国内前二、全球前五

早前华为公布的业绩显示今年前三季度的营收比去年同期减少了2000多亿元,华为虽然没有公布三大业务线的营收情况,不过业界人士认为企业业务应该是它的最大亮点,保持了增长势头。此前华为公布的业绩显示消费者业务、运营商业务是它的前两大收入…

HAYDON黑洞全球高端美妆专卖店设计分享!

作为国内首个提出不可定义的黑洞之旅概念的高端美妆体验店,通过邀请顶尖的专卖店设计公司,HAYDON黑洞把首家线下体验店落户在了武汉楚河汉街。 随着首店开启,众美妆、时尚、生活方式领域的达人纷纷到场打卡,这个沉浸式的黑洞之旅体…