国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【秒懂音視頻開發(fā)】15_AAC編碼實戰(zhàn)

這篇具有很好參考價值的文章主要介紹了【秒懂音視頻開發(fā)】15_AAC編碼實戰(zhàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本文將分別通過命令行、編程2種方式進行AAC編碼實戰(zhàn),使用的編碼庫是libfdk_aac。

要求

fdk-aac對輸入的PCM數(shù)據(jù)是有參數(shù)要求的,如果參數(shù)不對,就會出現(xiàn)以下錯誤:

[libfdk_aac @ 0x7fa3db033000] Unable to initialize the encoder: SBR library initialization error
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!

采樣格式

必須是16位整數(shù)PCM。

采樣率

支持的采樣率有(Hz):

  • 8000、11025、12000、16000、22050、24000、32000
  • 44100、48000、64000、88200、96000

命令行

基本使用

最簡單的用法如下所示:

# pcm -> aac
ffmpeg -ar 44100 -ac 2 -f s16le -i in.pcm -c:a libfdk_aac out.aac
 
# wav -> aac
# 為了簡化指令,本文后面會盡量使用in.wav取代in.pcm
ffmpeg -i in.wav -c:a libfdk_aac out.aac
  • -ar 44100 -ac 2 -f s16le

    • PCM輸入數(shù)據(jù)的參數(shù)
  • -c:a

    • 設置音頻編碼器
    • c表示codec(編解碼器),a表示audio(音頻)
    • 等價寫法
      • -codec:a
      • -acodec
    • 需要注意的是:這個參數(shù)要寫在aac文件那邊,也就是屬于輸出參數(shù)

默認生成的aac文件是LC規(guī)格的。

ffprobe out.aac
 
# 輸出結果如下所示
Audio: aac (LC), 44100 Hz, stereo, fltp, 120 kb/s

常用參數(shù)

  • -b:a
    • 設置輸出比特率
    • 比如-b:a 96k
ffmpeg -i in.wav -c:a libfdk_aac -b:a 96k out.aac
  • -profile:a
    • 設置輸出規(guī)格
    • 取值有:
      • aac_low:Low Complexity AAC (LC),默認值
      • aac_he:High Efficiency AAC (HE-AAC)
      • aac_he_v2:High Efficiency AAC version 2 (HE-AACv2)
      • aac_ld:Low Delay AAC (LD)
      • aac_eld:Enhanced Low Delay AAC (ELD)
    • 一旦設置了輸出規(guī)格,會自動設置一個合適的輸出比特率
      • 也可以用過-b:a自行設置輸出比特率
ffmpeg -i in.wav -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k out.aac
  • -vbr
    • 開啟VBR模式(Variable Bit Rate,可變比特率)
    • 如果開啟了VBR模式,-b:a選項將會被忽略,但-profile:a選項仍然有效
    • 取值范圍是0 ~ 5
      • 0:默認值,關閉VBR模式,開啟CBR模式(Constant Bit Rate,固定比特率)
      • 1:質(zhì)量最低(但是音質(zhì)仍舊很棒)
      • 5:質(zhì)量最高

【秒懂音視頻開發(fā)】15_AAC編碼實戰(zhàn)

?關注+私信1,免費分享2022最新最全學習提升資料包,資料內(nèi)容包括《Andoird音視頻開發(fā)必備手冊+音視頻最新學習視頻+大廠面試真題+2022最新學習路線圖(C/C++,Linux,F(xiàn)Fmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)等等?

【秒懂音視頻開發(fā)】15_AAC編碼實戰(zhàn)

?

AOT是Audio Object Type的簡稱。

ffmpeg -i in.wav -c:a libfdk_aac -vbr 1 out.aac

文件格式

AAC編碼的文件擴展名主要有3種:aac、m4a、mp4。

# m4a
ffmpeg -i in.wav -c:a libfdk_aac out.m4a
 
# mp4
ffmpeg -i in.wav -c:a libfdk_aac out.mp4

編程

需要用到2個庫:

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
}
 
// 錯誤處理
#define ERROR_BUF(ret) \
    char errbuf[1024]; \
    av_strerror(ret, errbuf, sizeof (errbuf));

函數(shù)聲明

我們最終會將PCM轉(zhuǎn)AAC的操作封裝到一個函數(shù)中。

extern "C" {
#include <libavcodec/avcodec.h>
}
 
// 參數(shù)
typedef struct {
    const char *filename;
    int sampleRate;
    AVSampleFormat sampleFmt;
    int chLayout;
} AudioEncodeSpec;
 
class FFmpegs {
public:
    FFmpegs();
 
    static void aacEncode(AudioEncodeSpec &in,
                          const char *outFilename);
};

函數(shù)實現(xiàn)

變量定義

// 編碼器
AVCodec *codec = nullptr;
// 上下文
AVCodecContext *ctx = nullptr;
 
// 用來存放編碼前的數(shù)據(jù)
AVFrame *frame = nullptr;
// 用來存放編碼后的數(shù)據(jù)
AVPacket *pkt = nullptr;
 
// 返回結果
int ret = 0;
 
// 輸入文件
QFile inFile(in.filename);
// 輸出文件
QFile outFile(outFilename);

獲取編碼器

下面的代碼可以獲取FFmpeg默認的AAC編碼器(并不是libfdk_aac)。

AVCodec *codec1 = avcodec_find_encoder(AV_CODEC_ID_AAC);
 
AVCodec *codec2 = avcodec_find_encoder_by_name("aac");
 
// true
qDebug() << (codec1 == codec2);
 
// aac
qDebug() << codec1->name;

不過我們最終要獲取的是libfdk_aac。

// 獲取fdk-aac編碼器
codec = avcodec_find_encoder_by_name("libfdk_aac");
if (!codec) {
    qDebug() << "encoder libfdk_aac not found";
    return;
}

檢查采樣格式

接下來檢查編碼器是否支持當前的采樣格式。

// 檢查采樣格式
if (!check_sample_fmt(codec, in.sampleFmt)) {
    qDebug() << "Encoder does not support sample format"
             << av_get_sample_fmt_name(in.sampleFmt);
    return;
}

檢查函數(shù)check_sample_fmt的實現(xiàn)如下所示。

// 檢查編碼器codec是否支持采樣格式sample_fmt
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;
}

創(chuàng)建上下文

avcodec_alloc_context3后面的3說明這已經(jīng)是第3版API,取代了此前的avcodec_alloc_contextavcodec_alloc_context2。

// 創(chuàng)建上下文
ctx = avcodec_alloc_context3(codec);
if (!ctx) {
    qDebug() << "avcodec_alloc_context3 error";
    return;
}
 
// 設置參數(shù)
ctx->sample_fmt = in.sampleFmt;
ctx->sample_rate = in.sampleRate;
ctx->channel_layout = in.chLayout;
// 比特率
ctx->bit_rate = 32000;
// 規(guī)格
ctx->profile = FF_PROFILE_AAC_HE_V2;

打開編碼器

// 打開編碼器
ret = avcodec_open2(ctx, codec, nullptr);
if (ret < 0) {
    ERROR_BUF(ret);
    qDebug() << "avcodec_open2 error" << errbuf;
    goto end;
}

如果是想設置一些libfdk_aac特有的參數(shù)(比如vbr),可以通過options參數(shù)傳遞。

AVDictionary *options = nullptr;
av_dict_set(&options, "vbr", "1", 0);
ret = avcodec_open2(ctx, codec, &options);

創(chuàng)建AVFrame

AVFrame用來存放編碼前的數(shù)據(jù)。

// 創(chuàng)建AVFrame
frame = av_frame_alloc();
if (!frame) {
    qDebug() << "av_frame_alloc error";
    goto end;
}
 
// 樣本幀數(shù)量(由frame_size決定)
frame->nb_samples = ctx->frame_size;
// 采樣格式
frame->format = ctx->sample_fmt;
// 聲道布局
frame->channel_layout = ctx->channel_layout;
// 創(chuàng)建AVFrame內(nèi)部的緩沖區(qū)
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
    ERROR_BUF(ret);
    qDebug() << "av_frame_get_buffer error" << errbuf;
    goto end;
}

創(chuàng)建AVPacket

// 創(chuàng)建AVPacket
pkt = av_packet_alloc();
if (!pkt) {
    qDebug() << "av_packet_alloc error";
    goto end;
}

打開文件

// 打開文件
if (!inFile.open(QFile::ReadOnly)) {
    qDebug() << "file open error" << in.filename;
    goto end;
}
if (!outFile.open(QFile::WriteOnly)) {
    qDebug() << "file open error" << outFilename;
    goto end;
}

開始編碼

// frame->linesize[0]是緩沖區(qū)的大小
// 讀取文件數(shù)據(jù)
while ((ret = inFile.read((char *) frame->data[0],
                          frame->linesize[0])) > 0) {
    // 最后一次讀取文件數(shù)據(jù)時,有可能并沒有填滿frame的緩沖區(qū)
    if (ret < frame->linesize[0]) {
        // 聲道數(shù)
        int chs = av_get_channel_layout_nb_channels(frame->channel_layout);
        // 每個樣本的大小
        int bytes = av_get_bytes_per_sample((AVSampleFormat) frame->format);
        // 改為真正有效的樣本幀數(shù)量
        frame->nb_samples = ret / (chs * bytes);
    }
 
    // 編碼
    if (encode(ctx, frame, pkt, outFile) < 0) {
        goto end;
    }
}
 
// flush編碼器
encode(ctx, nullptr, pkt, outFile);

encode函數(shù)專門用來進行編碼,它的實現(xiàn)如下所示。

// 音頻編碼
// 返回負數(shù):中途出現(xiàn)了錯誤
// 返回0:編碼操作正常完成
static int encode(AVCodecContext *ctx,
                  AVFrame *frame,
                  AVPacket *pkt,
                  QFile &outFile) {
    // 發(fā)送數(shù)據(jù)到編碼器
    int ret = avcodec_send_frame(ctx, frame);
    if (ret < 0) {
        ERROR_BUF(ret);
        qDebug() << "avcodec_send_frame error" << errbuf;
        return ret;
    }
 
    while (true) {
        // 從編碼器中獲取編碼后的數(shù)據(jù)
        ret = avcodec_receive_packet(ctx, pkt);
        // packet中已經(jīng)沒有數(shù)據(jù),需要重新發(fā)送數(shù)據(jù)到編碼器(send frame)
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
            return 0;
        } else if (ret < 0) { // 出現(xiàn)了其他錯誤
            ERROR_BUF(ret);
            qDebug() << "avcodec_receive_packet error" << errbuf;
            return ret;
        }
 
        // 將編碼后的數(shù)據(jù)寫入文件
        outFile.write((char *) pkt->data, pkt->size);
 
        // 釋放資源
        av_packet_unref(pkt);
    }
 
    return 0;
}

資源回收文章來源地址http://www.zghlxwxcb.cn/news/detail-434902.html

end:
    // 關閉文件
    inFile.close();
    outFile.close();
 
    // 釋放資源
    av_frame_free(&frame);
    av_packet_free(&pkt);
    avcodec_free_context(&ctx);

函數(shù)調(diào)用

AudioEncodeSpec in;
in.filename = "F:/in.pcm";
in.sampleRate = 44100;
in.sampleFmt = AV_SAMPLE_FMT_S16;
in.chLayout = AV_CH_LAYOUT_STEREO;
 
FFmpegs::aacEncode(in, "F:/out.aac");

到了這里,關于【秒懂音視頻開發(fā)】15_AAC編碼實戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【秒懂音視頻開發(fā)】26_RTMP服務器搭建

    【秒懂音視頻開發(fā)】26_RTMP服務器搭建

    基本概念 流媒體(Streaming media),也叫做:流式媒體。 是指將一連串的多媒體數(shù)據(jù)壓縮后,經(jīng)過互聯(lián)網(wǎng) 分段發(fā)送 數(shù)據(jù),在互聯(lián)網(wǎng)上即時傳輸影音以供觀賞的一種技術與過程 此技術使得數(shù)據(jù)包可以像 流水 一樣發(fā)送,如果不使用此技術,就必須得先 下載整個 媒體文件才能進

    2023年04月08日
    瀏覽(23)
  • 【音視頻 | AAC】AAC格式音頻文件解析

    【音視頻 | AAC】AAC格式音頻文件解析

    ??博客主頁??:??https://blog.csdn.net/wkd_007?? ??博客內(nèi)容??:??嵌入式開發(fā)、Linux、C語言、C++、數(shù)據(jù)結構、音視頻?? ??本文內(nèi)容??:??介紹AAC格式音頻文件解析?? ??金句分享??:??你不能選擇最好的,但最好的會來選擇你——泰戈爾?? 本文未經(jīng)允許,不得轉(zhuǎn)發(fā)!!

    2024年02月04日
    瀏覽(25)
  • 音視頻編碼實戰(zhàn)-------pcm+yuv數(shù)據(jù)轉(zhuǎn)成MP4

    音視頻編碼實戰(zhàn)-------pcm+yuv數(shù)據(jù)轉(zhuǎn)成MP4

    avcodec_find_encoder: 根據(jù)編碼器ID查找編碼器 avcodec_alloc_context3:創(chuàng)建編碼器上下文 avcodec_open2:打開編碼器 avformat_alloc_output_context2:為輸出格式創(chuàng)建復用器上下文 avformat_new_stream:創(chuàng)建音視頻流 avcodec_parameters_from_context:將編碼器上下文中的參數(shù)拷貝到音視頻流中的編碼器參數(shù)中AVCodec

    2024年02月15日
    瀏覽(32)
  • 音視頻處理 ffmpeg中級開發(fā) H264編碼

    音視頻處理 ffmpeg中級開發(fā) H264編碼

    libavcodec/avcodec.h 常用的數(shù)據(jù)結構 AVCodec 編碼器結構體 AVCodecContext 編碼器上下文 AVFrame 解碼后的幀 結構體內(nèi)存的分配和釋放 av_frame_alloc 申請 av_frame_free() 釋放 avcodec_alloc_context3() 創(chuàng)建編碼器上下文 avcodec_free_context() 釋放編碼器上下文 解碼步驟 avcodec_find_decoder 查找解碼器 avcod

    2024年02月01日
    瀏覽(109)
  • Qt/C++音視頻開發(fā)69-保存監(jiān)控pcm音頻數(shù)據(jù)到mp4文件/監(jiān)控錄像/錄像存儲和回放/264/265/aac/pcm等

    用ffmpeg做音視頻保存到mp4文件,都會遇到一個問題,尤其是在視頻監(jiān)控行業(yè),就是監(jiān)控攝像頭設置的音頻是PCM/G711A/G711U,解碼后對應的格式是pcm_s16be/pcm_alaw/pcm_mulaw,將這個原始的音頻流保存到mp4文件是會報錯的,在調(diào)用avformat_write_header寫文件頭的時候提示(-22) Invalid argument,

    2024年04月11日
    瀏覽(37)
  • 音視頻八股文(7)-- 音頻aac adts三層結構

    音視頻八股文(7)-- 音頻aac adts三層結構

    AAC(Advanced Audio Coding)是一種現(xiàn)代的音頻編碼技術,用于數(shù)字音頻的傳輸和存儲領域。AAC是MPEG-2和MPEG-4標準中的一部分,可提供更高質(zhì)量的音頻數(shù)據(jù),并且相比于MP3等舊有音頻格式,AAC需要更少的比特率。 AAC通過使用一些高級的音頻編碼算法來實現(xiàn)更好的聲音質(zhì)量和更低的壓

    2024年02月06日
    瀏覽(20)
  • RK3568平臺開發(fā)系列講解(音視頻篇)H264 的編碼結構

    RK3568平臺開發(fā)系列講解(音視頻篇)H264 的編碼結構

    ??返回專欄總目錄 沉淀、分享、成長,讓自己和他人都能有所收獲!?? ??視頻編碼的碼流結構其實就是指視頻經(jīng)過編碼之后得到的二進制數(shù)據(jù)是怎么組織的,換句話說,就是編碼后的碼流我們怎么將一幀幀編碼后的圖像數(shù)據(jù)分離出來,以及在二進制碼流數(shù)據(jù)中,哪一塊數(shù)

    2024年02月09日
    瀏覽(92)
  • 音視頻知識:MPEG-4、H264、MP4、AAC之間的關系

    MPEG-4 一種編碼標準。是國際標準化組織 (ISO) 主要針對消費類應用,已經(jīng)針對運動圖像壓縮定義的標準。MPEG(Moving Picture Experts Group)標準包括 MPEG1、MPEG2與 MPEG4。 MPEG-4標準目前分為27個部分,統(tǒng)稱為ISO/IEC14496國際標準。其中第10部分(ISO/IEC 14496-10)就是熟悉的高級視頻編碼

    2024年02月14日
    瀏覽(40)
  • 音視頻八股文(9)-- flv的h264六層結構和aac六層結構

    音視頻八股文(9)-- flv的h264六層結構和aac六層結構

    FLV(Flash Video)是Adobe公司推出的?種流媒體格式,由于其封裝后的?視頻?件體積?、封裝簡單等特點,?常適合于互聯(lián)?上使?。?前主流的視頻?站基本都?持FLV。采?FLV格式封裝的?件后綴為.flv。 FLV封裝格式是由?個?件頭(file header)和 ?件體(file Body)組成。其中,F(xiàn)LV

    2024年02月01日
    瀏覽(28)
  • Android音視頻開發(fā)實戰(zhàn)02-Jni

    Android音視頻開發(fā)實戰(zhàn)02-Jni

    JNI是Java Native Interface的縮寫,是Java提供的一種機制,用于在Java代碼中調(diào)用本地(C/C++)代碼。它允許Java代碼與本地代碼進行交互,通過JNI,Java應用程序可以調(diào)用一些原生庫或者操作系統(tǒng)API,以獲取更好的性能和更強的功能支持。 使用JNI需要編寫一些Native方法,并將其實現(xiàn)在

    2024年02月11日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包