首页 > 其他分享 >FFmpeg开发笔记(十四)FFmpeg音频重采样的缓存

FFmpeg开发笔记(十四)FFmpeg音频重采样的缓存

时间:2024-04-14 11:44:40浏览次数:25  
标签:采样 缓存 FFmpeg 音频 ogg swr frame

​FFmpeg在很多地方都运用了缓存机制,比如《FFmpeg开发实战:从零基础到短视频上线》一书的“3.3.2  对视频流重新编码”介绍了编解码的数据缓存,不单是视频编码过程和视频解码过程有缓存,甚至连音频重采样都用到了缓存。

也就是说,重采样函数swr_convert一次只会输出指定长度的音频数据,超出这个长度的数据被留在重采样的缓存当中。那么在对一个音频文件转换格式之时,有可能所有音频帧都遍历完了,重采样缓存里面还保存着剩余未取走的音频数据。此时要像对待视频编码缓存那样,想办法把剩下的音频数据冲出来。
具体到代码实现上,在调用swr_convert函数之时,倒数第二个参数填NULL,表示输入的数据内容为空;倒数第一个参数填0,表示输入的数据大小为0。这便告诉采样器,已经没有要转换的音频了,请把缓存中剩余的数据冲出来吧。那么swr_convert函数的返回值就是本次冲走的输出数据大小,当返回值为0时,表示重采样缓存已经冲光了,再也没有剩余的数据了,此时才能结束音频的格式转换操作。
当然,对于常见的mp3和aac格式,它们每帧的长度是固定的,正常情况调用一次swr_convert函数即可输出完整的音频数据,无需另外处理重采样缓存。只有ogg、amr、wma等格式的每帧音频长度不固定,才需要额外处理音频的重采样缓存,于是对《FFmpeg开发实战:从零基础到短视频上线》一书第五章的重采样代码改动如下。
打开chapter05/swrmp3.c,把下面这行

swr_frame->nb_samples = audio_decode_ctx->frame_size;

改为下面几行(因为ogg、amr和wma的frame_size为0,所以需要另外赋值):

swr_frame->nb_samples = audio_decode_ctx->frame_size;
if (swr_frame->nb_samples <= 0) {
    swr_frame->nb_samples = 512;
}

另外在轮询数据包的循环结束之后,补充下面的重采样缓存冲刷代码,这样新生成的音频文件才是完整的:

while (1) { // 冲走重采样的缓存(兼容对ogg、amr等格式的重采样)
    // 重采样。也就是把输入的音频数据根据指定的采样规格转换为新的音频数据输出
    ret = swr_convert(swr_ctx, // 音频采样器的实例
                    // 输出的数据内容和数据大小
                    swr_frame->data, swr_frame->nb_samples,
                    // 输入内容填NULL、输入大小填0表示冲走缓存
                    NULL, 0);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "swr_convert frame occur error %d.\n", ret);
        return -1;
    } else if (ret == 0) { // 到末尾了
        break;
    }
    save_mp3_file(fp_out, swr_frame); // 把音频帧保存到MP3文件
}

接着执行下面的编译命令。

gcc swrmp3.c -o swrmp3 -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lpostproc -lm

编译完成后执行以下命令启动测试程序,期望把ring.ogg重采样后保存为MP3文件。

./swrmp3 ../ring.ogg

程序运行完毕,发现控制台输出以下的日志信息,说明完成了对ogg文件重采样mp3音频的操作。

Success open input_file ring.ogg.
audio_decode_ctx frame_size=0, sample_fmt=8, sample_rate=11025, nb_channels=1
audio_encode_ctx frame_size=1152, sample_fmt=6, sample_rate=44100, nb_channels=1
target audio file is output_swrmp3.mp3
Success resample audio frame as mp3 file.

然后打开影音播放器可以正常播放output_swrmp3.mp3,表示上述代码正确实现了将ogg音频数据重采样再转存MP3文件的功能。

标签:采样,缓存,FFmpeg,音频,ogg,swr,frame
From: https://www.cnblogs.com/aqi00/p/18105749

相关文章

  • simple_ffmpeg_decoder(ffmpeg的解码器)
    代码#include<stdio.h>#define__STDC_CONSTANT_MACROS//因为ffmpeg是C语言编写的所以要继承C语言的语法格式extern"C"{#include"libavcodec/avcodec.h"#include"libavformat/avformat.h"#include"libswscale/swscale.h"};intmain(i......
  • FFmpeg开发笔记(十三)Windows环境给FFmpeg集成libopus和libvpx
    ​MP4是最常见的视频封装格式,在《FFmpeg开发实战:从零基础到短视频上线》一书的“1.2.3 自行编译与安装FFmpeg”介绍了如何给FFmpeg集成x264和x265两个库,从而支持H.264和H.265两种标准的编解码。视频的封装格式除了悠久的MP4和ASF之外,还有较新的WebM格式,该格式的音频编码主要采......
  • 视频直播源码,不同业务场景需选择不同方案去缓存数据
    视频直播源码,不同业务场景需选择不同方案去缓存数据在开发视频直播源码时,针对不同业务场景,我们应该选择不同的方案去缓存数据。本文就针对最常见的存储方案和场景做一些分类和介绍一些在Vue/React中的高阶用法,助力前端开发体验和应用的稳定性。前端缓存方案确定不同场......
  • Redis--缓存雪崩、击穿、穿透
    本文转载自:https://xiaolincoding.com/redis/cluster/cache_problem.html 缓存异常会面临的三个问题:缓存雪崩、击穿和穿透。其中,缓存雪崩和缓存击穿主要原因是数据不在缓存中,而导致大量请求访问了数据库,数据库压力骤增,容易引发一系列连锁反应,导致系统奔溃。不过,一旦数据被重新......
  • 美团二面:为什么不推荐使用 MyBatis 二级缓存?大部分人都答不上来!
    为了增加查询的性能,MyBatis提供了二级缓存架构,分为一级缓存和二级缓存。这两级缓存最大的区别就是:一级缓存是会话级别的,只要出了这个SqlSession,缓存就没用了。而二级缓存可以跨会话,多个会话可以使用相同的缓存!一级缓存使用简单,默认就开启。二级缓存需要手动开启,相对复杂,而且要......
  • Unity 音频资源优化
    1、声道设置(1)、不设置单声道音频大小为下图(2)、设置单声道音频大小为下图2、加载类型(1)、DecompressOnLoad使用内存8.1M(2)、CompressedInMemory占用内存2.7M(3)、Streaming占用内存1.5M但是CPU暂用提升了3、采样率和压缩格式设置4、总结简短音......
  • 继上期讲述MATLAB如何读取音频文件,这期讲述如何实现播放读取的音频文件并可以随时停止
    1.右击上期保存的GUI界面(.fig格式文件),点击“在GUIDE中打开“,如下图所示:2.然后按照上期绘制按钮操作,绘制出下图所示的GUI界面:3.再分别右击播放音频按钮和停止播放按钮,按照上期教学,输入各按钮所相对应的代码 ,播放音频按钮的代码是:globalyfs%定义全局变量sound(y,fs);......
  • 视频处理的利器,ffmpeg-python库详解与应用示例
    左手编程,右手年华。大家好,我是一点,关注我,带你走入编程的世界。公众号:一点sir,关注领取python编程资料在数字媒体的时代,视频处理成为了一项重要的技能。无论是剪辑、转码、还是添加特效,都需要强大的工具来处理视频素材。Python作为一门功能强大的编程语言,在视频处理领域也有着广......
  • centos7中ffmpeg的安装方法
    Linux系统安装ffmpeg&升级ffmpeg一、介绍多媒体视频处理工具FFmpeg有非常强大的功能,包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。由于最近要处理音视频格式转换问题,因此需要安装、升级ffmpeg,下面来记录一下踩坑过程。 二、安装ffmpeg1、下载并解压ffmpeg......
  • FFmpeg常用功能
    1.转码视频格式:ffmpeg-iinput.mp4output.avi上述命令将输入的MP4视频文件转换为AVI格式。2.压缩视频文件:ffmpeg-iinput.mp4-vcodeclibx264-crf23output.mp4 该命令使用libx264视频编解码器对输入的MP4文件进行压缩,并将压缩后的视频保存为MP4格式。CRF值(Cons......