使用FFmpeg实现抽取多媒体文件的音频并按照AAC格式进行保存--附源码
抽取音频文件
注册log
与编解码器
av_log_set_level(AV_LOG_INFO);
av_register_all();
打开多媒体文件
打开多媒体文件,并读取头部信息
/*** Open an input stream and read the header. The codecs are not opened.* The stream must be closed with avformat_close_input().** @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).* May be a pointer to NULL, in which case an AVFormatContext is allocated by this* function and written into ps.* Note that a user-supplied AVFormatContext will be freed on failure.* @param url URL of the stream to open.* @param fmt If non-NULL, this parameter forces a specific input format.* Otherwise the format is autodetected.* @param options A dictionary filled with AVFormatContext and demuxer-private options.* On return this parameter will be destroyed and replaced with a dict containing* options that were not found. May be NULL.** @return 0 on success, a negative AVERROR on failure.** @note If you want to use custom IO, preallocate the format context and set its pb field.*/
int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options);
/*Open an input stream and read the header*/
int ret = avformat_open_input(&fmt_ctx, "/work/test/test.mp4", NULL, NULL);
if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "can't open file.\n");return -1;
}
打开一个文件用于写入音频文件
char *pDst = NULL;
pDst = "test.aac";
// write audio data to AAC file
FILE *dst_fd = fopen(pDst, "wb");
if (dst_fd == NULL) {av_log(NULL, AV_LOG_ERROR, "open dst_fd failed.\n");avformat_close_input(&fmt_ctx);return -1;
}
输出多媒体信息
输出多媒体信息就是讲多媒体的信息以及metadata
信息打印出来
/** Print detailed information about the input or output format**/
av_dump_format(fmt_ctx, 0, "/work/test/test.mp4", 0);
确保输入的多媒体文件中有帧信息
// 2. get stream
/*Read packets of a media file to get stream information.*/
ret = avformat_find_stream_info(fmt_ctx, NULL);
if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "failed to find stream information.");avformat_close_input(&fmt_ctx);fclose(dst_fd);return -1;
}
提取音频信息
提取音频信息,并按照AAC格式将音频信息写入文件
AVPacket pkt;
/*Initialize optional fields of a packet with default values.*/
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
// 循环将音频信息写入AAC文件
int len = -1;
/*保存原始数据,播放时需要添加AAC的音频格式说明的头*/
while (av_read_frame(fmt_ctx, &pkt) >= 0) {if (pkt.stream_index == audio_index) {/*每帧开头都要写*/char adts_header_buf[7];// 为每帧音频添加AAC头部信息adts_header(adts_header_buf, pkt.size);fwrite(adts_header_buf, 1, 7, dst_fd);len = fwrite(pkt.data, 1, pkt.size, dst_fd);cout << pkt.size << endl;if (len != pkt.size) {av_log(NULL, AV_LOG_ERROR, "waning, length is not equl size of pkt.\n");return -1;}}/*Wipe the packet.*/av_packet_unref(&pkt);
}
// 添加ADTS头部信息
void adts_header(char *szAdtsHeader, int dataLen) {int audio_object_type = 2;int sampling_frequency_index = 7;int channel_config = 2;int adtsLen = dataLen + 7;szAdtsHeader[0] = 0xff; //syncword:0xfff 高8bitsszAdtsHeader[1] = 0xf0; //syncword:0xfff 低4bitsszAdtsHeader[1] |= (0 << 3); //MPEG Version:0 for MPEG-4,1 for MPEG-2 1bitszAdtsHeader[1] |= (0 << 1); //Layer:0 2bitsszAdtsHeader[1] |= 1; //protection absent:1 1bitszAdtsHeader[2] =(audio_object_type - 1) << 6; //profile:audio_object_type - 1 2bitsszAdtsHeader[2] |=(sampling_frequency_index & 0x0f) << 2; //sampling frequency index:sampling_frequency_index 4bitsszAdtsHeader[2] |= (0 << 1); //private bit:0 1bitszAdtsHeader[2] |=(channel_config & 0x04) >> 2; //channel configuration:channel_config 高1bitszAdtsHeader[3] = (channel_config & 0x03) << 6; //channel configuration:channel_config 低2bitsszAdtsHeader[3] |= (0 << 5); //original:0 1bitszAdtsHeader[3] |= (0 << 4); //home:0 1bitszAdtsHeader[3] |= (0 << 3); //copyright id bit:0 1bitszAdtsHeader[3] |= (0 << 2); //copyright id start:0 1bitszAdtsHeader[3] |= ((adtsLen & 0x1800) >> 11); //frame length:value 高2bitsszAdtsHeader[4] = (uint8_t) ((adtsLen & 0x7f8) >> 3); //frame length:value 中间8bitsszAdtsHeader[5] = (uint8_t) ((adtsLen & 0x7) << 5); //frame length:value 低3bitsszAdtsHeader[5] |= 0x1f; //buffer fullness:0x7ff 高5bitsszAdtsHeader[6] = 0xfc;
}
AAC结构说明参考
[AAC说明可以参考]: https://blog.csdn.net/leixiaohua1020/article/details/50535042
结束释放资源
音频写好之后,释放掉申请的资源
/*Close an opened input AVFormatContext*/
avformat_close_input(&fmt_ctx);
if (dst_fd != NULL)fclose(dst_fd);
完整代码
//
// Created by andrew on 2020/11/1.
//
#include <iostream>
using namespace std;
extern "C" {#include <libavutil/log.h>
#include <libavformat/avformat.h>
}void adts_header(char *szAdtsHeader, int dataLen) {int audio_object_type = 2;int sampling_frequency_index = 7;int channel_config = 2;int adtsLen = dataLen + 7;szAdtsHeader[0] = 0xff; //syncword:0xfff 高8bitsszAdtsHeader[1] = 0xf0; //syncword:0xfff 低4bitsszAdtsHeader[1] |= (0 << 3); //MPEG Version:0 for MPEG-4,1 for MPEG-2 1bitszAdtsHeader[1] |= (0 << 1); //Layer:0 2bitsszAdtsHeader[1] |= 1; //protection absent:1 1bitszAdtsHeader[2] =(audio_object_type - 1) << 6; //profile:audio_object_type - 1 2bitsszAdtsHeader[2] |=(sampling_frequency_index & 0x0f) << 2; //sampling frequency index:sampling_frequency_index 4bitsszAdtsHeader[2] |= (0 << 1); //private bit:0 1bitszAdtsHeader[2] |=(channel_config & 0x04) >> 2; //channel configuration:channel_config 高1bitszAdtsHeader[3] = (channel_config & 0x03) << 6; //channel configuration:channel_config 低2bitsszAdtsHeader[3] |= (0 << 5); //original:0 1bitszAdtsHeader[3] |= (0 << 4); //home:0 1bitszAdtsHeader[3] |= (0 << 3); //copyright id bit:0 1bitszAdtsHeader[3] |= (0 << 2); //copyright id start:0 1bitszAdtsHeader[3] |= ((adtsLen & 0x1800) >> 11); //frame length:value 高2bitsszAdtsHeader[4] = (uint8_t) ((adtsLen & 0x7f8) >> 3); //frame length:value 中间8bitsszAdtsHeader[5] = (uint8_t) ((adtsLen & 0x7) << 5); //frame length:value 低3bitsszAdtsHeader[5] |= 0x1f; //buffer fullness:0x7ff 高5bitsszAdtsHeader[6] = 0xfc;
}/** 从多媒体文件中抽取媒体信息* */int main(int argc, char *argv[]) {AVFormatContext *fmt_ctx = NULL;av_log_set_level(AV_LOG_INFO);/*所有进行操作前,先执行以下,否则需要自己制定类型*/av_register_all();// 1. 读取多媒体文件char *pSrc = NULL;char *pDst = NULL;pSrc = (char *) "/work/test/test.mp4";pDst = "test.aac";/*Open an input stream and read the header*/int ret = avformat_open_input(&fmt_ctx, "/work/test/test.mp4", NULL, NULL);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "can't open file.\n");return -1;}// write audio data to AAC fileFILE *dst_fd = fopen(pDst, "wb");if (dst_fd == NULL) {av_log(NULL, AV_LOG_ERROR, "open dst_fd failed.\n");avformat_close_input(&fmt_ctx);return -1;}// 2. get stream/*Read packets of a media file to get stream information.*/ret = avformat_find_stream_info(fmt_ctx, NULL);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "failed to find stream information.");avformat_close_input(&fmt_ctx);fclose(dst_fd);return -1;}/** Print detailed information about the input or output format* */av_dump_format(fmt_ctx, 0, "/work/test/test.mp4", 0);int audio_index = -1;audio_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);if (audio_index < 0) {av_log(NULL, AV_LOG_ERROR, "ret = %d\n", ret);avformat_close_input(&fmt_ctx);fclose(dst_fd);return -1;}AVPacket pkt;/*Initialize optional fields of a packet with default values.*/av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;int len = -1;/*保存原始数据,播放时需要添加AAC的音频格式说明的头*/while (av_read_frame(fmt_ctx, &pkt) >= 0) {if (pkt.stream_index == audio_index) {/*每帧开头都要写*/char adts_header_buf[7];adts_header(adts_header_buf, pkt.size);fwrite(adts_header_buf, 1, 7, dst_fd);len = fwrite(pkt.data, 1, pkt.size, dst_fd);cout << pkt.size << endl;if (len != pkt.size) {av_log(NULL, AV_LOG_ERROR, "waning, length is not equl size of pkt.\n");return -1;}}/*Wipe the packet.*/av_packet_unref(&pkt);}/*Close an opened input AVFormatContext*/avformat_close_input(&fmt_ctx);if (dst_fd != NULL)fclose(dst_fd);return 0;
}
使用FFmpeg实现抽取多媒体文件的音频并按照AAC格式进行保存--附源码相关推荐
- FFmpeg —— 裁剪视频(含音视频),不需编解码(附源码)
说明 附上指令方式:ffmpeg -i in.mp4 -ss 00:00:10 -to 00:00:39 out.mp4 完整源码 #include <iostream>
- 20220517 Python 制作一个儿童学习软件 (附源码和软件下载) 包含语音合成 视频播放 pyqt pptsx3 Qmovie request pygame 音频播放
20220517 Python 制作一个儿童学习软件 (附源码和软件下载) 包含语音合成 视频播放 pyqt pptsx3 Qmovie request pygame 音频播放 文章目录 202205 ...
- macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码)
实战需求 macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 支持剪切音频 支持复制音频 支持删除音频 支持un ...
- android flv 编码器,Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载)...
Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载) 项目地址 https://github.com/979451341/RtmpSave 这个项目主要代码 ...
- RTSP协议视频监控智能分析平台EasyNVR如何将音频转化为aac格式并上传?
在之前的博文中,我们和大家分享了使用EasyNVR视频监控直播平台时,如何实现自定义直播背景音乐,在该文中我们知道可以通过拉流库融合的方式推送. 但是在实际的应用过程中,我们发现上传的不同格式的音频的 ...
- 人肉解析系列(一)————FLV-java你所关心的,我这里都有。附源码。非FFmpeg相关,纯java人肉解析。手写FLV。H264 AAC转FLV
第一次写博客,不知道有没有什么潜规则.总之呢,是好是坏都已经在落笔的那一刻开始了. 说起直播,各位都不陌生,毕竟国内这几年直播,短视频等视频行业大火,让所有程序员对直播都能如数家珍,随口便能讲出几种协 ...
- Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.使用录音机录制音频 手机有自带的系统相机,也有自带的系统录音机,只要在调用startActivityForResult之前指定该动作,就会自动 ...
- Python图像识别实战(一):实现按数量随机抽取图像复制到另一文件夹(附源码和实现效果)
前面我介绍了可视化的一些方法以及机器学习在预测方面的应用,分为分类问题(预测值是离散型)和回归问题(预测值是连续型)(具体见之前的文章). 从本期开始,我将做一个关于图像识别的系列文章,让读者慢慢理解 ...
- 20行Python代码爬取2W多条音频文件素材【内附源码+详细解析】新媒体创作必备
大家好,我是辣条. 今天的内容稍显简单,不过对于新媒体创作的朋友们还是很有帮助的,你能用上的话记得给辣条三连! 爬取目标 网站:站长素材 工具使用 开发工具:pycharm 开发环境:python3. ...
最新文章
- yolov5论文叫什么_论文格式与论文查重到底是什么鬼?教你半小时搞定的独门技巧...
- 超实用!K8s 开发者必须知道的 6 个开源工具
- boost::multiprecision模块debug_adaptor相关的测试程序
- 【转】visual studio 2019 (vs) 显示右侧缩略图_缩略图_滚动条
- kafka tool 查看指定group下topic的堆积数量_ELK架构下利用Kafka Group实现Logstash的高可用...
- 用机器指令和汇编指令编程(修改版)
- 2021了,不会还有测试人员认为Jmeter就等于性能测试吧!
- matlab 文件列表,如何從Matlab寫入多個列表到同一個excel文件?
- 舰船目标检测的学习笔记(legacy)
- SSD Network Architecture--keras version
- react 实战案例(webpack构建)
- 百度地图 地图级别 是什么意思
- taobao.itemprops.get( 获取标准商品类目属性 )
- [附源码]Java计算机毕业设计SSM歌唱比赛积分管理系统
- 一看就会,12种不同场景的拍摄模式!
- FPGA烧写SPI FLASH
- prof8000安装
- 单位四元数多姿态插值(squad)
- 爱了、阿里巴巴 JAVA 岗发布,最新内部面试题(含 P5-P7)
- Unity3D 大型游戏 最后一站 源码 部分重点NetworkManager(二)(8)