这篇博客主要记录的是
extern "C" {
#include
#include
#include
#include
}
#include
#include
int buildAdtsHeader(char *const header, const int dataLength, const int profile, const int samplerate, const int channels) {
//采样率编号
std::map<int, int> samplerateMap;
samplerateMap.insert(std::make_pair(96000, 0x0));
samplerateMap.insert(std::make_pair(88200, 0x1));
samplerateMap.insert(std::make_pair(64000, 0x2));
samplerateMap.insert(std::make_pair(48000, 0x3));
samplerateMap.insert(std::make_pair(44100, 0x4));
samplerateMap.insert(std::make_pair(32000, 0x5));
samplerateMap.insert(std::make_pair(24000, 0x6));
samplerateMap.insert(std::make_pair(22050, 0x7));
samplerateMap.insert(std::make_pair(16000, 0x8));
samplerateMap.insert(std::make_pair(12000, 0x9));
samplerateMap.insert(std::make_pair(11025, 0xa));
samplerateMap.insert(std::make_pair(8000, 0xb));
int samplerateCode = samplerateMap.find(samplerate)->second;
//生成Header
int frameLength = dataLength + 7;
header[0] = 0xff; //syncword:0xff
header[1] = 0xf0;
header[1] |= (0 << 3); //MPEG Version: 0 MPEG-4, 1 MPEG-2, 1bit
header[1] |= (0 << 1); //Layer: 0, 2bit
header[1] |= 1; //protection absent: 1, 1bit
header[2] = (profile) << 6; //profile: aac profile, 2bit
header[2] |= (samplerateCode & 0x0f) << 2; //samplerate, 4bit
header[2] |= (0 << 1); //private bit: 0, 1bit
header[2] |= (channels & 0x04) >> 2; //channels, 1bit
header[3] = (channels & 0x03) << 6; //channels, 2bit
header[3] |= (0 << 5); //original: 0, 1bit
header[3] |= (0 << 4); //home: 0, 1bit
header[3] |= (0 << 3); //copyright id bit: 0, 1bit
header[3] |= (0 << 2); //copyright id start: 0, 1bit
header[3] |= ((frameLength & 0x1800) >> 11); //frame length part1, 2bit
header[4] = (uint8_t)((frameLength & 0x7f8) >> 3); //frame length part2, 8bit
header[5] = (uint8_t)((frameLength & 0x7) << 5); //frame length part3, 3bit
header[5] |= 0x1f; //buffer fullness part1, 5bit
header[6] = 0xfc; //buffer fullness part2, 6bit
return 0;
}
int main() {
char *inputFile = "G:/src.mp4";
char *outputFile = "G:/dst.aac";
FILE *aacFile = fopen(outputFile, "wb+");
//打开视频文件
AVFormatContext *avFormatContext = NULL;
avformat_open_input(&avFormatContext, inputFile, NULL, NULL);
//探测流信息
avformat_find_stream_info(avFormatContext, NULL);
//获取音频流
int audioStreamIndex = av_find_best_stream(avFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
AVStream *audioStream = avFormatContext->streams[audioStreamIndex];
//创建并初始化AVPacket
AVPacket *packet = av_packet_alloc();
av_init_packet(packet);
//读取文件,把aac数据写入文件
while (av_read_frame(avFormatContext, packet) >= 0) {
if (packet->stream_index != audioStreamIndex)
continue;
//创建AVPacket对应的头部
char header[7] = {};
buildAdtsHeader(header, packet->size, audioStream->codecpar->profile, audioStream->codecpar->sample_rate, audioStream->codecpar->channels);
//写入AVPacket的Header和Body
//如果是TS流的数据话,AVPacket本身已经携带Header了,不需要再写入
fwrite(header, 1, 7, aacFile);
fwrite(packet->data, 1, packet->size, aacFile);
//解除一个引用计数
av_packet_unref(packet);
}
//关闭和释放资源
av_free_packet(packet);
if (avFormatContext)
avformat_close_input(&avFormatContext);
if (aacFile)
fclose(aacFile);
return 0;
}