1、目标:使用ffmpeg库函数,将音频码流(AAC、mp3等)解码为pcm采样数据

2、音频解码过程

1)根据输入的码流文件,初始化格式上下文(fmt_ctx);
2)根据格式上下文,找到合适的解码器(Codec),同时返回流索引(音频对应streams[0],视频对应stream[1]);
3)根据格式上下文,获取编码时的参数设置(fmt_ctx->streams[index]->codecpar);
4)创建解码器的上下文(cod_ctx),根据编码参数初始化解码器上下文,打开解码器;
5)设置解码输出的相关参数,初始化重采样上下文
6)创建packet存储原来的编码数据,创建frame存储解码后的像素/采样数据
7)循环读取一帧编码数据,并进行转码,转码后的采样数据写入输出文件。
8)关闭文件,释放资源

3、代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"#define sourcefile "testvideo/output.aac"int init_fmt_ctx(AVFormatContext **fmt_ctx, const char *file) {*fmt_ctx = avformat_alloc_context();if (*fmt_ctx == NULL) {printf("avformat_alloc failed.\n");return -1;} if (avformat_open_input(fmt_ctx, file, NULL, NULL) != 0) {printf("Couldn't open input stream.\n");return -1;}if (avformat_find_stream_info(*fmt_ctx, NULL) < 0) {printf("Couldn't find stream information.\n");return -1;}// 转存有效信息到stderrav_dump_format(*fmt_ctx, 0, file, 0);return 0;
}int main(int argc, char *argv[])
{AVFormatContext *fmt_ctx = NULL;AVCodecContext *cod_ctx = NULL;AVCodec *cod = NULL; AVPacket packet;// 1. 打开相关流,初始化fmt_ctxif (init_fmt_ctx(&fmt_ctx, sourcefile) < 0) goto _Error;// 2. 找到合适的编解码器,返回第一帧数据索引int stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1,
-1, &cod, -1);if (cod == NULL) {printf("Couldn't find codec.\n");goto _Error;}// printf("stream_index:%d\n", stream_index);// 3. 获取编码时的参数AVCodecParameters *param = fmt_ctx->streams[stream_index]->codecpar;// 4. 设置解码上下文,并打开解码器cod_ctx = avcodec_alloc_context3(cod);avcodec_parameters_to_context(cod_ctx, param);if (avcodec_open2(cod_ctx, cod, NULL) < 0) {printf("Couldn't open codec.\n");goto _Error;}// 5. 重采样初始化和前后参数设置/*********** 设置输出相关参数 ******************/int out_channels = param->channels;int out_sample_fmt = AV_SAMPLE_FMT_S16;int out_sample_rate = param->sample_rate;int out_nb_samples = param->frame_size;uint64_t out_channel_layout = param->channel_layout;// 初始化重采样上下文struct SwrContext *convert_ctx = swr_alloc();convert_ctx = swr_alloc_set_opts(convert_ctx, \out_channel_layout, out_sample_fmt, out_sample_rate, \  param->channel_layout, param->format, param->sample_rate,\0, NULL);swr_init(convert_ctx);// 6. 创建packet,存储编码数据av_init_packet(&packet);// 创建Frame, 存储解码后的采样数据AVFrame *frame = av_frame_alloc();frame->channels = out_channels;          // 通道数不变frame->format = out_sample_fmt;          // 采样位深16bitframe->nb_samples = out_nb_samples;      // 单通道采样个数av_frame_get_buffer(frame, 0);// 7. 每次读取一帧编码数据,然后进行转码FILE *fout = fopen("output.pcm", "w+");uint8_t **data = (uint8_t **)av_calloc(1, sizeof(*data));int data_size = av_samples_alloc(data, NULL, \out_channels, out_nb_samples, out_sample_fmt, 0);while (av_read_frame(fmt_ctx, &packet) >= 0) {if (packet.stream_index != stream_index) continue;if (avcodec_send_packet(cod_ctx, &packet) < 0) {printf("Decode error.\n");goto _Error;}while (avcodec_receive_frame(cod_ctx, frame) >= 0) {swr_convert(convert_ctx, data, data_size, \(const uint8_t **)frame->data, frame->nb_samples);fwrite(data[0], 1, data_size, fout);}av_packet_unref(&packet);}_Error:// 8. 关闭文件,释放资源    if (fmt_ctx) {avformat_close_input(&fmt_ctx);avformat_free_context(fmt_ctx);} if (cod_ctx) {avcodec_close(cod_ctx);avcodec_free_context(&cod_ctx);}if (convert_ctx) {swr_free(&convert_ctx);}if (fout) { fclose(fout);}return 0;
}

4、编译运行:

#!/bin/sh# myrun.sh --- ffmpeg相关程序运行脚本
file=$1gcc $file.c -I include/ -L lib/ -lavdevice -lavformat -lavfilter -lavcodec -lswresample -lswscale -lavutil  # -o $file

相关文章推荐:AAC音频码流解析

ffmpeg音视频编码入门:音频解码(acc/mp3 转 pcm)相关推荐

  1. 视频教程-FFmpeg音视频编码实战屏幕录像机视频课程-基于QT5和FFMpegSDK-C/C++

    FFmpeg音视频编码实战屏幕录像机视频课程-基于QT5和FFMpegSDK 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟 ...

  2. FFmpeg音视频编码实战屏幕录像机视频课程-基于QT5和FFMpegSDK-夏曹俊-专题视频课程...

    FFmpeg音视频编码实战屏幕录像机视频课程-基于QT5和FFMpegSDK-3798人已学习 课程介绍         本课程讲解的是基于流行的直播技术 FFMpeg3.3音视频处理框架,和应用广的 ...

  3. FFmpeg从视频中提取音频保存为mp3文件

    如何把视频文件中的音频数据提取出来,网络上有不少音频提取工具,但作为技术人员提到音视频处理,肯定会想到FFmpeg.本文介绍了如何基于FFmpeg从视频中提取音频,然后将音频保存为mp3格式的音频文件 ...

  4. 学习笔记(01):FFmpeg音视频编码实战屏幕录像机视频课程-基于QT5和FFMpegSDK-音视频编码类封装介绍和使用ffmpeg工具抽取rgb和pcm...

    立即学习:https://edu.csdn.net/course/play/5384/98363?utm_source=blogtoedu 通过ffmpeg抽取rgb和pcm

  5. 【音视频零基础入门 1】视频播放器原理、流媒体协议、封装格式、视频编码、音频编码

    [音视频零基础入门 1]视频播放器原理.流媒体协议.封装格式.视频编码 一.视频播放器原理 1.1 解协议 1.2 解封装 1.3 解码 1.4 视音频同步 二.流媒体协议 三.封装格式 四.封装格式 ...

  6. ffmpeg音视频编解码入门

    一.ffmpeg下载与安装 在官网https://ffmpeg.zeranoe.com/builds/中,下载static版本的ffmpeg文件,解压后里面的bin文件夹里包含了三个.exe文件,其中 ...

  7. FFmpeg音视频编解码示例

    FFmpeg示例程序集:https://www3.nd.edu/~sjiang1/docio/ffmpeg_doc/globals_eval.html FFmpeg音视频编解码示例:https://w ...

  8. FFMPEG音视频同步-音视频实时采集并编码推流

    FFMPEG音视频同步-音视频实时采集并编码推流 //------------------------------------------------------------------------- ...

  9. Atitit ffmpeg功能表 多媒体处理类库工具 音频视频 1.1.ffmpeg音视频合成  1.2.Atitit 视频音频分离 提取法 1.3.ffmpeg对视频封装和分离 使用ffmpeg对

    Atitit ffmpeg功能表 多媒体处理类库工具 音频视频 目录 1.1. ffmpeg音视频合成 1 1.2. Atitit 视频音频分离 提取法 1 1.3. ffmpeg对视频封装和分离 1 ...

  10. 音视频从入门到精通——FFmpeg 播放器实现音视频同步的三种方式

    老人们经常说,播放器对音频和视频的播放没有绝对的静态的同步,只有相对的动态的同步,实际上音视频同步就是一个"你追我赶"的过程. 音视频的同步方式有 3 种,即:音视频分别向系统时钟 ...

最新文章

  1. 麦肯锡:优秀数据科学家的5个特征!
  2. 优化asp.net ajax的脚本资源下载
  3. App主流UI框架结构
  4. hideprocess in bcb
  5. 总帐明细账对账不平数据库修改
  6. oppo手机计算机,OPPO手机助手
  7. HTML知识积累及实践(四) - 表单元素
  8. 网络运维网管解决方案
  9. 假装内卷,才是互联网人的骚操作
  10. nginx的log_format日志格式和字段介绍
  11. 【vpn异地组网专题】linux(centos7)安装 PPTP服务器
  12. 3年开发了5个私人项目:自动化办公、网站、机器人、小程序...免费开源,拿走不谢~
  13. 解构瑞幸小鹿茶:两大战场、一套逻辑、一个梦想
  14. f2fs系列文章fsck(五)
  15. 大数据实训-大二下期
  16. .NET 图片格式转换
  17. 使用antd-pro组件 实现图片上传和图片编辑
  18. 【Camunda六】Camunda实现会签和或签
  19. 大数据平台开源实施的难点
  20. 零基础HTML入门教程(11)--初识VSCode

热门文章

  1. c语言putchar_C语言写一个小程序,胖胖的爱心桃
  2. 模拟计算机用英语怎么说,电脑里的 属性 英语怎么说
  3. QT 中QComboBox控件鼠标事件过滤
  4. SAP 批量下载表数据到EXCEL中
  5. 如何编译Android的kernel,如何下载并编译Android 4.0内核源码Goldfish(图文)
  6. 颜宁谈为何选择深圳:一拍即合!我麻溜地向普林斯顿递了辞职申请
  7. 实体词典 情感词典_情感词典最全版
  8. 《圈圈教你玩USB》 第二章 USB 硬件系统设计_测试程序的编写和调试——看书笔记
  9. VB编程必备!_VB源码之友(内含-下载-破解-使用方法)
  10. Linux和UNIX操作系统的关系及区别(详解)