热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

音视频Day09PCM转WAV

1.在FFmpeg的源码中,经常能看到3是什么意思?二进制右移三位,表示除以

1. 在 FFmpeg 的源码中,经常能看到 >>3 是什么意思?

  • 二进制右移三位,表示 除以 8

2. 如何通过命名行得知录音设备的采样率声道数采样格式

  • 让录音设备进行录音 ffmpeg -f avfoundation -i :0 out.wav
Input #0, avfoundation, from ':0':
Duration: N/A, start: 87533.086750, bitrate: 256 kb/s
Stream #0:0: Audio: pcm_f32le, 8000 Hz, mono, flt, 256 kb/s
  • 采样率:8000Hz
  • 声道数 mono(单声道)
  • 采样格式:f32le(浮点 32 位小端模式)

3. 如何在代码中获取录音设备的采样率声道数采样格式

  • ctx → streams → streams → codec → sample_rate = 8000 (采样率)
  • ctx → streams → streams → codec → sample_fmt = 1 (声道数)
  • ctx → streams → streams → codec_id = AV_CODEC_ID_PCM_F32LE (采样格式)

4. RIFF 是什么?哪两个比较主流的音频格式是遵守 RIFF 的?

  • RIFF(Resource Interchange File Format,资源交换文件格式)由 Microsoft 和 IBM 提出
  • WAV、AVI 文件都是基于 RIFF 标准的文件格式,所以 WAV、AVI 文件的最前面 4 个字节都是 RIFF 四个字符

5. chunk 是什么意思?一个 chunk 由哪三部分组成?

  • chunk:数据块的意思
  • 每个 chunk 主要包含三部分:id(chunk 的标识)、data-size(chunk 的数据部分大小,字节为单位)、data(chunk 的数据部分)

6. 解剖 WVA 文件

  • 使用前面命令行录制音频,可以获得 out.wav 文件,文件大小:348204 字节
  • 我们将 out.wav 使用 vscode 以二进制文件的格式打开,然后我们分析其头部数据
// out.wav 的首部部分16 进制数据
00000000: 52 49 46 46 24 50 05 00 57 41 56 45 66 6D 74 20    RIFF$P..WAVEfmt.
00000010: 10 00 00 00 01 00 02 00 44 AC 00 00 10 B1 02 00    ........D,...1..
00000020: 04 00 10 00 64 61 74 61 00 50 05 00 00 00 0E BB    ....data.P.....;
  • out.wav 的前 44 个字节进行解析如下:
52 49 46 46(ChunkID,4 字节) = ‘RIFF’

24 50 05 00 (ChunkSize,4 字节)=  348196  = 348204 - 8

57 41 56 45 (Format,4 字节) = ‘WAVE’

66 6D 74 20 (Subchunk1ID,4 字节) = ‘fmt ’

10 00 00 00 (Subchunk1 Size,4 字节) = 16

01 00(AudioFormate,2 字节) = 音频格式 = 1

02 00 (NumChannels,2 字节)= 声道数 = 2

44 AC 00 00(SampleRate,4 字节)= 采样率 = 44100

10 B1 02 00(ByteRate,4 字节)= 字节率 = 176400

04 00 (BlockAlign,2 字节)= 内存对齐 = 4

10 00 (BitsPerSample)= 每个样本的位深度 =  16

64 61 74 61(Subchunk2ID,4 字节) = ‘data’

00 50 05 00 (Subchunk2 Size,4 字节) = 音频PCM数据大小 = 348160 = 348204 - 44

有资料需求的可以了解下,有关于包括 数据结构、底层进阶、图形视觉、音视频、架构设计、逆向安防、RxSwift、flutter,算法等方面的资料,面试资料就在群文件里面可自行下载,891点击 488进入 181有什么问题也可以直接在里面提出来,互相交流,同时内有好友发内推机会,一起共同进步!

7. 需要理解的三幅图

音视频 Day 09 PCM 转 WAV
音视频 Day 09 PCM 转 WAV
WAV 文件格式
音视频 Day 09 PCM 转 WAV
WAV 文件格式

8. 命令行实现 PCM 转 WAV

ffmpeg -ar 44100 -ac 2 -f s16le -i out.pcm -bitexact out2.wav

9. 代码实现 PCM 转 WAV

void FFmpegs::pcm2wav(WAVHeader &header, const char *pcmFilename, const char *wavFilename) {
 header.blockAlign = header.bitsPerSample * header.numChannels >> 3;
 header.byteRate = header.sampleRate * header.blockAlign;

 // 打开 pcm 文件
 QFile pcmFile(pcmFilename);
 if (!pcmFile.open(QFile::ReadOnly)) {
     qDebug()  0) {
     wavFile.write(buf, size);
 }

 // 关闭文件
 pcmFile.close();
 wavFile.close();
}
  • 调用代码如下:
WAVHeader header;
header.sampleRate = 44100;
header.bitsPerSample = 16;
header.numChannels = 2;

FFmpegs::pcm2wav(header,
              "/Users/linsipei/Documents/ffmpeg_workspcace/05_tmp/in.pcm",
              "/Users/linsipei/Documents/ffmpeg_workspcace/05_tmp/out.wav");

10. 代码实现 录制的PCM 直接转 WAV(包含动态获取录音设备的相关信息操作)

// 获取输入流
AVStream *stream = ctx->streams[0];
// 获取音频参数
AVCodecParameters *params = stream->codecpar;

//pcm 转 wav 文件
WAVHeader header;
header.sampleRate = params->sample_rate;
header.bitsPerSample = av_get_bits_per_sample(params->codec_id);
header.numChannels = params->channels;
if (params->codec_id >= AV_CODEC_ID_PCM_F32BE) {
 header.audioFormat = AUDIO_FORMAT_FLOAT;
}
FFmpegs::pcm2wav(header, filename.toUtf8().data(), wavFilename.toUtf8().data());

作者:carrot__lsp
链接:https://juejin.cn/post/6955032831466684453


推荐阅读
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 深入解析Struts、Spring与Hibernate三大框架的面试要点与技巧 ... [详细]
  • 你的问题在于:1. 代码格式混乱,缺乏必要的缩进,导致可读性极低;2. 使用 `strlen()` 和 `malloc()` 函数时,必须包含相应的头文件;3. `write()` 函数的返回值处理不当,建议检查并处理其返回值以确保程序的健壮性。此外,建议在编写代码时遵循良好的编程规范,增加代码的可维护性和可读性。 ... [详细]
  • 本文详细介绍了在MySQL中如何高效利用EXPLAIN命令进行查询优化。通过实例解析和步骤说明,文章旨在帮助读者深入理解EXPLAIN命令的工作原理及其在性能调优中的应用,内容通俗易懂且结构清晰,适合各水平的数据库管理员和技术人员参考学习。 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
  • 利用 fopen、fwrite、fread、fseek 和 fclose 实现文件中整型数据的读写操作 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • 本文详细探讨了在ASP.NET环境中通过加密数据库连接字符串来提升数据安全性的方法。加密技术不仅能够有效防止敏感信息泄露,还能增强应用程序的整体安全性。文中介绍了多种加密手段及其实施步骤,帮助开发者在日常开发过程中更好地保护数据库连接信息,确保数据传输的安全可靠。 ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有