FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书的“5.1.2 把音频流保存为PCM文件”介绍了如何把媒体文件中的音频流转存为原始的PCM音频,在样例代码的转存过程中,解码后的PCM数据未经任何加工处理,就直接保存到二进制文件。也就是说,原音频的采样频率是多少,PCM文件的采样频率也是多少;原音频的声道数量是多少,PCM文件的声道数量也是多少;原音频的采样位数是多少,PCM文件的采样位数也是多少。
原汁原味保存的PCM文件本来也没什么问题,可是在实际应用中,有的业务场景需要特定规格的PCM音频。比如某厂家的语音识别引擎,要求只能输入16位的PCM数据,然而标准的MP3音频都采用32位采样,如此一来,得想办法把32位的MP3音频转换为16位的PCM音频才行。
考虑到使用FFmpeg的命令行转换比较方便,于是在控制台执行下面的ffmpeg格式转换指令,在转换采样频率和声道数量的同时一起转换采样位数。
ffmpeg -i night.mp3 -ar 16000 -ac 1 -acodec pcm_s16le night.pcm
谁知控制台输出以下的报错信息“pcm_s16le codec not supported”,意思是不支持16位的PCM编码器。
pcm_s16le codec not supported
咦,FFmpeg怎么会不支持这么基本的PCM编码器呢?继续执行下面的编码器查看命令:
ffmpeg -encoders | grep pcm
发现输出的查询结果赫然出现下面的pcm_s16le信息,说明FFmpeg默认已经支持该编码器。
A....D pcm_s16le PCM signed 16-bit little-endian
那么为啥ffmpeg命令行无法正常转换PCM音频的采样位数呢?
搜了一圈发现没有使用ffmpeg成功转换采样位数的案例,只好先把原音频转换为32位采样的PCM文件,转换命令如下所示:
ffmpeg -i night.mp3 -ar 16000 -ac 1 -acodec pcm_f32le -f f32le night.pcm
接下来另外编写转换音频采样位数的代码convertpcm.c,代码内容如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int pcm32_to_pcm16(const char *filename)
{
FILE *fp = fopen(filename, "rb");
FILE *fp1 = fopen("output_16.pcm", "wb");
unsigned char *sample = (unsigned char*)calloc(1, 4+1);
while(!feof(fp))
{
fread(sample, 4, 1, fp);
sample[4] = '\0';
float *sample32 = (float*)sample;
short sample16 = (short)floor( (*sample32) * 32767 );
fwrite(&sample16, 2, 1, fp1);
}
free(sample);
fclose(fp);
fclose(fp1);
return 0;
}
int main(int argc, char **argv) {
const char *src_name = "night.pcm";
if (argc > 1) {
src_name = argv[1];
}
pcm32_to_pcm16(src_name);
}
保存代码,然后执行下面的编译命令。
gcc convertpcm.c -o convertpcm
编译完成,再执行下面的采样位数转换命令。
./convertpcm night.pcm
现在生成的output_16.pcm就是16位采样的PCM文件,可以用作语音识别了。
更多详细的FFmpeg开发知识参见《FFmpeg开发实战:从零基础到短视频上线》一书。
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频的更多相关文章
- FFmpeg开发笔记(十):ffmpeg在ubuntu上的交叉编译移植到海思HI35xx平台
FFmpeg和SDL开发专栏(点击传送门) 上一篇:<FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放>下一篇:敬请期待 前言 将ffmpeg移植到海思H ...
- 安卓开发笔记(十八):实现button按钮事件的三种方法
Android开发中有三种主要的方式用于设置View的点击事件,1.创建内部类:2.主类中实现OnClickListener接口:3.使用匿名内部类.这三种方式都用到了OnClickListener接 ...
- 论文阅读笔记五十八:FoveaBox: Beyond Anchor-based Object Detector(CVPR2019)
论文原址:https://arxiv.org/abs/1904.03797 摘要 FoveaBox属于anchor-free的目标检测网络,FoveaBox直接学习可能存在的图片种可能存在的目标,这期 ...
- .net开发笔记(十八) winform中的等待框
winform中很多任务是需要在后台线程(或类似)中完成的,也就是说,经常容易涉及到UI界面与后台工作线程之间的交互.比如UI界面控制后台工作的执行(启动.暂停.停止等),后台工作进度在UI界面上的显 ...
- Java开发笔记(十八)上下求索的while循环
循环是流程控制的又一重要结构,“白天-黑夜-白天-黑夜”属于时间上的循环,古人“年复一年.日复一日”的“日出而作.日落而息”便是每天周而复始的生活.计算机程序处理循环结构时,给定一段每次都要执行的代码 ...
- Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件
前言 上一篇已经将himpp套入qt的基础上进行开发.那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤. 受限制 因为直接配置sample的vi比较麻烦 ...
- FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- FFmpeg开发笔记(四):ffmpeg解码的基本流程详解
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放
前言 ffmpeg播放rtsp网络流和摄像头流. Demo 使用ffmpeg播放局域网rtsp1080p海康摄像头:延迟0.2s,存在马赛克 使用ffmpeg播放网络rtsp文件流 ...
- FFmpeg开发笔记(三):ffmpeg介绍、windows编译以及开发环境搭建
前言 本篇章是对之前windows环境的补充,之前windows的是无需进行编译的,此篇使用源码进行编译,版本就使用3.4.8. FFmpeg简介 FFmpeg是领先的多媒体框架,能够解码 ...
随机推荐
- 为baselines算法库安装mujoco环境支持——ubuntu 20.04安装MuJoCo2.1.1
下载开源版本的mujoco二进制文件: wget https://github.com/deepmind/mujoco/releases/download/2.1.1/mujoco-2.1.1-lin ...
- npm WARN config global `--global`, `--local` are deprecated. Use `--location 的解决方法
1.背景 2.解决步骤 2.1.找到nodejs的安装路径 2.2.修改配置文件 将文件里的 prefix-g 改为 prefix --location=global 修改前: 修改后: 点击保存就解 ...
- DophinScheduler 如何定期删除日志实例?
转载自东华果汁哥 Apache DophinScheduler 运行一段时间后,实例调度日志越来越多,需要定期清理. SQL 错误 [1701] [42000]: Cannot truncate a ...
- 【A GUIDE TO CRC ERROR DETECTION ALGORITHM】 (译文1)
A GUIDE TO CRC ERROR DETECTION ALGORITHM (译文) <A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHM& ...
- Linux 进程编程入门
关于进程和线程的关系,之前一口君写过这几篇文章,大家可以参考下. 本文从头带着大家一起学习Linux进程 <搞懂进程组.会话.控制终端关系,才能明白守护进程干嘛的?> <[粉丝问答6 ...
- 【CMake系列】11-CMake Pack
cmake pack 用于将我们的写好的项目 打包,发送给使用方:打包后产生的内容有 源代码包 二进制包 平台原生的二进制安装 Debian -> .deb red hat -> .rpm ...
- Win32 SDK 下的TreeCtrl控件的封装
自己照着MFC封装,半月前封装了一半,碰到问题就放下了,今天终于封装好了. [Ctree.h]文件 #pragma once #include <windows.h> #include & ...
- 折腾 Quickwit,Rust 编写的分布式搜索引擎(专为从对象存储中实现亚秒级搜索而设计)
什么是 Quickwit? Quickwit 是首个能在云端存储上直接执行复杂的搜索与分析查询的引擎,并且具有亚秒级延迟.它借助 Rust 语言和分离计算与存储的架构设计,旨在实现资源高效利用.易于操 ...
- 禁止 SSH 传递 locale 环境变量
SSH 在连接远程机器时默认会传递一些环境变量,其中就包括你本机的 locale 变量.这会导致远程机器的 locale 配置变成和你本地主机一样.有时候我们不希望这种行为,我们可以通过修改 SSH ...
- Docker学习系列3:常用命令之容器命令
本文是Docker学习系列教程中的第三篇.前几篇教程如下: 「图文教程」Windows11下安装Docker Desktop 「填坑」在windows系统下安装Docker Desktop后迁移镜像位 ...