首先引入音频帧的概念:

正常人听觉的频率范围大约在20Hz~20kHz之间。
采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。
根据奈奎斯特采样理论,为了保证声音不失真,采样频率应该在40kHz左右。
常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,
如果采用更高的采样频率,还可以达到DVD的音质。
对采样率为44.1kHz的AAC音频进行解码时,一帧的解码时间须控制在23.22毫秒内。
通常是按1024个采样点一帧
分析:
1. AAC
一个AAC原始帧包含某段时间内1024个采样点相关数据。
用1024主要是因为AAC是用的1024点的mdct。
音频帧的播放时间 = 一个AAC帧对应的采样样本的个数 / 采样频率(单位为s)。
采样率(samplerate)为 44100Hz,表示每秒 44100个采样点, 
所以,根据公式,   
音频帧的播放时长 = 一个AAC帧对应的采样点个数 / 采样频率
则,当前一帧的播放时间 = 1024 * 1000000/44100= 23.22ms(单位为ms)
48kHz采样率,
则,当前一帧的播放时间 = 1024 * 1000000/48000= 21.32ms(单位为ms)
22.05kHz采样率,
则,当前一帧的播放时间 = 1024 * 1000000/22050= 46.44ms(单位为ms)
2.MP3 
mp3 每帧均为1152个字节, 
则:
每帧播放时长 = 1152 * 1000000 / sample_rate
例如:sample_rate = 44100HZ时, 
计算出的时长为26.122ms,
这就是经常听到的mp3每帧播放时间固定为26ms的由来。

ffmpeg音频转码:

由于不同格式音频帧数的不同,在使用ffmpeg作音频转码时需要作音频fifo来缓存解码数据,依据编码音频帧需要给对应的大小。

音频fifo可使用ffmpeg中已写好的fifo,定义在libavutil/audio_fifo.h下。

AVAudioFifo,SwrContext定义及初始化:

[cpp] view plain copy    
  1. AVAudioFifo *af = NULL;
  2. SwrContext *resample_context = NULL;
  3. long long pts = 0;
  4. for(int i=0; i<1; i++){
  5. printf(" samplerate input = %d , samplerate output = %d\n",pAudioCodecCtx[i]->sample_rate, AudioEncodeCtx[i]->sample_rate);
  6. resample_context = swr_alloc_set_opts(NULL, av_get_default_channel_layout(AudioEncodeCtx[i]->channels),
  7. AudioEncodeCtx[i]->sample_fmt,
  8. AudioEncodeCtx[i]->sample_rate,
  9. av_get_default_channel_layout(pAudioCodecCtx[i]->channels),
  10. pAudioCodecCtx[i]->sample_fmt,
  11. pAudioCodecCtx[i]->sample_rate,
  12. 0, NULL);
  13. swr_init(resample_context);
  14. }
  15. af = av_audio_fifo_alloc(AudioEncodeCtx[0]->sample_fmt, AudioEncodeCtx[0]->channels, 1);
  16. if(af == NULL)
  17. {
  18. printf("error af \n");
  19. return -1;
  20. }

转码过程:

[cpp] view plain copy    
  1. if (avcodec_decode_audio4(pAudioCodecCtx[i], pAudioframe[i], &frame_size, &pkt) >= 0) {
  2. if (i == 0){
  3. uint8_t *converted_input_samples = NULL;
  4. converted_input_samples = (uint8_t *)calloc(AudioEncodeCtx[i]->channels, sizeof(*converted_input_samples));
  5. av_samples_alloc(&converted_input_samples, NULL, AudioEncodeCtx[i]->channels, pAudioframe[i]->nb_samples, AudioEncodeCtx[i]->sample_fmt, 0);
  6. int error = 0;
  7. if((error = swr_convert(resample_context, &converted_input_samples, pAudioframe[i]->nb_samples,
  8. (const uint8_t**)pAudioframe[i]->extended_data, pAudioframe[i]->nb_samples))<0){
  9. printf("error  : %d\n",error);
  10. }
  11. av_audio_fifo_write(af, (void **)&converted_input_samples, pAudioframe[i]->nb_samples);
  12. int got_frame=0;
  13. //Encode
  14. while(av_audio_fifo_size(af) >= AudioEncodeCtx[i]->frame_size){
  15. int frame_size = FFMIN(av_audio_fifo_size(af),AudioEncodeCtx[i]->frame_size);
  16. pOutAudioframe[i]->nb_samples =  frame_size;
  17. pOutAudioframe[i]->channel_layout = AudioEncodeCtx[i]->channel_layout;
  18. pOutAudioframe[i]->sample_rate = AudioEncodeCtx[i]->sample_rate;
  19. pOutAudioframe[i]->format = AudioEncodeCtx[i]->sample_fmt;
  20. av_frame_get_buffer(pOutAudioframe[i], 0);
  21. av_audio_fifo_read(af, (void **)&pOutAudioframe[i]->data, frame_size);
  22. pOutAudioframe[i]->pts=pts;
  23. pts += pOutAudioframe[i]->nb_samples;
  24. audio_pkt.data = NULL;
  25. audio_pkt.size = 0;
  26. av_init_packet(&audio_pkt);
  27. avcodec_encode_audio2(AudioEncodeCtx[i], &audio_pkt, pOutAudioframe[i], &got_frame);
  28. }
  29. }
  30. break;
  31. }
http://blog.csdn.net/xiaojun111111/article/details/52683843

基于ffmpeg的音频转码相关推荐

  1. 基于 FFMPEG 的音频编解码(一):Hello FFMPEG,安装与编译

    Hello FFMPEG 基于 FFMPEG 的音频编解码(一):Hello FFMPEG,安装与编译 基于 FFMPEG 的音频编解码(二):音频解码 基于 FFMPEG 的音频编解码(三):音频编 ...

  2. 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)

    本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样数据编码为AAC的压缩编码数据.编码器代码十分简单,但是每一行代码都很重要.通过看本编码器的源代码,可以了解FFMPEG音 ...

  3. 基于 FFMPEG 的音频编解码(三):音频编码

    音频编码 基于 FFMPEG 的音频编解码(一):Hello FFMPEG,安装与编译 基于 FFMPEG 的音频编解码(二):音频解码 基于 FFMPEG 的音频编解码(三):音频编码 在前面文章中 ...

  4. 基于 FFMPEG 的音频编解码(二):音频解码

    音频解码 基于 FFMPEG 的音频编解码(一):Hello FFMPEG,安装与编译 基于 FFMPEG 的音频编解码(二):音频解码 基于 FFMPEG 的音频编解码(三):音频编码 在 Hell ...

  5. Qt基于FFmpeg实现视频转码

    一.简述转码 转码的作用:封装格式的实现.(h264->mov.mp4.flv.avi(封装格式)等) 之前博客中提到如何把像素数据编码得到 H264 的压缩码流数据,但是一般的播放工具是没法直 ...

  6. android 混音 源码,FFmpegAndroid android 端基于 FFmpeg 实现音频剪切、拼接、转码、混音、编解码;视频剪切、水印、截图、转码、编 @codeKK c开源站...

    android 端基于 FFmpeg 库的使用 添加编译 ffmpeg.shine.mp3lame.x264 源码的参考脚本 目前音视频相关处理: 音频剪切.拼接 音频混音 音频转码 音视频合成 音频 ...

  7. 利用ffmpeg进行音频转码

    在进行音频转码前,首先需要查看我们原始音频中的编码格式以及一些重要的音频参数,包括:采样率,采样格式,通道类型等. 通过将原始的编码格式,采样率,采样格式,通道类型与目标编码格式,采样率,采样格式,通 ...

  8. C# 使用 ffmpeg 进行音频转码

    先放一下 ffmpeg 的官方文档以及下载地址: 官方文档:http://ffmpeg.org/ffmpeg.html 下载地址:http://ffmpeg.org/download.html 用 f ...

  9. ffmpeg之音频转码及重采样

    最近在用ffmpeg做音频这一块,奈何网上这一块的确少,能找到的有些还不能用.今天算是磕磕绊绊把代码调通了.写篇博客讲讲我的拙见. 之所有把转码和重采样写在一起,因为感觉他们是同一个流程完成的工作.下 ...

最新文章

  1. 大数据下的电商新打法
  2. Spring(三)AOP面向切面编程
  3. python学习笔记day08 文件功能详解
  4. loadrunner编写脚本常用策略,用以记录,看的懂的拿走,看不懂说明与你有缘无份...
  5. 用户管理界面开源代码_商城系统开源代码对于企业有利还是有弊?
  6. 白嫖我常用的 11 个超火的前端必备在线工具,终于有时间上班摸鱼了
  7. 好记心不如烂笔头,ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题...
  8. 在浏览器里使用SAPGUI里的SE80
  9. pythonpil库过滤图像contour_一秒钟带你走进P图世界-----(python)PIL库的使用
  10. bouncycastle NoSuchFieldError:xxx 版本冲突
  11. 【转】在C#中使用SQLite
  12. 剑指offer面试题[9-3]-矩形覆盖
  13. Java小白进阶笔记(5)-进阶面向对象
  14. 计算机二级c语言编译题评分,计算机二级C语言题型和评分标准
  15. bl wn810a linux驱动下载,BL-LW06-AR/BL-WN810A无线网卡驱动for all【支持所有系统】
  16. Java多线程+IO流+网络编程+MySQL+JDBC编程实现多人联机版坦克大战
  17. BELLHOP 关于Actup冲激响应的绘制
  18. 微信ios版本的两个灰度功能和一些小改变
  19. 通信原理仿真100例 | 多普勒频移的matlab仿真
  20. 24的两个好的中文论坛

热门文章

  1. Java基础入门(持续更新)
  2. 天津再出新政 经适房限价房也可公积金贷款
  3. 完成selec函数的TCP客户端
  4. 全局前置守卫--路由拦截
  5. RUNJS优秀代码搜集
  6. ERROR: Module load completed but symbols could not be loaded for ntoskrnl.exe Loading Kernel Symbols
  7. 26个充满创意的平面广告作品欣赏
  8. 单卡加载多卡训练保存的模型
  9. 应用服务器性能优化总结
  10. 5g主题演讲_主题演讲-比尔·盖茨-继续