如何使用FFmpeg抽取音视频的音频数据,代码如下:

  1. void adts_header(char *szAdtsHeader, int dataLen);
  2.  
  3. // 使用FFmpeg从视频中抽取音频
  4. void extractAudio() {
  5.  
  6. // 设置日志输出等级
  7. av_log_set_level(AV_LOG_INFO);
  8.  
  9. AVFormatContext *fmt_ctx = NULL;
  10. AVPacket pkt;
  11.  
  12. av_register_all();
  13.  
  14. int ret;
  15. int len;
  16. int audio_index = -;
  17.  
  18. // 打开输入文件
  19. ret = avformat_open_input(&fmt_ctx, "111.mp4", NULL, NULL);
  20.  
  21. // 检查打开输入文件是否成功
  22. if (ret < ) {
  23. printf("cant open file,error message = %s", av_err2str(ret));
  24. return;
  25. }
  26.  
  27. // 打开输入文件成功,打印一下Meta信息
  28. // av_dump_format(fmt_ctx, 0, "111.flv", 0);
  29.  
  30. // 打开输出文件
  31. FILE* dst_fd = fopen("111.aac", "wb"); // w 写入 b 二进制文件
  32.  
  33. // 检查输出文件打开是否成功,如果失败,就输出日志,并关闭输出文件的引用
  34. if (!dst_fd) {
  35. av_log(NULL, AV_LOG_ERROR, "Can't Open Out File!\n");
  36. avformat_close_input(&fmt_ctx);
  37. }
  38.  
  39. // 获取到音频流(使用av_find_best_stream:多媒体文件中拿到想使用的最好的一路流)
  40.  
  41. av_init_packet(&pkt);
  42. pkt.data = NULL;
  43. pkt.size = ;
  44.  
  45. ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -, -, NULL, );
  46. for (int i = ; i < fmt_ctx->nb_streams; i++) {
  47. if (fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
  48. audio_index = i;
  49. break;
  50. }
  51. }
  52.  
  53. printf("Audio Stream Index = %d", audio_index);
  54.  
  55. // 检查发现音频流的结果
  56. if (audio_index < ) {
  57. av_log(NULL, AV_LOG_ERROR, "Can't find Best Audio Stream!\n");
  58. //printf("Reason = %s", av_err2str(ret));
  59. // 关闭输出文件和输出文件的引用
  60. avformat_close_input(&fmt_ctx);
  61. fclose(dst_fd);
  62. return;
  63. }
  64.  
  65. while (av_read_frame(fmt_ctx, &pkt) >= ) {
  66. if (pkt.stream_index == audio_index) {
  67. printf("Has Read An Audio Packet\n");
  68. char adts_header_buf[];
  69. adts_header(adts_header_buf, pkt.size);
  70. fwrite(adts_header_buf, , , dst_fd);
  71. len = fwrite(pkt.data, , pkt.size, dst_fd);
  72. if (len != pkt.size) {
  73. av_log(NULL, AV_LOG_WARNING, "Waring! Length of data not equal size of pkt!\n");
  74. }
  75. }
  76. // 将引用基数减一
  77. av_packet_unref(&pkt);
  78. //av_free_packet(&pkt);
  79. }
  80.  
  81. // 关闭文件(输入/输出)
  82. avformat_close_input(&fmt_ctx);
  83. if (dst_fd) {
  84. fclose(dst_fd);
  85. }
  86. }
  87.  
  88. void adts_header(char *szAdtsHeader, int dataLen) {
  89.  
  90.     int audio_object_type = 2;
        int sampling_frequency_index = 7;
        int channel_config = 2;
  91.  
  92.     int adtsLen = dataLen + 7;
  93.  
  94.     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
  95.  
  96.     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
  97.  
  98.     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
  99.  
  100.     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 抽取音视频的音频数据的更多相关文章

  1. FFmpeg开发实战(五):FFmpeg 抽取音视频的视频数据

    如何使用FFmpeg抽取音视频的视频数据,代码如下: // FFmpegTest.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include ...

  2. FFmpeg简易播放器的实现-音视频同步

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  3. 获取音视频文件AVMetadata数据

    获取音视频文件AVMetadata数据 问题来源: http://stackoverflow.com/questions/16318821/extracting-mp3-album-artwork-i ...

  4. libavcodec是一款LGPL自由软件编解码库,用于视频和音频数据的编解码工作

    http://zh.wikipedia.org/zh-cn/Libavcodec http://baike.baidu.com/view/856526.htm libavcodec是一款LGPL自由软 ...

  5. FFmpeg开发实战(三):FFmpeg 打印音视频Meta信息

    在之前使用FFmpeg命令行的时候,我们经常看到FFmpeg命令行在输出音视频文件的会打印一下文件的Meta信息,类似如图: 那么我们如何通过代码的方式输出这些Meta信息呢? FFmpeg提供了一个 ...

  6. FFmpeg开发实战(六):使用 FFmpeg 将YUV数据编码为视频文件

    本文中实现的一个小功能是把一个YUV原始视频数据(时间序列图像)经过h264编码为视频码流,然后在使用mp4封装格式封装. 编码&封装的流程图如下: 使用ffmpeg编码流程: 1.首先使用a ...

  7. FFmpeg开发实战(一):FFmpeg 打印日志

    在Visual Studio 开发(二):VS 2017配置FFmpeg开发环境一文中,我们配置好了FFmpeg的开发环境,下面我们开始边实战,边学习FFmpeg. 首先,我们要学习的就是FFmpeg ...

  8. ffmpeg 2.3版本号, 关于ffplay音视频同步的分析

    近期学习播放器的一些东西.所以接触了ffmpeg,看源代码的过程中.就想了解一下ffplay是怎么处理音视频同步的,之前仅仅大概知道通过pts来进行同步,但对于怎样实现却不甚了解,所以想借助这个机会, ...

  9. Android IOS WebRTC 音视频开发总结(五五)-- 音视频通讯中的抗丢包与带宽自适应原理

    本文主要分析webrtc中的抗丢包与带宽自适应原理,文章来自博客园RTC.Blacker,欢迎关注微信公众号blacker,更多详见www.rtc.help 文章内容主要来自中国电信北京研究院丁博士在 ...

随机推荐

  1. 初探storm

    Storm入门之Storm示例及UI参数讲解 Storm UI REST API Storm 1.1.0 中文文档 Apache Storm 1.1.0 中文文档 | ApacheCN Storm U ...

  2. QMainWindow

    QMainWindow继承自QWidget,是一个顶层窗口,它可以包含其他的界面元素:菜单栏.工具栏.状态栏.子窗口等. QMainWindow不能设置布局(setLayout()方法),因为它有自己 ...

  3. RabbitMQ教程

    1.引言 RabbitMQ——Rabbit Message Queue的简写,但不能仅仅理解其为消息队列,消息代理更合适.RabbitMQ 是一个由 Erlang 语言开发的AMQP(高级消息队列协议 ...

  4. UOJ#375. 【ZJOI2018】迷宫

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ375.html 题解 首先,我们可以建出一个 k 个点的自动机,第 i 个点表示当前数对 k 取模为 i- ...

  5. Centos将yum源设置为阿里云的镜像源

    第一步:备份原有镜像源 mv /etc/yum.repo.d/Centos-Base.repo /etc/yum.repo.d/Centos-Base.repo.bak 第二步:下载阿里云的镜像源 w ...

  6. 当使用xmapp时session序列化生成的文件的路径

    由于没有安装tomcat而是安的xmapp所以序列化和反序列化时并没有在tomcat的里边生成session文件而是在java的工作路径下生成在以下路径下 D:\pro\java\workspace\ ...

  7. python copy模块

    python copy模块 copy模块用于对象的拷贝操作 该模块只提供了两个主要的方法: copy.copy:浅复制 copy.deepcopy:深复制 直接赋值,深拷贝和浅拷贝的区别 直接赋值:简 ...

  8. ELK logstash geoip值为空故障排查

    首先我们用的是elasticsearch+kibana+logstash+filebeat 客户端filebeat收集日志后经过服务端logstash规则处理后储存到elasticsearch中,在k ...

  9. JAVA递归生成树形菜单

    递归生成一个如图的菜单,编写两个类数据模型Menu.和创建树形的MenuTree.通过以下过程实现: 1.首先从菜单数据中获取所有根节点. 2.为根节点建立次级子树并拼接上. 3.递归为子节点建立次级 ...

  10. Date动态获取时间

    ·getDate            |  根据本地时间获取当前日期(本月的几号) ·getDay             |  根据本地时间获取今天是星期几(0-Sunday,1-Monday.. ...