ffmpeg编码aac音频

这段代码展示了如何使用FFmpeg库找到MP2编码器,配置编码参数如采样率、位率和声道布局,并编码单音节音频数据到AAC文件。主要函数包括检查样本格式支持、选择采样率和声道布局。最终将编码后的音频写入指定文件。
摘要由CSDN通过智能技术生成

在这里插入图片描述
主要代码如下

#include<stdio.h>
#include "libavutil/avutil.h"
#include "libavutil/timestamp.h"
#include "libavdevice/avdevice.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "ff.h"
/* check that a given sample format is supported by the encoder */
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
{
    const enum AVSampleFormat *p = codec->sample_fmts;

    while (*p != AV_SAMPLE_FMT_NONE) {
        if (*p == sample_fmt)
            return 1;
        p++;
    }
    return 0;
}

/* just pick the highest supported samplerate */
static int select_sample_rate(const AVCodec *codec)
{
    const int *p;
    int best_samplerate = 0;

    if (!codec->supported_samplerates)
        return 44100;

    p = codec->supported_samplerates;
    while (*p) {
        if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
            best_samplerate = *p;
        p++;
    }
    return best_samplerate;
}

/* select layout with the highest channel count */
static int select_channel_layout(const AVCodec *codec)
{
    const uint64_t *p;
    uint64_t best_ch_layout = 0;
    int best_nb_channels   = 0;

    if (!codec->channel_layouts)
        return AV_CH_LAYOUT_STEREO;

    p = codec->channel_layouts;
    while (*p) {
        int nb_channels = av_get_channel_layout_nb_channels(*p);

        if (nb_channels > best_nb_channels) {
            best_ch_layout    = *p;
            best_nb_channels = nb_channels;
        }
        p++;
    }
    return best_ch_layout;
}


void encode_audio(void) {

    const char *filename="/home/chendongpu/encode_audio.aac";
        const AVCodec *codec;
        AVCodecContext *c= NULL;
        AVFrame *frame;
        AVPacket pkt;
        int i, j, k, ret, got_output;
        FILE *f;
        uint16_t *samples;
        float t, tincr;

//        if (argc <= 1) {
//            fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
//            return 0;
//        }
//        filename = argv[1];

        /* register all the codecs */
        avcodec_register_all();

        /* find the MP2 encoder */
        codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
        if (!codec) {
            fprintf(stderr, "Codec not found\n");
            exit(1);
        }

        c = avcodec_alloc_context3(codec);
        if (!c) {
            fprintf(stderr, "Could not allocate audio codec context\n");
            exit(1);
        }

        /* put sample parameters */
        c->bit_rate = 64000;

        /* check that the encoder supports s16 pcm input */
        c->sample_fmt = AV_SAMPLE_FMT_S16;
        if (!check_sample_fmt(codec, c->sample_fmt)) {
            fprintf(stderr, "Encoder does not support sample format %s",
                    av_get_sample_fmt_name(c->sample_fmt));
            exit(1);
        }

        /* select other audio parameters supported by the encoder */
        c->sample_rate    = select_sample_rate(codec);
        c->channel_layout = select_channel_layout(codec);
        c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);

        /* open it */
        if (avcodec_open2(c, codec, NULL) < 0) {
            fprintf(stderr, "Could not open codec\n");
            exit(1);
        }

        f = fopen(filename, "wb+");
        if (!f) {
            fprintf(stderr, "Could not open %s\n", filename);
            exit(1);
        }

        /* frame containing input raw audio */
        frame = av_frame_alloc();
        if (!frame) {
            fprintf(stderr, "Could not allocate audio frame\n");
            exit(1);
        }

        frame->nb_samples     = c->frame_size;
        frame->format         = c->sample_fmt;
        frame->channel_layout = c->channel_layout;

        /* allocate the data buffers */
        ret = av_frame_get_buffer(frame, 0);
        if (ret < 0) {
            fprintf(stderr, "Could not allocate audio data buffers\n");
            exit(1);
        }

        /* encode a single tone sound */
        t = 0;
        tincr = 2 * M_PI * 440.0 / c->sample_rate;
        for (i = 0; i < 200; i++) {
            av_init_packet(&pkt);
            pkt.data = NULL; // packet data will be allocated by the encoder
            pkt.size = 0;

            /* make sure the frame is writable -- makes a copy if the encoder
             * kept a reference internally */
            ret = av_frame_make_writable(frame);
            if (ret < 0)
                exit(1);
            samples = (uint16_t*)frame->data[0];

            for (j = 0; j < c->frame_size; j++) {
                samples[2*j] = (int)(sin(t) * 10000);

                for (k = 1; k < c->channels; k++)
                    samples[2*j + k] = samples[2*j];
                t += tincr;
            }
            /* encode the samples */
            ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
            if (ret < 0) {
                fprintf(stderr, "Error encoding audio frame\n");
                exit(1);
            }
            if (got_output) {
                fwrite(pkt.data, 1, pkt.size, f);
                av_packet_unref(&pkt);
            }
        }

        /* get the delayed frames */
        for (got_output = 1; got_output; i++) {
            ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
            if (ret < 0) {
                fprintf(stderr, "Error encoding frame\n");
                exit(1);
            }

            if (got_output) {
                fwrite(pkt.data, 1, pkt.size, f);
                av_packet_unref(&pkt);
            }
        }
        fclose(f);

        av_frame_free(&frame);
        avcodec_free_context(&c);

      return ;
}


下载代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

reg183

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值