本人刚开始学习ffmpeg,写此博客作为笔记,也希望能帮助其他刚入门的童鞋!ffmpeg源码下载和编译本文就直接跳过,源码doc/example路径下有很多demo,可以为我们演示ffmpeg的api如何使用,对我们理解ffmpeg的api有很大帮助。本文将介绍decode_audio.c如何编译使用。

代码主体框架:
1、根据Codec ID查找编码器(Codec)
2、根据编码器 ID查找解析器(Parse)。注:解析器用于解封装,解封装后的数据放到AVPacket中
3、根据Codec创建AVCodecContext。
4、循环读取输入文件,送入解析器解封装出AVPacket,然后再解码出AVFrame数据。
inputFile ----(解封装)–> AVPacket —(解码)—>AVFrame —(保存pcm数据)–> File.pcm

注:音频中一个AVFrame可能包含多个音频帧。而视频则一个AVFrame对应一帧图像。

因测试方便,我修改了部分代码用于适配FLAC格式的音频文件。代码如下

/** Copyright (c) 2001 Fabrice Bellard** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.*//*** @file* audio decoding with libavcodec API example** @example decode_audio.c*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include <libavutil/frame.h>
#include <libavutil/mem.h>#include <libavcodec/avcodec.h>#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,FILE *outfile)
{int i, ch;int ret, data_size;/* send the packet with the compressed data to the decoder */ret = avcodec_send_packet(dec_ctx, pkt);if (ret < 0) {fprintf(stderr, "Error submitting the packet to the decoder\n");exit(1);}/* read all the output frames (in general there may be any number of them */while (ret >= 0) {ret = avcodec_receive_frame(dec_ctx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)return;else if (ret < 0) {fprintf(stderr, "Error during decoding\n");exit(1);}data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);if (data_size < 0) {/* This should not occur, checking just for paranoia */fprintf(stderr, "Failed to calculate data size\n");exit(1);}printf("+++++ FLC-DBG: data_size = %d +++++\n", data_size); //单通道样本(sample)大小printf("+++++ FLC-DBG: frame->nb_samples = %d +++++\n", frame->nb_samples); //帧个数printf("+++++ FLC-DBG: dec_ctx->channels = %d +++++\n", dec_ctx->channels); //通道数printf("+++++ FLC-DBG: frame->linesize[0] = %d +++++\n", frame->linesize[0]); //frame->data[0]数据长度(Bytes)printf("+++++ FLC-DBG: frame->linesize[1] = %d +++++\n", frame->linesize[1]);//FLAC格式的文件,解码后数据都放在frame->data[0]中,长度可根据frame->linesize[0]来获取。//原始代码不同声道数据存在不同的frame->data[i]中。
//        for (i = 0; i < frame->nb_samples; i++)
//            for (ch = 0; ch < dec_ctx->channels; ch++)
//                fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);//仅保存单通道数据。//for (i = 0; i < frame->nb_samples; i++)//  fwrite(frame->data[0] + i * data_size*dec_ctx->channels, 1, data_size, outfile);//保存全部通道fwrite(frame->data[0], 1, frame->linesize[0], outfile);}
}int main(int argc, char **argv)
{const char *outfilename, *filename;const AVCodec *codec;AVCodecContext *c= NULL;AVCodecParserContext *parser = NULL;int len, ret;FILE *f, *outfile;uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];uint8_t *data;size_t   data_size;AVPacket *pkt;AVFrame *decoded_frame = NULL;if (argc <= 2) {fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);exit(0);}filename    = argv[1];outfilename = argv[2];pkt = av_packet_alloc();/* find the MPEG audio decoder *///此处修改为FLAC的codec id。//codec = avcodec_find_decoder(AV_CODEC_ID_MP2);codec = avcodec_find_decoder(AV_CODEC_ID_FLAC);if (!codec) {fprintf(stderr, "Codec not found\n");exit(1);}parser = av_parser_init(codec->id);if (!parser) {fprintf(stderr, "Parser not found\n");exit(1);}c = avcodec_alloc_context3(codec);if (!c) {fprintf(stderr, "Could not allocate audio codec context\n");exit(1);}/* open it */if (avcodec_open2(c, codec, NULL) < 0) {fprintf(stderr, "Could not open codec\n");exit(1);}f = fopen(filename, "rb");if (!f) {fprintf(stderr, "Could not open %s\n", filename);exit(1);}outfile = fopen(outfilename, "wb");if (!outfile) {av_free(c);exit(1);}/* decode until eof */data      = inbuf;data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);while (data_size > 0) {if (!decoded_frame) {if (!(decoded_frame = av_frame_alloc())) {fprintf(stderr, "Could not allocate audio frame\n");exit(1);}}ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,data, data_size,AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);if (ret < 0) {fprintf(stderr, "Error while parsing\n");exit(1);}data      += ret;data_size -= ret;printf("\n+++++ FLC-DBG: pkt->data:%p, pkt->size:%d +++++\n",pkt->data, pkt->size);if (pkt->size)decode(c, pkt, decoded_frame, outfile);if (data_size < AUDIO_REFILL_THRESH) {memmove(inbuf, data, data_size);data = inbuf;len = fread(data + data_size, 1,AUDIO_INBUF_SIZE - data_size, f);if (len > 0)data_size += len;}}/* flush the decoder */pkt->data = NULL;pkt->size = 0;decode(c, pkt, decoded_frame, outfile);fclose(outfile);fclose(f);avcodec_free_context(&c);av_parser_close(parser);av_frame_free(&decoded_frame);av_packet_free(&pkt);return 0;
}

使用方法

./decode_audio ~/Music/yesterdayOnceMore.flac ~/Music/output.pcm

查看编码后的数据,使用Audacity,选择导入原始数据。

配置原始数据的采样率、位宽、声道数。


点击播放按钮,试听我们解码出来的文件吧

整个工程的下载地址:
https://download.csdn.net/download/lyy901135/11296755
注:Makefile中需要对头文件和库的路径进行适配。

ffmpeg example演示教程 -AudioDecode相关推荐

  1. onnx 测试_ONNX 现场演示教程

    ONNX 现场演示教程 译者:冯宝宝 本教程将向您展示如何使用ONNX将已从PyTorch导出的神经模型传输模型转换为Apple CoreML格式.这将允许您在Apple设备上轻松运行深度学习模型,在 ...

  2. 详细介绍Qt,ffmpeg 和SDl 教程之间的联系

    Qt与 ffmpeg 与 SDl 教程是本文要介绍的内容,从多个角度介绍本文,运用了qmake,先来看内容. 1.  注释 从" #" 开始,到这一行结束. 2.  指定源文件 1 ...

  3. 关于编译FFMPEG的初级教程

    关于编译FFMPEG的初级教程 1.首先我们要下载相关工具,这里不多说,大家按照我的地址去下载文件就好了 MINGW下载地址:http://prdownloads.sourceforge.net/mi ...

  4. unity 实验演示 教程_铁匠常见问题解答和Unity演示团队

    unity 实验演示 教程 Since showing our short film The Blacksmith at GDC 2015 in March, we've received many ...

  5. 【题目】了解ffmpeg以及FFmpeg下载安装教程

    [时间]2018.09.15 [题目]了解ffmpeg以及FFmpeg下载安装教程 [参考链接]https://blog.csdn.net/yang725614/article/details/796 ...

  6. centos安装ffmpeg php,lnmp下安装ffmpeg和ffmpeg-php教程

    现在我将我的过程方法发布出来. 以下都是用SSH命令 一.安装ffmpeg 操作系统:centos6 安装ffmpeg有两种方式:①.用源码包安装,这个不知道怎么回事老是报错②用yum命令安装,cen ...

  7. ffmpeg 和 SDL 教程2:输出到屏幕

    2019独角兽企业重金招聘Python工程师标准>>> SDL和视频 为了在屏幕上显示,我们将使用SDL.SDL是Simple Direct Layer的缩写.它是一个出色的多媒体库 ...

  8. PyTorch 1.0 中文官方教程:ONNX 现场演示教程

    译者:冯宝宝 本教程将向您展示如何使用ONNX将已从PyTorch导出的神经模型传输模型转换为Apple CoreML格式.这将允许您在Apple设备上轻松运行深度学习模型,在这种情况下,可以从摄像机 ...

  9. 【FFMPEG】vs2019调用FFmpeg动态库教程

    测试环境: windows10 64位 visual studio 2019 ffmpeg-4.2.2 如何自己编译FFmpeg点击此链接: [FFMPEG]win10上编译FFmpeg-64位动态库 ...

最新文章

  1. 东软信息学院java试题,东软Java笔试题答案
  2. Apple System: Error: ENFILE: file table overflow
  3. python 日期 格式转换 英文_量化数据预处理-中文日期(含)转英文日期
  4. OpenCV中 IplImage 与 Mat的区别
  5. 增加索引提高查询效率
  6. 聊聊SQL优化的基础思路
  7. 8. GD32F103C8T6 定时器-输入捕获测频率
  8. linux去除内容重复行,实例详细说明linux下去除重复行命令uniq
  9. 阿里面试官最新分享的Java面试宝典,含8大核心内容讲解
  10. 瑞雪时晴,不亦快哉   ——图灵十一月月刊
  11. 带隙基准电压-Bandgap详细介绍
  12. itext7实现参数和图片替换
  13. Unity美术场景制作基础流程和注意事项梳理
  14. windows 快捷键关闭屏幕
  15. 【视野】解密腾讯完整前端技术体系
  16. 阿里云商标注册快速上手笔记(新手图文教程)
  17. 酷炫多彩的个性化词云可视化
  18. ASP医院管理系统—病历管理系统的设计与实现
  19. 丁晓钟怎么样_丁晓钟老师的课程怎么样?
  20. 驼峰命名法和下划线命名法互转

热门文章

  1. 写互联网文案的新技巧
  2. java中定义一个时间_Java中的日期和时间
  3. 手机断触怎么办_手机屏幕断触怎么办?弹片微针模组解决手机屏幕测试难题
  4. 《安富莱嵌入式周报》第266期:真正模拟DA神的威力,全开源nV级测量仪表挑战赛结束,欣赏震撼设计过程
  5. algo_KNN(k-nearest neighbor)
  6. Zookeeper分布式锁
  7. 全面质量管理体系运转的基本方法 PDCA
  8. 题解:单词排序(水)
  9. 脚崴了!又肿又疼怎么办?
  10. 设计模式(二)(C++)