前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >最简单的基于FFMPEG的音频编码器(PCM编码为AAC)

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

作者头像
全栈程序员站长
发布于 2022-07-08 10:07:55
发布于 2022-07-08 10:07:55
1.3K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是全栈君。

本文介绍一个最简单的基于FFMPEG的音频编码器。该编码器实现了PCM音频採样数据编码为AAC的压缩编码数据。编码器代码十分简单,可是每一行代码都非常重要。通过看本编码器的源码。能够了解FFMPEG音频编码的流程。

本程序使用最新版的类库(编译时间为2014.5.6)。开发平台为VC2010。全部的配置都已经做好,仅仅须要执行就能够了。

流程(2014.9.29更新)

以下附一张使用FFmpeg编码音频的流程图。

使用该流程。不仅能够编码AAC的音频,并且能够编码MP3,MP2等等各种FFmpeg支持的音频。图中蓝色背景的函数是实际输出数据的函数。

浅绿色的函数是音频编码的函数。

简介一下流程中各个函数的意义:

av_register_all():注冊FFmpeg全部编解码器。 avformat_alloc_output_context2():初始化输出码流的AVFormatContext。 avio_open():打开输出文件。 av_new_stream():创建输出码流的AVStream。 avcodec_find_encoder():查找编码器。 avcodec_open2():打开编码器。 avformat_write_header():写文件头(对于某些没有文件头的封装格式,不须要此函数。比方说MPEG2TS)。 avcodec_encode_audio2():编码音频。即将AVFrame(存储PCM採样数据)编码为AVPacket(存储AAC,MP3等格式的码流数据)。 av_write_frame():将编码后的视频码流写入文件。 av_write_trailer():写文件尾(对于某些没有文件头的封装格式。不须要此函数。比方说MPEG2TS)。

代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 *最简单的基于FFmpeg的音频编码器
 *Simplest FFmpeg Audio Encoder
 *
 *雷霄骅 Lei Xiaohua
 *leixiaohua1020@126.com
 *中国传媒大学/数字电视技术
 *Communication University of China / Digital TV Technology
 *http://blog.csdn.net/leixiaohua1020
 *
 *本程序实现了音频PCM採样数据编码为压缩码流(MP3。WMA,AAC等)。 *是最简单的FFmpeg音频编码方面的教程。 *通过学习本样例能够了解FFmpeg的编码流程。 *This software encode PCM data to AAC bitstream. *It's the simplest audio encoding software based on FFmpeg.  *Suitable for beginner of FFmpeg  */#include <stdio.h>#define __STDC_CONSTANT_MACROS#ifdef _WIN32//Windowsextern "C"{#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"};#else//Linux...#ifdef __cplusplusextern "C"{#endif#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>#ifdef __cplusplus};#endif#endifint flush_encoder(AVFormatContext *fmt_ctx,unsigned int stream_index){	int ret;	int got_frame;	AVPacket enc_pkt;	if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &		CODEC_CAP_DELAY))		return 0;	while (1) {		enc_pkt.data = NULL;		enc_pkt.size = 0;		av_init_packet(&enc_pkt);		ret = avcodec_encode_audio2 (fmt_ctx->streams[stream_index]->codec, &enc_pkt,			NULL, &got_frame);		av_frame_free(NULL);		if (ret < 0)			break;		if (!got_frame){			ret=0;			break;		}		printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n",enc_pkt.size);		/* mux encoded frame */		ret = av_write_frame(fmt_ctx, &enc_pkt);		if (ret < 0)			break;	}	return ret;}int main(int argc, char* argv[]){	AVFormatContext* pFormatCtx;	AVOutputFormat* fmt;	AVStream* audio_st;	AVCodecContext* pCodecCtx;	AVCodec* pCodec;	uint8_t* frame_buf;	AVFrame* pFrame;	AVPacket pkt;	int got_frame=0;	int ret=0;	int size=0;	FILE *in_file=NULL;	                        //Raw PCM data	int framenum=1000;                          //Audio frame number	const char* out_file = "tdjm.aac";          //Output URL	int i;	in_file= fopen("tdjm.pcm", "rb");	av_register_all();	//Method 1.	pFormatCtx = avformat_alloc_context();	fmt = av_guess_format(NULL, out_file, NULL);	pFormatCtx->oformat = fmt;	//Method 2.	//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);	//fmt = pFormatCtx->oformat;	//Open output URL	if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){		printf("Failed to open output file!\n");		return -1;	}	audio_st = avformat_new_stream(pFormatCtx, 0);	if (audio_st==NULL){		return -1;	}	pCodecCtx = audio_st->codec;	pCodecCtx->codec_id = fmt->audio_codec;	pCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;	pCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;	pCodecCtx->sample_rate= 44100;	pCodecCtx->channel_layout=AV_CH_LAYOUT_STEREO;	pCodecCtx->channels = av_get_channel_layout_nb_channels(pCodecCtx->channel_layout);	pCodecCtx->bit_rate = 64000;  	//Show some information	av_dump_format(pFormatCtx, 0, out_file, 1);	pCodec = avcodec_find_encoder(pCodecCtx->codec_id);	if (!pCodec){		printf("Can not find encoder!\n");		return -1;	}	if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){		printf("Failed to open encoder!\n");		return -1;	}	pFrame = av_frame_alloc();	pFrame->nb_samples= pCodecCtx->frame_size;	pFrame->format= pCodecCtx->sample_fmt;		size = av_samples_get_buffer_size(NULL, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);	frame_buf = (uint8_t *)av_malloc(size);	avcodec_fill_audio_frame(pFrame, pCodecCtx->channels, pCodecCtx->sample_fmt,(const uint8_t*)frame_buf, size, 1);		//Write Header	avformat_write_header(pFormatCtx,NULL);	av_new_packet(&pkt,size);	for (i=0; i<framenum; i++){		//Read PCM		if (fread(frame_buf, 1, size, in_file) <= 0){			printf("Failed to read raw data! \n");			return -1;		}else if(feof(in_file)){			break;		}		pFrame->data[0] = frame_buf;  //PCM Data		pFrame->pts=i*100;		got_frame=0;		//Encode		ret = avcodec_encode_audio2(pCodecCtx, &pkt,pFrame, &got_frame);		if(ret < 0){			printf("Failed to encode!\n");			return -1;		}		if (got_frame==1){			printf("Succeed to encode 1 frame! \tsize:%5d\n",pkt.size);			pkt.stream_index = audio_st->index;			ret = av_write_frame(pFormatCtx, &pkt);			av_free_packet(&pkt);		}	}		//Flush Encoder	ret = flush_encoder(pFormatCtx,0);	if (ret < 0) {		printf("Flushing encoder failed\n");		return -1;	}	//Write Trailer	av_write_trailer(pFormatCtx);	//Clean	if (audio_st){		avcodec_close(audio_st->codec);		av_free(pFrame);		av_free(frame_buf);	}	avio_close(pFormatCtx->pb);	avformat_free_context(pFormatCtx);	fclose(in_file);	return 0;}

结果

程序执行完毕后。会将一个PCM採样数据文件(*.pcm)编码为AAC码流文件(*.aac)。

下载

simplest ffmpeg audio encoder

项目主页

SourceForge:https://sourceforge.net/projects/simplestffmpegaudioencoder/

Github:https://github.com/leixiaohua1020/simplest_ffmpeg_audio_encoder

开源中国:http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_audio_encoder

CSDNproject下载地址:

http://download.csdn.net/detail/leixiaohua1020/7324091

PUDNproject下载地址:

http://www.pudn.com/downloads644/sourcecode/multimedia/detail2605236.html

更新-1.1 (2015.2.13)=========================================

这次考虑到了跨平台的要求,调整了源码。经过这次调整之后,源码能够在以下平台编译通过:

VC++:打开sln文件就可以编译,无需配置。

cl.exe:打开compile_cl.bat就可以命令行下使用cl.exe进行编译,注意可能须要依照VC的安装路径调整脚本里面的參数。编译命令例如以下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
::VS2010 Environment
call "D:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
::include
@set INCLUDE=include;%INCLUDE%
::lib
@set LIB=lib;%LIB%
::compile and link
cl simplest_ffmpeg_audio_encoder.cpp /link avcodec.lib avformat.lib avutil.lib ^
avdevice.lib avfilter.lib postproc.lib swresample.lib swscale.lib /OPT:NOREF

MinGW:MinGW命令行下执行compile_mingw.sh就可以使用MinGW的g++进行编译。 编译命令例如以下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
g++ simplest_ffmpeg_audio_encoder.cpp -g -o simplest_ffmpeg_audio_encoder.exe \
-I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil

GCC:Linux或者MacOS命令行下执行compile_gcc.sh就可以使用GCC进行编译。编译命令例如以下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc simplest_ffmpeg_audio_encoder.cpp -g -o simplest_ffmpeg_audio_encoder.out \
-I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil

PS:相关的编译命令已经保存到了project目录中

CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/8445209

SourceForge上已经更新。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/116024.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年1月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
java的poi技术读取和导入Excel
http://www.cnblogs.com/hongten/gallery/image/111987.html
Hongten
2018/09/13
1.1K0
10、借助POI实现Java生成并打印excel报表(1)
该文章介绍了如何利用Excel表格进行数据分析。文章首先介绍了如何导入Excel表格,然后介绍了如何使用VLOOKUP函数和IF函数对数据进行分析和处理。接着,文章介绍了如何使用Excel表格进行数据可视化,包括创建柱状图和折线图。最后,文章介绍了如何使用Excel表格进行数据导出和打印。
YGingko
2017/12/28
5.3K0
Excel工具类
代码 package com.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import j
码客说
2019/10/22
6910
java导出excel的两种方式
这篇在我的csdn上阅读数近三万,点赞几十个,算是比较火的一篇了,在这里分享一下,公司总免不了与文件导入导出打交道,前段时间我做了媒体预览服务,媒体打包服务,最近又在做大文件拆分服务,以后会分享其他相关的,没时间读,可以先收藏。
jiankang666
2022/05/12
2.6K0
java导出excel的两种方式
POI -纯java代码实现导出excel表格
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 HSSF - 提供读写Microsoft Excel格式档案的功能。 XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。 HWPF - 提供读写Microsoft Word格式档案的功能。 HSLF - 提供读写Microsoft PowerPoint格式档案的功能。 HDGF - 提供读写Microsoft Visio格式档案的
小帅丶
2018/02/08
2.7K0
Excel文件导入导出操作
日常开发工作中对于文件的相关操作大家多少都会涉及:上传解析、数据导出等。此篇内容主要分享一下工作中常用的Excel文件的解析和导出工作类实现。
沁溪源
2020/10/13
1.3K0
JavaWeb中将数据从数据库导出到Excel表的实例
这个博客里面开发的项目,使用POI导出Excel,经过修改支持文件弹窗选择,在使用中包括以下几步。 1.添加jar包
geekfly
2022/04/24
1.1K0
JavaWeb中将数据从数据库导出到Excel表的实例
利用POI组件导出Excel的简单示例
//模拟数据实体类 package excel; import java.util.Date; public class Student { private int id; private String name; private int age; private Date birth; public Student() { } public Student(int id, String name, int age, Date birth) { this.id = id; th
冷冷
2018/02/08
7350
Java 实现文件批量导入导出最佳实践(兼容xls,xlsx)
java实现文件的导入导出数据库,目前在大部分系统中是比较常见的功能了,今天写个小demo来理解其原理,没接触过的同学也可以看看参考下。
业余草
2020/07/10
4.1K0
Java 实现文件批量导入导出最佳实践(兼容xls,xlsx)
java导出excel
话不多说,上代码: ExcelUtils 工具类 package com.lvic.foss.web.utils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFRow
斯文的程序
2019/11/07
2.1K0
使用POI操作Excel
官网:http://poi.apache.org ,POI支持office的所有版本
HUC思梦
2020/09/03
1K0
java的poi技术读,写Excel[2003-2007,2010]
在上一篇blog:java的poi技术读取Excel[2003-2007,2010] 中介绍了关于java中的poi技术读取excel的相关操作
Hongten
2018/09/13
1.1K0
java的poi技术读,写Excel[2003-2007,2010]
java使用POI处理EXCEL的核心类(二)
接上一篇写了使用poi导出excel,今天把读取excel的方法补上,核心类如下:
用户5640963
2019/07/28
8830
Java 利用poi把数据库中数据导入Excel
使用时先把poi包导入工程的path,注意只需要导入poi包即可,下载后有三个jar包
Hongten
2018/09/13
2.1K0
Java 利用poi把数据库中数据导入Excel
java POI读取Excel文件
java POI读取Excel文件 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import
大师级码师
2021/09/21
9080
POI 方式-excle 表格导出实现-java-poi
效果: jsp 页面 用的Bootstrap : <li class="dropdown"> <a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-file-excel-o"></i></a> <ul cl
微风-- 轻许--
2022/04/13
9090
POI 方式-excle 表格导出实现-java-poi
用SpringMvc实现Excel导出功能
以前只知道用poi导出Excel,最近用了SpringMvc的Excel导出功能,结合jxl和poi实现,的确比只用Poi好,两种实现方式如下:
JQ实验室
2022/02/09
1.9K0
基于jdk1.7实现的excel导出工具类
本文通过介绍一种通用的Excel导出工具类,用于实现Excel表格导出功能,支持多种格式的导出,同时支持自定义导出数据以及自定义样式等功能。该工具类具有灵活配置的特点,可以自定义输出Excel的格式、大小、颜色、字体、表格等样式,支持多线程导出和单线程导出,并且支持分页导出和压缩导出。同时,该工具类还提供了一些常用的工具方法,用于快速构造Excel表格,简化代码,提高开发效率。
杉枫
2017/12/26
8530
Apache POI使用详解[通俗易懂]
开发中经常会设计到excel的处理,如导出Excel,导入Excel到数据库中,操作Excel目前有两个框架,一个是apache 的poi, 另一个是 Java Excel
全栈程序员站长
2022/09/14
5K0
Apache POI使用详解[通俗易懂]
Springboot+Poi实现Excel的导入导出
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
默存
2022/06/17
3.3K0
Springboot+Poi实现Excel的导入导出
相关推荐
java的poi技术读取和导入Excel
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验