一、准备工作

  参考:https://www.cnblogs.com/doudouyoutang/p/10220599.html

  搭建本地rtmp服务:

  https://www.cnblogs.com/doudouyoutang/p/6602430.html

  获取使用到的库,openssl 和 librtmp

  参考:

  https://www.jianshu.com/p/b38656443e71
  https://github.com/x2on/OpenSSL-for-iPhone

  也可以从我的工程中直接拿 https://github.com/liqiushui/RtmpDumpAsAAC

二、关键解释:

  RTMP的Message音频和视频分开发送的,音频和视频的发送类似,第一次会收到一个AAC Sequence Header,这里面包含音频格式的描述信息

  Message 判断为音频之后,通过判断前两个字节可以得到后面是 AAC Sequence Header 还是 AAC裸数据

 if(packet.m_packetType == RTMP_PACKET_TYPE_AUDIO)
{
//Audio Packet
//FLV Audio Tag 原始数据,包含Tag Header, 音频Tag Header一般由一个字节定义(AAC用两个字节)
//第一个字节的定义如下:音频格式 4bits | 采样率 2bits | 采样精度 1bits | 声道数 1bits|
/*
看第2个字节,如果音频格式AAC(0x0A),AudioTagHeader中会多出1个字节的数据AACPacketType,这个字段来表示AACAUDIODATA的类型:
0x00 = AAC sequence header,类似h.264的sps,pps,在FLV的文件头部出现一次。
0x01 = AAC raw,AAC数据
*/ //FLV Audio Tag, 完整格式,结构为:【0x08, 3字节包长度,4字节时间戳,00 00 00】,AF 01 N字节AAC数据 | 前包长度
//其中编码后AAC纯数据长度为N,3字节包长度 = N + 2
//前包长度 = 11 + 3字节包长度 = 11 + N + 2 = 13 + N。
//如果要保存AAC为流数据,需要 【ADTS头 + AACRaw数据】【ADTS头 + AACRaw数据】【ADTS头 + AACRaw数据】 写入文件 if(packet.m_nBodySize >= 2 && packet.m_body[1] == 0x00)
{
//AAC sequence header
this->p = new FLVAudioTagHeader((const unsigned char *)(packet.m_body));
this->p->parse();
this->p->dumpHeaderInfo();
//FFMpeg 解析参考
//https://github.com/herocodemaster/rtmp-cpp/blob/3ec35590675560ac4fa9557ca7a5917c617d9999/RTMP/projects/ffmpeg/src_completo/libavcodec/mpeg4audio.c
//用bit操作类https://blog.csdn.net/qll125596718/article/details/6901935
this->p->parseAudioConfig((const char *)(packet.m_body + 2), packet.m_nBodySize-2);
} if(packet.m_nBodySize >= 2 && packet.m_body[1] == 0x01)
{
//AAC Raw Data
unsigned char adts[7] = {0};
this->p->aac_set_adts_head(adts, packet.m_nBodySize - 2);
this->dumpBytesToFlv(adts, 7);
this->dumpBytesToFlv((const unsigned char *)(packet.m_body+2), packet.m_nBodySize-2);
} RTMPPacket_Free(&packet);
}

  RTMP的AAC Payload是 2个字节的头 + 【音频裸数据 | 或者 AAC Sequence Header】,

  关于AAC Sequence Header的解析,可以参考FFMPEG

  如果不解析AAC Sequence Header也是可以的,因为后面每段音频的前两个字节的头,也包含音频格式、采样率、帧率的信息

  得到音频的裸数据后,如果需要播放,需要在每段数据前面加上ADTS头

  感谢: https://blog.csdn.net/lichen18848950451/article/details/78266054

    int aac_set_adts_head(unsigned char *buf, int size)
{
ADTSContext *acfg = &this->ctx;
unsigned char byte;
if (size < ADTS_HEADER_SIZE)
{
return -1;
}
buf[0] = 0xff;
buf[1] = 0xf1;
byte = 0;
byte |= (acfg->objecttype & 0x03) << 6;
byte |= (acfg->sample_rate_index & 0x0f) << 2;
byte |= (acfg->channel_conf & 0x07) >> 2;
buf[2] = byte;
byte = 0;
byte |= (acfg->channel_conf & 0x07) << 6;
byte |= (ADTS_HEADER_SIZE + size) >> 11;
buf[3] = byte;
byte = 0;
byte |= (ADTS_HEADER_SIZE + size) >> 3;
buf[4] = byte;
byte = 0;
byte |= ((ADTS_HEADER_SIZE + size) & 0x7) << 5;
byte |= (0x7ff >> 6) & 0x1f;
buf[5] = byte;
byte = 0;
byte |= (0x7ff & 0x3f) << 2;
buf[6] = byte; return 0; }

  在追加了ADTS头,aac流就可以导入播放器进行播放了

  

Dump Rtmp Audio Stream To AAC Formate File (从Rtmp流提取并保存AAC音频文件)的更多相关文章

  1. aac adts & LATM封装码流分析

    本文继续上一篇文章的内容,介绍一个音频码流处理程序.音频码流在视频播放器中的位置如下所示. 本文中的程序是一个AAC码流解析程序.该程序可以从AAC码流中分析得到它的基本单元ADTS frame,并且 ...

  2. ffmpeg 合并aac格式音频文件

    1:连接到一起 'ffmpeg - i "concat:D:\learn\audio\1.aac|D:\learn\audio\2.aac" - acodec copy D:\le ...

  3. The jQuery HTML5 Audio / Video Library (jQuery jPlayer插件给你的站点增加视频和音频功能)

    http://jplayer.org/ The jQuery HTML5 Audio / Video Library jPlayer is the completely free and open s ...

  4. [C/C++] zltabout(带缩进的格式化输出)v1.0。能以相同的代码绑定到 C FILE 或 C++流

    作者:zyl910 一.缘由 在写一些生成文本的程序时,经常需要使用带缩进的格式化输出的功能.以前为此写过不少类似的函数,可惜它们的可重用性很差. 这是因为——1) C语言的FILE*不支持重定向到自 ...

  5. IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE

    本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于 ...

  6. java File (文档流)

    一.   数据流的基本概念 1.数据流 在Java中把不同的数据源与程序之间的数据传输都抽象表述为“流”(stream),以实现相对统一和简单的输入/输出操作方式.传输中的数据就像流水一样,也称为数据 ...

  7. h5 audio播放音频文件

    h5 audio播放音频文件 注:下面html中样式及不相关的内容去掉了 第一个例子 播放没有防盗链的外网音频文件是可以的 <!doctype html> <html> < ...

  8. 使用audio标签播放音频文件

    HTML5定义了一个新的元素用来指定标准的方式来插入音频文件到web页面中:<audio>标签.使用audio标签可以控制音频的播放与停止,循环播放与播放次数设置,以及播放位置等等. 例如 ...

  9. H5页面实现一个Audio标签加载多个音频文件,并进行播放和展示音频长度

    最近微信项目中有需求,要将微信端发送过来的amr格式的语音文件,在项目中的页面上进行展示和播放,实现方式如下: 1.首先java后台收到微信端的消息推送的时候,使用 ffmpeg将amr格式的音频文件 ...

  10. CEF3 HTML5 audio标签为什么不能播放mp3格式的音频文件

    CEF3 HTML5 audio标签 为什么不能播放mp3格式的音频文件   原因略.   解决方法: 找一个最新版的chrome ,我用的是24版本.路径 C:\Documents and Sett ...

随机推荐

  1. 推荐几款Vue后台管理系统的框架,以便备用

    推荐几款Vue后台管理系统的框架,以便备用 Vue.js 是一个目前比较流行的前端框架,在业界也算很有名气,今天这里为大家罗列一下基于Vue的后端管理的框架. 使用这些框架你会发现它包括了我们常用的路 ...

  2. 重学c#系列——缓存[盛派源码分析cache](九)

    前言 以前整理过缓存的东西在: https://www.cnblogs.com/aoximin/p/12727659.html 只是粗略的例子,因为真的要去介绍缓存这个东西,要从内存开始,是一个有时间 ...

  3. 将项目封装进docker进行迁移和使用

    首先要理解docker的基本使用,本文不做过多阐述,博主也对docker没有了解透彻. 这里列一下docker的基本命令: docker info # 查看docker信息 docker -v # 查 ...

  4. 嘉楠k210 多线程 点亮流水灯

    from Maix import GPIO from fpioa_manager import fm import _thread import time fm.register(24, fm.fpi ...

  5. 力扣1346(java&python)-检查整数及其两倍数是否存在(简单)

    题目: 给你一个整数数组 arr,请你检查是否存在两个整数 N 和 M,满足 N 是 M 的两倍(即,N = 2 * M). 更正式地,检查是否存在两个下标 i 和 j 满足: i != j 0 &l ...

  6. Flink Sort-Shuffle 实现简介

    简介:Sort-Shuffle 使 Flink 在应对大规模批数据处理任务时更加游刃有余 本文介绍 Sort-Shuffle 如何帮助 Flink 在应对大规模批数据处理任务时更加游刃有余.主要内容包 ...

  7. 日志审计携手DDoS防护助力云上安全

    ​简介: 本文主要介绍日志审计结合DDoS防护保障云上业务安全的新实践. 日志审计携手DDoS防护助力云上安全 1 背景介绍 设想一下,此时你正在高速公路上开车去上班,路上还有其他汽车,总体而言,大家 ...

  8. [FAQ] 没有docker用户组,怎么让普通用户有权限操作docker

      如果没有docker用户组,可以通过以下步骤让普通用户有权限操作docker: 创建一个名为docker的用户组: sudo groupadd docker 将当前用户添加到docker用户组中: ...

  9. 🎊这个 OpenTiny 开源项目的 CLI 可太牛了,两行命令创建一个美观大气的 Vue Admin 后台管理系统,有手就会,连我的设计师朋友都学会啦啦

    大家好,我是 Kagol,OpenTiny 开源社区运营,TinyVue 跨端.跨框架组件库核心贡献者,专注于前端组件库建设和开源社区运营. 近期尝试了下 OpenTiny 的 CLI 工具,不得不说 ...

  10. dotnet 调试应用启动闪退的方法

    应用程序如果启动即闪退,那大部分时候日志模块还没初始化完成,很难通过应用自身的启动流程了解到应用启动失败的原因.本文来告诉几个不同的方法用来调查应用启动失败的原因 应用启动失败的原因可能有很多,例如系 ...