音视频解封装--解封装分离音频AAC文件
1:简介
如下图所示,解封装就是将Flv、MP4等文件解封装为视频H264或H265压缩数据,音频解封装为AAC压缩数据。
2:ADTS头结构
ADTS的全称是Audio Data Transport Stream,是AAC音频的传输流TS格式。ADTS可以再任意帧解码,每一帧都有头信息。
AAC音频文件的每一帧由ADTS Header和AAC Audio Data组成,ADTS头信息为7个字节或者9个字节(一般情况为7个字节,取决于是否包含CRC校验,也就是固定头中protection_absent的值),分为adts_fixed_header固定头,adts_variable_header可变头;固定头信息中的数据每一帧都相同,可变头信息在帧与帧之间可变。
3:流程分析
4:代码分析
这里代码逻辑不是很严谨,异常部分也未作处理,着力先提取出AAC数据。
#include <iostream>
#include <stdio.h>
extern "C"
{
#include <libavformat/avformat.h>
}
using namespace std;const int sampling_frequencies[] ={96000, // 0x088200, // 0x164000, // 0x248000, // 0x344100, // 0x432000, // 0x524000, // 0x622050, // 0x716000, // 0x812000, // 0x911025, // 0xa8000 // 0xb
};int adts_header(char * const p_adts_header, const int data_length,const int profile, const int samplerate,const int channels)
{int sampling_frequency_index = 3; // 默认48000hzint adtsLen = data_length + 7;//adts头为7个字节长度int frequencies_size = sizeof(sampling_frequencies)/sizeof(sampling_frequencies[0]);int i = 0;for(i = 0;i < frequencies_size;i++){if(sampling_frequencies[i] == samplerate){sampling_frequency_index = i;break;}}if (i >= frequencies_size){printf("unsupport samplerate:%d\n",samplerate);return -1;}p_adts_header[0] = 0xff;//syncwordp_adts_header[1] = 0xf0;//syncwordp_adts_header[1] |= 0;//ID:MPEG标识符,0标识MPEG-4,1标识MPEG-2p_adts_header[1] |= 0;p_adts_header[1] |= 1;p_adts_header[2] |= profile << 6;p_adts_header[2] |= (sampling_frequency_index & 0x0f) << 2;p_adts_header[2] |= 0 << 1;p_adts_header[2] |= (channels & 0x04)>>2;p_adts_header[3] = (channels & 0x03)<<6; //channel configuration:channels 低2bitsp_adts_header[3] = (channels & 0x03)<<6; //channel configuration:channels 低2bitsp_adts_header[3] |= (0 << 5); //original:0 1bitp_adts_header[3] |= (0 << 4); //home:0 1bitp_adts_header[3] |= (0 << 3); //copyright id bit:0 1bitp_adts_header[3] |= (0 << 2); //copyright id start:0 1bitp_adts_header[3] |= ((adtsLen & 0x1800) >> 11); //frame length:value 高2bitsp_adts_header[4] = (uint8_t)((adtsLen & 0x7f8) >> 3); //frame length:value 中间8bitsp_adts_header[5] = (uint8_t)((adtsLen & 0x7) << 5); //frame length:value 低3bitsp_adts_header[5] |= 0x1f; //buffer fullness:0x7ff 高5bitsp_adts_header[6] = 0xfc; //11111100 //buffer fullness:0x7ff 低6bits
}int main()
{const char *default_filename = "believe.mp4";FILE *aac_fd = NULL;aac_fd = fopen("mp4ToAac.aac", "wb");//1:解复用器上下文分配AVFormatContext *ctx = NULL;int audio_index = -1;//2:打根据url打开文件int ret = 0;char errors[1024];if((ret = avformat_open_input(&ctx, default_filename, NULL, NULL)) < 0){av_strerror(ret, errors, 1024);av_log(NULL, AV_LOG_DEBUG, "Could not open source file: %s, %d(%s)\n",default_filename,ret,errors);return -1;}//3:读取媒体数据包获取码流信息ret = avformat_find_stream_info(ctx,NULL);if(ret <0){if(ctx)avformat_free_context(ctx);getchar();return 0;}//av_dump_format(ctx,0,default_filename,0);//4:查找音频流audio_index = av_find_best_stream(ctx,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);if(audio_index < 0){printf("av_find_best_Stream failed");return 0;}AVPacket pkt;av_init_packet(&pkt);if(ctx->streams[audio_index]->codecpar->codec_id != AV_CODEC_ID_AAC){printf("the medio file not find aav stream");return 0;}printf("av_read_frame");//5:读一帧数据到pkt中while(av_read_frame(ctx,&pkt) >= 0){if (pkt.stream_index == audio_index){//6:添加adts头char adts_header_buf[7] = {0};adts_header(adts_header_buf,pkt.size,ctx->streams[audio_index]->codecpar->profile,ctx->streams[audio_index]->codecpar->sample_rate,ctx->streams[audio_index]->codecpar->channels);//7:aac文件输出fwrite(adts_header_buf,1,7,aac_fd);int len = fwrite(pkt.data,1,pkt.size,aac_fd);if(len != pkt.size){av_log(NULL, AV_LOG_DEBUG, "warning, length of writed data isn't equal pkt.size(%d, %d)\n",len,pkt.size);}}av_packet_unref(&pkt);}printf("succes");if(ctx){avformat_close_input(&ctx);}if(aac_fd){fclose(aac_fd);}return 0;
}
音视频解封装--解封装分离音频AAC文件相关推荐
- WebRTC音视频同步详解
WebRTC音视频同步详解 1 WebRTC版本 2 时间戳 2.1 视频时间戳 2.2 音频时间戳 2.3 NTP时间戳 2 延迟 3 同步 3.1 一张图看懂音视频同步 3.2 音视频相对延迟 3 ...
- 走进音视频的世界——Matroska封装格式的介绍(二)
Matroska封装格式非常灵活.兼容性好,既适用于本地文件存储又可以进行实时流传输.本篇文章主要探讨Matroska的编解码器映射,如何封装视频流.音频流.字幕流.如果要Matroska的介绍.功能 ...
- Android音视频开发,详说PCM音频重采样、PCM编码
直播伴音,两种数据能否合在一起?不能叠加在一起 会有噪音 合并以后 再去编码推流 直播的例子 客户端播放器,可以开启多个播放器 对于我们重采样 很多时候就是为了统一格式,就是为了要合并这个流,去推送, ...
- 音视频开发(四)——编码音频
基于QT+FFMPEG的音视频开发(四)--编码音频 一.编码一般步骤 二.编码 2.1 创建编码器(本文创建AAC) 2.2 核心编码 三.源码 我的大部分学习都来自雷神,没有基础去雷神博客转转,每 ...
- 从零开始学习音视频编程技术(二) 音频格式讲解
从零开始学习音视频编程技术(二) 音频格式讲解 原文地址:http://blog.yundiantech.com/?log=blog&id=5 1. 音频简介 前面我们说过视频有一个每秒钟采集 ...
- 音视频开发入门基础知识(音频入门篇)
RTSP实时音视频开发实战课程:<RTSP实时音视频开发实战> 音视频开发入门基础知识(音频入门篇) 目录 前言 音频的采集和播放 音频常见的格式 音频的编码 前言 在音视频开发入门基础知 ...
- (一) 音视频基础_Mpeg4封装格式音视频编码格式_解封装解码_像素格式_PCM音频-采样率-通道-planar_MP4标准和h264格式的NAL的GOP分析
封装:从文件中把音视频读出来 解码:将音视频解压出来 重采样:将音视频转换成声卡显卡支持的格式,视频需要做像素格式的转换MPEG(或叫MPEG-4)是一套用于音频﹑视频信息压缩的编码标准. MPEG- ...
- 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式 详解
http://blog.csdn.net/wishfly/article/details/50187417 编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运 ...
- 音视频处理之PS封装的介绍与使用
1.PS封装介绍 MPEG2-PS是一种多路复用数字音频,视频等的封装容器.PS是Program Stream(程序流或节目流)的简称.程序流 将一个或多个分组但有共同的时间基准的基本数据流(PES) ...
最新文章
- linux下运行python unitest_Python unittest打印日志可以在Linux上运行,但在Windows上不行...
- 【NAACL2021】Graph4NLP:图深度学习自然语言处理(附ppt)
- CentOS常见配置
- c++ 人脸识别_应用层下的人脸识别(四):人脸研判
- ENVI5.4完美实现MODIS NDVI数据格式转换和投影变换
- OpenCV 4.0 rc版本发布,扩展计算图Graph API
- android录音相关
- Lodop设置打印维护返回打印语句代码
- Android如何实现音频输出路由的切换
- JMS-activeMq点对点模式
- Topaz DeNoise AI 3.6.2 for Mac(图片降噪软件)
- 前端分页(详细步骤)
- HTML表格循环中合并单元格,table循环实现表格相同列合并
- 关于给hexo博客增加每日一言(诗句,影视名句,网易云热评等)
- 人工智能点点通-AI开发工具介绍-钱兴会-专题视频课程
- HTML5实现动态时钟
- 微信小程序中定位报错在app.json中声明permission字段
- 这可能是我学习计算机以来的全部收获和总结
- Go发送Gmail邮件
- python3.8.2怎么卸载_Python卸载
热门文章
- Unity MegaFiers导入(pc2)格式缓存动画失败出现错误
- mysql联合查询和关联查询
- 采集到竞争对手公司信息的10个经典方法
- python 笔记:dtw包
- STM32 MCUISP下载 开始连接...401, 接收到: 芯片超时无应答,无法连接
- 从零开始安卓无障碍服务Accessibility
- LPK木马分析-03
- linux编辑jar包内文件,报错无法保存处理
- JSP页面%@ ...%是 什么意思
- Flutter 小技巧之玩转字体渲染和问题修复