FFmpeg开发实战(四):FFmpeg 抽取音视频的音频数据
如何使用FFmpeg抽取音视频的音频数据,代码如下:
- void adts_header(char *szAdtsHeader, int dataLen);
- // 使用FFmpeg从视频中抽取音频
- void extractAudio() {
- // 设置日志输出等级
- av_log_set_level(AV_LOG_INFO);
- AVFormatContext *fmt_ctx = NULL;
- AVPacket pkt;
- av_register_all();
- int ret;
- int len;
- int audio_index = -;
- // 打开输入文件
- ret = avformat_open_input(&fmt_ctx, "111.mp4", NULL, NULL);
- // 检查打开输入文件是否成功
- if (ret < ) {
- printf("cant open file,error message = %s", av_err2str(ret));
- return;
- }
- // 打开输入文件成功,打印一下Meta信息
- // av_dump_format(fmt_ctx, 0, "111.flv", 0);
- // 打开输出文件
- FILE* dst_fd = fopen("111.aac", "wb"); // w 写入 b 二进制文件
- // 检查输出文件打开是否成功,如果失败,就输出日志,并关闭输出文件的引用
- if (!dst_fd) {
- av_log(NULL, AV_LOG_ERROR, "Can't Open Out File!\n");
- avformat_close_input(&fmt_ctx);
- }
- // 获取到音频流(使用av_find_best_stream:多媒体文件中拿到想使用的最好的一路流)
- av_init_packet(&pkt);
- pkt.data = NULL;
- pkt.size = ;
- ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -, -, NULL, );
- for (int i = ; i < fmt_ctx->nb_streams; i++) {
- if (fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- audio_index = i;
- break;
- }
- }
- printf("Audio Stream Index = %d", audio_index);
- // 检查发现音频流的结果
- if (audio_index < ) {
- av_log(NULL, AV_LOG_ERROR, "Can't find Best Audio Stream!\n");
- //printf("Reason = %s", av_err2str(ret));
- // 关闭输出文件和输出文件的引用
- avformat_close_input(&fmt_ctx);
- fclose(dst_fd);
- return;
- }
- while (av_read_frame(fmt_ctx, &pkt) >= ) {
- if (pkt.stream_index == audio_index) {
- printf("Has Read An Audio Packet\n");
- char adts_header_buf[];
- adts_header(adts_header_buf, pkt.size);
- fwrite(adts_header_buf, , , dst_fd);
- len = fwrite(pkt.data, , pkt.size, dst_fd);
- if (len != pkt.size) {
- av_log(NULL, AV_LOG_WARNING, "Waring! Length of data not equal size of pkt!\n");
- }
- }
- // 将引用基数减一
- av_packet_unref(&pkt);
- //av_free_packet(&pkt);
- }
- // 关闭文件(输入/输出)
- avformat_close_input(&fmt_ctx);
- if (dst_fd) {
- fclose(dst_fd);
- }
- }
- 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 高8bits
szAdtsHeader[1] = 0xf0; //syncword:0xfff 低4bits
szAdtsHeader[1] |= (0 << 3); //MPEG Version:0 for MPEG-4,1 for MPEG-2 1bit
szAdtsHeader[1] |= (0 << 1); //Layer:0 2bits
szAdtsHeader[1] |= 1; //protection absent:1 1bit- szAdtsHeader[2] = (audio_object_type - 1) << 6; //profile:audio_object_type - 1 2bits
szAdtsHeader[2] |= (sampling_frequency_index & 0x0f) << 2; //sampling frequency index:sampling_frequency_index 4bits
szAdtsHeader[2] |= (0 << 1); //private bit:0 1bit
szAdtsHeader[2] |= (channel_config & 0x04) >> 2; //channel configuration:channel_config 高1bit- szAdtsHeader[3] = (channel_config & 0x03) << 6; //channel configuration:channel_config 低2bits
szAdtsHeader[3] |= (0 << 5); //original:0 1bit
szAdtsHeader[3] |= (0 << 4); //home:0 1bit
szAdtsHeader[3] |= (0 << 3); //copyright id bit:0 1bit
szAdtsHeader[3] |= (0 << 2); //copyright id start:0 1bit
szAdtsHeader[3] |= ((adtsLen & 0x1800) >> 11); //frame length:value 高2bits- szAdtsHeader[4] = (uint8_t)((adtsLen & 0x7f8) >> 3); //frame length:value 中间8bits
szAdtsHeader[5] = (uint8_t)((adtsLen & 0x7) << 5); //frame length:value 低3bits
szAdtsHeader[5] |= 0x1f; //buffer fullness:0x7ff 高5bits
szAdtsHeader[6] = 0xfc;
}
(目前AAC格式不是很明确,代码运行存在问题,待学习AAC完成后,再完善)
FFmpeg开发实战(四):FFmpeg 抽取音视频的音频数据的更多相关文章
- FFmpeg开发实战(五):FFmpeg 抽取音视频的视频数据
如何使用FFmpeg抽取音视频的视频数据,代码如下: // FFmpegTest.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include ...
- FFmpeg简易播放器的实现-音视频同步
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- 获取音视频文件AVMetadata数据
获取音视频文件AVMetadata数据 问题来源: http://stackoverflow.com/questions/16318821/extracting-mp3-album-artwork-i ...
- libavcodec是一款LGPL自由软件编解码库,用于视频和音频数据的编解码工作
http://zh.wikipedia.org/zh-cn/Libavcodec http://baike.baidu.com/view/856526.htm libavcodec是一款LGPL自由软 ...
- FFmpeg开发实战(三):FFmpeg 打印音视频Meta信息
在之前使用FFmpeg命令行的时候,我们经常看到FFmpeg命令行在输出音视频文件的会打印一下文件的Meta信息,类似如图: 那么我们如何通过代码的方式输出这些Meta信息呢? FFmpeg提供了一个 ...
- FFmpeg开发实战(六):使用 FFmpeg 将YUV数据编码为视频文件
本文中实现的一个小功能是把一个YUV原始视频数据(时间序列图像)经过h264编码为视频码流,然后在使用mp4封装格式封装. 编码&封装的流程图如下: 使用ffmpeg编码流程: 1.首先使用a ...
- FFmpeg开发实战(一):FFmpeg 打印日志
在Visual Studio 开发(二):VS 2017配置FFmpeg开发环境一文中,我们配置好了FFmpeg的开发环境,下面我们开始边实战,边学习FFmpeg. 首先,我们要学习的就是FFmpeg ...
- ffmpeg 2.3版本号, 关于ffplay音视频同步的分析
近期学习播放器的一些东西.所以接触了ffmpeg,看源代码的过程中.就想了解一下ffplay是怎么处理音视频同步的,之前仅仅大概知道通过pts来进行同步,但对于怎样实现却不甚了解,所以想借助这个机会, ...
- Android IOS WebRTC 音视频开发总结(五五)-- 音视频通讯中的抗丢包与带宽自适应原理
本文主要分析webrtc中的抗丢包与带宽自适应原理,文章来自博客园RTC.Blacker,欢迎关注微信公众号blacker,更多详见www.rtc.help 文章内容主要来自中国电信北京研究院丁博士在 ...
随机推荐
- 初探storm
Storm入门之Storm示例及UI参数讲解 Storm UI REST API Storm 1.1.0 中文文档 Apache Storm 1.1.0 中文文档 | ApacheCN Storm U ...
- QMainWindow
QMainWindow继承自QWidget,是一个顶层窗口,它可以包含其他的界面元素:菜单栏.工具栏.状态栏.子窗口等. QMainWindow不能设置布局(setLayout()方法),因为它有自己 ...
- RabbitMQ教程
1.引言 RabbitMQ——Rabbit Message Queue的简写,但不能仅仅理解其为消息队列,消息代理更合适.RabbitMQ 是一个由 Erlang 语言开发的AMQP(高级消息队列协议 ...
- UOJ#375. 【ZJOI2018】迷宫
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ375.html 题解 首先,我们可以建出一个 k 个点的自动机,第 i 个点表示当前数对 k 取模为 i- ...
- Centos将yum源设置为阿里云的镜像源
第一步:备份原有镜像源 mv /etc/yum.repo.d/Centos-Base.repo /etc/yum.repo.d/Centos-Base.repo.bak 第二步:下载阿里云的镜像源 w ...
- 当使用xmapp时session序列化生成的文件的路径
由于没有安装tomcat而是安的xmapp所以序列化和反序列化时并没有在tomcat的里边生成session文件而是在java的工作路径下生成在以下路径下 D:\pro\java\workspace\ ...
- python copy模块
python copy模块 copy模块用于对象的拷贝操作 该模块只提供了两个主要的方法: copy.copy:浅复制 copy.deepcopy:深复制 直接赋值,深拷贝和浅拷贝的区别 直接赋值:简 ...
- ELK logstash geoip值为空故障排查
首先我们用的是elasticsearch+kibana+logstash+filebeat 客户端filebeat收集日志后经过服务端logstash规则处理后储存到elasticsearch中,在k ...
- JAVA递归生成树形菜单
递归生成一个如图的菜单,编写两个类数据模型Menu.和创建树形的MenuTree.通过以下过程实现: 1.首先从菜单数据中获取所有根节点. 2.为根节点建立次级子树并拼接上. 3.递归为子节点建立次级 ...
- Date动态获取时间
·getDate | 根据本地时间获取当前日期(本月的几号) ·getDay | 根据本地时间获取今天是星期几(0-Sunday,1-Monday.. ...