FFmpeg -Mp4解封装提取音频包写入out1.aac文件中(代码实现)

#include <iostream>
using namespace std;
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include <stdio.h>
}
const int sampling_frequencies[] = {
        96000,  // 0x0
        88200,  // 0x1
        64000,  // 0x2
        48000,  // 0x3
        44100,  // 0x4
        32000,  // 0x5
        24000,  // 0x6
        22050,  // 0x7
        16000,  // 0x8
        12000,  // 0x9
        11025,  // 0xa
        8000   // 0xb
        // 0xc d e f是保留的
};

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; // 默认使用48000hz
    int adtsLen = data_length + 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) {
        std::cout << "没有找到支持的采样率" << std::endl;
        return -1;
    }

    p_adts_header[0] = 0xff;         //syncword:0xfff                          高8bits
    p_adts_header[1] = 0xf0;         //syncword:0xfff                          低4bits
    p_adts_header[1] |= (0 << 3);    //MPEG Version:0 for MPEG-4,1 for MPEG-2  1bit
    p_adts_header[1] |= (0 << 1);    //Layer:0                                 2bits
    p_adts_header[1] |= 1;           //protection absent:1                     1bit

    p_adts_header[2] = (profile) << 6;            //profile:profile               2bits
    p_adts_header[2] |=
            (sampling_frequency_index & 0x0f) << 2; //sampling frequency index:sampling_frequency_index  4bits
    p_adts_header[2] |= (0 << 1);             //private bit:0                   1bit
    p_adts_header[2] |= (channels & 0x04) >> 2; //channel configuration:channels  高1bit

    p_adts_header[3] = (channels & 0x03) << 6; //channel configuration:channels 低2bits
    p_adts_header[3] |= (0 << 5);               //original:0                1bit
    p_adts_header[3] |= (0 << 4);               //home:0                    1bit
    p_adts_header[3] |= (0 << 3);               //copyright id bit:0        1bit
    p_adts_header[3] |= (0 << 2);               //copyright id start:0      1bit
    p_adts_header[3] |= ((adtsLen & 0x1800) >> 11);           //frame length:value   高2bits

    p_adts_header[4] = (uint8_t) ((adtsLen & 0x7f8) >> 3);     //frame length:value    中间8bits
    p_adts_header[5] = (uint8_t) ((adtsLen & 0x7) << 5);       //frame length:value    低3bits
    p_adts_header[5] |= 0x1f;                                 //buffer fullness:0x7ff 高5bits
    p_adts_header[6] = 0xfc;      //‭11111100‬       //buffer fullness:0x7ff 低6bits

    return 0;
}
int main(){
    const char *in_filename="in2.mp4";
    const char *aac_filename="out1.aac";
    FILE *aac_fd=NULL;
    aac_fd=fopen(aac_filename,"wb");

    AVFormatContext *ifmt_ctx=NULL;
    int audio_index=-1;
    AVPacket *pkt=NULL;
    int ret=0;

    ifmt_ctx=avformat_alloc_context();
    ret=avformat_open_input(&ifmt_ctx,in_filename,NULL,NULL);
    audio_index=av_find_best_stream(ifmt_ctx,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);

     pkt=av_packet_alloc();
    av_init_packet(pkt);
    while(1){
        ret=av_read_frame(ifmt_ctx,pkt);   //不会去释放pkt的buf,如果我们外部不去释放,就会出现内存泄漏
        if(ret<0){     //跳出循环
            break;
        }
        if(pkt->stream_index==audio_index){
            //处理音频
             int len=0;
            char adts_header_buf[7]={0};
            adts_header(adts_header_buf,pkt->size,
                                         ifmt_ctx->streams[audio_index]->codecpar->profile,
                                         ifmt_ctx->streams[audio_index]->codecpar->sample_rate,
                                         ifmt_ctx->streams[audio_index]->codecpar->channels );
            fwrite(adts_header_buf,1,7,aac_fd);   //写adts header,ts流不适用,ts流分离出来的packet带了adts header
            len=fwrite(pkt->data,1,pkt->size,aac_fd);  //写adts data
            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);
        }else{
            av_packet_unref(pkt);  //释放buffer
        }
    }
    printf("while finsh\n");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值