当前位置: 首页 > article >正文

Qt5.9.2 + FFmpeg4.3实战:解决音频重采样后AAC编码的‘滋滋声’与速度异常

Qt5.9.2 FFmpeg4.3实战解决音频重采样后AAC编码的‘滋滋声’与速度异常在音视频开发领域音频重采样是一个常见但容易踩坑的技术点。特别是在实时音频处理场景下采样率转换过程中的细微参数设置不当往往会导致令人头疼的音频质量问题。本文将深入剖析Ubuntu 18.04环境下使用Qt5.9.2和FFmpeg4.3进行音频采集、重采样和AAC编码时遇到的典型滋滋声和播放速度异常问题提供一套完整的解决方案。1. 问题现象与根源分析当开发者尝试将48000Hz采样率的音频数据重采样为44100Hz并编码为AAC格式时经常会遇到两个典型症状持续的滋滋电流声听起来像是背景噪声被放大播放速度异常音频比正常速度快约8.8%48000/44100≈1.088这些问题的根源在于采样点数的精确计算和缓冲区管理。让我们先理解几个关键概念采样率转换比例48000→44100的转换比例是160:147约等于1.088帧大小对齐AAC编码器通常要求每帧1024个采样点重采样精度swr_convert()函数返回的实际采样点数会有±1的浮动注意直接按1024个采样点进行重采样会导致计算误差累积这是产生速度异常和噪声的主要原因。2. 重采样参数的正确设置2.1 采样点数的黄金比例解决这个问题的关键在于找到48000和44100之间的整数对应关系。经过实践验证以下参数组合效果最佳参数类型源采样点数目标采样点数单通道480441双通道960882这种设置确保了采样率转换的精确性。对应的代码实现如下// 初始化重采样上下文 SwrContext *swr_ctx swr_alloc(); av_opt_set_int(swr_ctx, in_sample_rate, 48000, 0); av_opt_set_int(swr_ctx, out_sample_rate, 44100, 0); av_opt_set_sample_fmt(swr_ctx, in_sample_fmt, AV_SAMPLE_FMT_S16, 0); av_opt_set_sample_fmt(swr_ctx, out_sample_fmt, AV_SAMPLE_FMT_FLT, 0); // 设置重采样参数 const int src_nb_samples 480; // 单通道源采样点数 const int dst_nb_samples 441; // 单通道目标采样点数 // 分配输入输出缓冲区 uint8_t **src_data nullptr; av_samples_alloc_array_and_samples(src_data, NULL, 2, src_nb_samples, AV_SAMPLE_FMT_S16, 0); uint8_t **dst_data nullptr; av_samples_alloc_array_and_samples(dst_data, NULL, 2, dst_nb_samples, AV_SAMPLE_FMT_FLT, 0);2.2 处理重采样浮动值实际重采样过程中swr_convert()返回的采样点数可能会有±1的浮动int actual_samples swr_convert( swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)src_data, src_nb_samples ); // actual_samples可能是440、441或442这种浮动对最终音频质量影响很大需要特殊处理直接写入PCM文件以actual_samples为准后续编码处理需要缓冲对齐到编码器要求的帧大小3. 缓冲区管理与数据对齐3.1 使用AVAudioFifo实现精确缓冲为了解决重采样输出与编码器输入之间的帧大小不匹配问题FFmpeg提供的AVAudioFifo是最佳选择// 创建音频FIFO缓冲区 AVAudioFifo *fifo av_audio_fifo_alloc( AV_SAMPLE_FMT_FLT, // 采样格式 2, // 通道数 1024 * 2 // 初始容量(足够大) ); // 写入重采样后的数据 av_audio_fifo_write(fifo, (void **)dst_data, actual_samples); // 当缓冲区有足够数据时读取 if (av_audio_fifo_size(fifo) 1024) { AVFrame *frame av_frame_alloc(); frame-nb_samples 1024; frame-format AV_SAMPLE_FMT_FLT; frame-channel_layout AV_CH_LAYOUT_STEREO; av_frame_get_buffer(frame, 0); av_audio_fifo_read(fifo, (void **)frame-data, 1024); // 将frame送入编码器... }3.2 处理剩余数据在停止采集时缓冲区中可能还有未处理的数据需要特殊处理未重采样的原始数据先完成重采样已重采样但未编码数据凑齐完整帧再编码编码器内部缓冲送入空帧触发刷新处理流程示例// 1. 处理原始数据缓冲区 while (原始缓冲区有数据) { // 重采样并写入FIFO } // 2. 处理重采样FIFO while (av_audio_fifo_size(fifo) 0) { int to_read FFMIN(av_audio_fifo_size(fifo), 1024); AVFrame *frame ...; av_audio_fifo_read(fifo, (void **)frame-data, to_read); encode_frame(frame); } // 3. 刷新编码器 encode_frame(nullptr); // 送入空帧4. 电流声问题的终极解决方案滋滋电流声通常由以下原因导致缓冲区大小计算错误直接使用dst_linesize写入文件采样格式转换问题S16到FLT的转换精度损失内存对齐问题缓冲区未正确对齐正确的做法是使用av_samples_get_buffer_size计算实际数据大小int buf_size av_samples_get_buffer_size( NULL, // 不单独获取linesize 2, // 通道数 actual_samples, // 实际采样点数 AV_SAMPLE_FMT_S16, // 目标格式 1 // 对齐 ); // 写入文件时使用精确计算的大小 fwrite(dst_data[0], 1, buf_size, output_file);此外还需要注意避免频繁的内存分配释放重用缓冲区检查采样格式兼容性确保所有组件使用一致的格式验证重采样上下文参数特别是通道布局和采样率5. 完整实现流程与性能优化5.1 实时音频处理流水线一个健壮的音频处理流程应包含以下步骤采集阶段从设备读取固定大小(如1024采样点)的原始数据积累到480的整数倍(如480×41920采样点)重采样阶段按480:441的比例分批处理处理浮动采样点数(440-442)缓冲对齐使用AVAudioFifo管理重采样后数据凑齐1024采样点送入编码器编码阶段配置FDK-AAC编码参数处理编码器延迟和内部缓冲5.2 性能优化技巧批量处理积累足够数据再处理减少频繁调用开销内存池预分配和重用缓冲区避免实时分配线程分离将采集、处理、编码放在不同线程延迟控制合理设置缓冲区大小平衡延迟和稳定性// 优化的主循环结构示例 while (running) { // 采集阶段 if (采集足够原始数据) { // 重采样阶段 int consumed 0; while (consumed src_samples) { int ret swr_convert(...); // 写入FIFO... consumed src_batch_size; } } // 编码阶段 if (fifo中有足够数据) { AVFrame *frame ...; av_audio_fifo_read(fifo, (void **)frame-data, 1024); encode_frame(frame); } }在实际项目中我发现最稳定的配置是使用双缓冲机制一个缓冲用于采集原始数据另一个用于重采样后的数据。当采集缓冲满时交换指针这样可以最大限度地减少锁竞争和内存拷贝。

相关文章:

Qt5.9.2 + FFmpeg4.3实战:解决音频重采样后AAC编码的‘滋滋声’与速度异常

Qt5.9.2 FFmpeg4.3实战:解决音频重采样后AAC编码的‘滋滋声’与速度异常 在音视频开发领域,音频重采样是一个常见但容易踩坑的技术点。特别是在实时音频处理场景下,采样率转换过程中的细微参数设置不当,往往会导致令人头疼的音频…...

k8s PDB(Pod Disruption Budget)介绍(集群维护或调度时,确保足够Pod)minAvailable、maxUnavailable、自愿中断、kubectl drain、HPA

文章目录Kubernetes PDB(Pod Disruption Budget)详解一、什么是 PDB?二、什么是“自愿中断”?1. 自愿中断(PDB 可控制)2. 非自愿中断(PDB 无法控制)三、PDB 的核心字段1. minAvailab…...

Java的invokedynamic指令:Lambda表达式和Nashorn引擎的基础

Java的invokedynamic指令:Lambda表达式和Nashorn引擎的基础 Java 7引入的invokedynamic指令彻底改变了JVM的动态语言支持能力,为后续Lambda表达式和Nashorn引擎的实现奠定了基础。这一指令通过运行时动态解析方法调用,显著提升了灵活性和性能…...

报错 RuntimeError: Only consecutive 1-d tensor indices are supported in exporting aten::index_put to O

多个轴索引,存在多个数值,需要满足【:】所在轴的数值在内存中是连续的,也就是【:】只能出现在最后的dimension,不能出现在前面,先放到最后,然后用permute函数 错误的方式1:x[self.c1[:, 0], :,…...

Gitleaks介绍(开源的Git仓库敏感信息扫描工具,用于检测代码中是否包含潜在secrets)密钥扫描、敏感信息扫描、自定义规则Regex、SARIF、质量门禁、Trivy、SAST

文章目录使用 Gitleaks 防止代码仓库泄露敏感信息一、什么是 Gitleaks?二、为什么需要 Gitleaks?1. Git 是“永久记录”2. 自动化开发带来的风险3. 安全合规要求三、Gitleaks 的核心能力1. 基于规则的检测(Rule-based Detection)2…...

避开这3个坑,你的OpenCV Python项目运行效率能快一倍

OpenCV Python性能优化实战:避开这3个效率黑洞 在计算机视觉项目的开发过程中,性能瓶颈往往隐藏在看似无害的代码片段里。当你的视频处理流水线开始卡顿,或是内存占用莫名飙升时,问题可能源于一些容易被忽视的编码习惯。本文将深入…...

除了收入健康,CFPS数据还能怎么玩?挖掘家庭追踪调查的隐藏研究场景

解锁CFPS数据的多维研究潜力:超越传统分析的创新视角 中国家庭追踪调查(CFPS)作为国内最具代表性的纵向社会调查项目,其价值远未被充分挖掘。当大多数研究者仍聚焦于经济收入和健康状况等常规维度时,那些隐藏在问卷角落…...

如何快速提升Mac鼠标体验:专业级滚动优化完整指南

如何快速提升Mac鼠标体验:专业级滚动优化完整指南 【免费下载链接】Mos 一个用于在 macOS 上平滑你的鼠标滚动效果或单独设置滚动方向的小工具, 让你的滚轮爽如触控板 | A lightweight tool used to smooth scrolling and set scroll direction independently for y…...

[CentOS 7实战] 从零部署高可用TeamSpeak语音服务器

1. 环境准备与基础配置 在CentOS 7上部署TeamSpeak服务器前,需要做好充分的环境准备。我建议使用至少2核4G配置的云服务器,实测这个配置可以稳定支持50人同时在线的语音通信。如果是大型游戏社区使用,建议选择4核8G以上的配置。 首先需要检查…...

3分钟上手:B站视频数据分析工具快速指南

3分钟上手:B站视频数据分析工具快速指南 【免费下载链接】Bilivideoinfo Bilibili视频数据爬虫 精确爬取完整的b站视频数据,包括标题、up主、up主id、精确播放数、历史累计弹幕数、点赞数、投硬币枚数、收藏人数、转发人数、发布时间、视频时长、视频简介…...

3种创新方法:如何用CREST彻底解决分子构象采样难题

3种创新方法:如何用CREST彻底解决分子构象采样难题 【免费下载链接】crest CREST - A program for the automated exploration of low-energy molecular chemical space. 项目地址: https://gitcode.com/gh_mirrors/crest/crest 你是否曾为分子构象探索的计算…...

TFT Overlay:终极云顶之弈悬浮辅助工具完全指南

TFT Overlay:终极云顶之弈悬浮辅助工具完全指南 【免费下载链接】TFT-Overlay Overlay for Teamfight Tactics 项目地址: https://gitcode.com/gh_mirrors/tf/TFT-Overlay TFT Overlay是一款专为《英雄联盟:云顶之弈》玩家设计的免费悬浮辅助工具…...

DDrawCompat三步部署指南:让Windows 10/11经典游戏重获新生

DDrawCompat三步部署指南:让Windows 10/11经典游戏重获新生 【免费下载链接】DDrawCompat DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11 项目地址: https://gitcode.com/gh_mirrors/dd/D…...

实用指南:如何为Windows 11 LTSC 24H2高效恢复微软商店完整方案

实用指南:如何为Windows 11 LTSC 24H2高效恢复微软商店完整方案 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore Windows 11 LTSC 24H2 版本…...

HunterPie:从数据迷雾到狩猎大师的智能进化指南

HunterPie:从数据迷雾到狩猎大师的智能进化指南 【免费下载链接】HunterPie-legacy A complete, modern and clean overlay with Discord Rich Presence integration for Monster Hunter: World. 项目地址: https://gitcode.com/gh_mirrors/hu/HunterPie-legacy …...

从“身份识别”到“数据对话”:I2C、SPI、CAN、PCIe四大总线通信机制深度剖析

1. 总线通信的本质:从"你是谁"到"我们怎么聊" 在嵌入式系统的世界里,总线就像硬件设备之间的社交网络。想象你走进一个会议室,首先要确认每个人的身份(握手或名片交换),然后才能开始有…...

免费开源远程桌面控制终极指南:如何用BilldDesk替代ToDesk和向日葵

免费开源远程桌面控制终极指南:如何用BilldDesk替代ToDesk和向日葵 【免费下载链接】billd-desk 基于Vue3 WebRTC Nodejs Flutter搭建的远程桌面控制、游戏串流 项目地址: https://gitcode.com/gh_mirrors/bi/billd-desk 你是否厌倦了远程控制软件的各种限…...

I2C、SPI、CAN、PCIe:从“身份识别”到“对话方式”的四大总线深度解析

1. 四大总线的"身份证":如何唯一标识设备 想象一下你走进一个挤满人的会议室,想要找张三谈事情。这时候你需要两种信息:第一,如何从人群中识别出张三(唯一标识);第二,用什…...

实战构建抖音直播弹幕采集系统:DouyinLiveWebFetcher技术实现方案

实战构建抖音直播弹幕采集系统:DouyinLiveWebFetcher技术实现方案 【免费下载链接】DouyinLiveWebFetcher 抖音直播间网页版的弹幕数据抓取(2025最新版本) 项目地址: https://gitcode.com/gh_mirrors/do/DouyinLiveWebFetcher 在社交媒…...

IDM永久激活终极指南:开源脚本安全冻结试用期的完整教程

IDM永久激活终极指南:开源脚本安全冻结试用期的完整教程 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 还在为IDM试用期到期而烦恼吗?ID…...

别再折腾CUDA版本了!用Anaconda Navigator一键搞定TensorFlow/PyTorch的GPU环境(附版本匹配表)

告别CUDA版本地狱:Anaconda Navigator极简搭建TensorFlow/PyTorch GPU环境实战指南 刚入坑深度学习的开发者,十有八九会在环境配置阶段崩溃——CUDA版本不兼容、cuDNN找不到对应版本、Python环境冲突...这些报错信息就像一堵高墙,把无数热情挡…...

LibreCAD多语言界面终极指南:20+语言快速切换与专业配置方法

LibreCAD多语言界面终极指南:20语言快速切换与专业配置方法 【免费下载链接】LibreCAD LibreCAD is a cross-platform 2D CAD program written in C17. It can read DXF/DWG files and can write DXF/PDF/SVG files. It supports point/line/circle/ellipse/parabol…...

HC32F460 SPI驱动ILI9341踩坑实录:从寄存器配置到屏幕闪烁的解决方案

HC32F460驱动ILI9341实战避坑指南:从SPI配置到显示优化的全流程解析 第一次点亮ILI9341屏幕时,那种期待与忐忑交织的感觉至今难忘——接好线、写完代码、上电测试,结果要么白屏要么花屏,甚至直接毫无反应。这种经历对于嵌入式开发…...

SSD-PyTorch训练自定义数据集避坑指南:从VOC格式准备到模型调参全流程

SSD-PyTorch实战:自定义数据集训练避坑与性能优化全解析 第一次用SSD训练自己的目标检测模型时,我盯着报错信息发呆了半小时——明明按照教程操作,却在数据加载环节卡住。后来才发现是PyTorch版本差异导致的API变更。这种"看似简单实则暗…...

org.openpnp.vision.pipeline.stages.WritePartTemplateImage

文章目录org.openpnp.vision.pipeline.stages.WritePartTemplateImage功能参数WritePartTemplateImage和ImageWrite的区别产生测试图片例子1 - 自动产生文件名效果ENDorg.openpnp.vision.pipeline.stages.WritePartTemplateImage 功能 将当前工作图像(如检测到的元…...

别再踩坑了!MyBatis-Plus分页失效?可能是你的PaginationInnerInterceptor没配对

MyBatis-Plus分页插件深度解析:从失效排查到最佳实践 遇到MyBatis-Plus分页查询结果异常?别急着怀疑人生,这很可能是插件配置的"版本陷阱"在作祟。自从3.4版本架构调整后,原先直来直去的PaginationInterceptor配置方式…...

别再花钱买服务器了!用Ngrok免费把本地项目变成公网可访问(Windows/Linux保姆级教程)

零成本公网访问:Ngrok内网穿透实战指南(Windows/Linux双平台) 你是否遇到过这样的场景:刚在本地调试好一个网页应用,急需让同事预览效果;或是开发了一个微信小程序后端,需要临时给客户演示功能…...

告别VLC!手把手教你编译支持H265的FFmpeg,用ffplay播放RTMP流(附避坑指南)

从零构建支持H265的RTMP播放器:FFmpeg深度定制指南 在流媒体技术快速迭代的今天,H265编码以其卓越的压缩效率成为4K/8K超高清内容的首选方案。然而,当我们需要通过RTMP协议传输H265视频时,却面临着传统播放器兼容性不足的困境。本…...

四、Zabbix监控-实战SNMP协议监控异构IT资产

1. SNMP协议:异构IT监控的通用语言 第一次接触企业级IT监控时,我被机房里的设备多样性惊呆了——思科交换机的CLI界面、华为路由器的Web配置、惠普打印机的专用协议,还有那些老旧到连SSH都不支持的服务器。当时就在想:难道要为每个…...

SAP MM开发避坑指南:BAPI_GOODSMVT_CREATE调用时,如何快速找到自定义移动类型对应的GOODSMVT_CODE?

SAP MM开发实战:自定义移动类型与GOODSMVT_CODE的精准匹配策略 在SAP物料管理(MM)模块的开发过程中,BAPI_GOODSMVT_CREATE是最常用的接口之一,但许多开发者在处理自定义移动类型时都会遇到一个共同难题:如何…...