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

FFmpeg 解碼 AAC 格式的音頻

這篇具有很好參考價(jià)值的文章主要介紹了FFmpeg 解碼 AAC 格式的音頻。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

FFmpeg 默認(rèn)是可以解碼 AAC 格式的音頻,但是如果需要獲取 PCM16 此類數(shù)據(jù)則需要經(jīng)過音頻轉(zhuǎn)碼。首先要打開解碼器,然后向解碼器發(fā)送 AAC 音頻幀(不帶 ADTS),然后從解碼器獲取解碼后的音頻幀,數(shù)據(jù)是 float 類型的,如果需要則進(jìn)行轉(zhuǎn)碼流程將 float 轉(zhuǎn)成整型。

一、AAC 音頻

AAC 是高級音頻編碼(Advanced Audio Coding)的縮寫,出現(xiàn)于 1997 年,最初是基于 MPEG-2 的音頻編碼技術(shù)。由Fraunhofer IIS、Dolby Laboratories、AT&T、Sony 等公司共同開發(fā),目的是取代 MP3 格式。2000 年,MPEG-4 標(biāo)準(zhǔn)出臺,AAC 重新集成了其它技術(shù)(PS、SBR),為區(qū)別于傳統(tǒng)的 MPEG-2 AAC,故含有 SBR 或 PS 特性的 AAC 又稱為 MPEG-4 AAC。

AAC 是新一代的音頻有損壓縮技術(shù),它通過一些附加的編碼技術(shù)(比如 PS、SBR 等),衍生出了LC-AAC、HE-AAC、HE-AACv2 三種主要的編碼,LC-AAC 就是比較傳統(tǒng)的 AAC,相對而言,主要用于中高碼率(>=80Kbps),HE-AAC(相當(dāng)于AAC+SBR)主要用于中低碼(<=80Kbps),而新近推出的 HE-AACv2 (相當(dāng)于AAC+SBR+PS)主要用于低碼率(<=48Kbps),事實(shí)上大部分編碼器設(shè)成 <=48Kbps 自動啟用 PS 技術(shù),而 >48Kbps 就不加 PS,就相當(dāng)于普通的 HE-AAC。

1.1 種類

FFmpeg 中一共定義了十種 Profile 格式的 AAC,帶 MPEG2 為 MPEG2 支持,其他的為 MPEG4 支持的。

avcodec.h
?

#define FF_PROFILE_AAC_MAIN 0
#define FF_PROFILE_AAC_LOW  1
#define FF_PROFILE_AAC_SSR  2
#define FF_PROFILE_AAC_LTP  3
#define FF_PROFILE_AAC_HE   4
#define FF_PROFILE_AAC_HE_V2 28
#define FF_PROFILE_AAC_LD   22
#define FF_PROFILE_AAC_ELD  38
#define FF_PROFILE_MPEG2_AAC_LOW 128
#define FF_PROFILE_MPEG2_AAC_HE  131

MAIN 代表主規(guī)格

LOW 低復(fù)雜度規(guī)格(Low Complexity)

SSR 可變采樣率規(guī)格(Scaleable Sample Rate)

LTP 長時(shí)期預(yù)測規(guī)格(Long Term Predicition)

HE 高效率規(guī)格(High Efficiency)AAC+

HE_V2 高效率 V2 規(guī)格(High Efficiency V2)Enhanced AAC+

LD 低延遲規(guī)格(Low Delay)

ELD 增強(qiáng)低延遲規(guī)格(Enhanced low Low Delay)

1.2 格式

查看《ISO/IEC 13818-7》可進(jìn)一步了解 AAC 音頻的詳細(xì)格式。AAC 的音頻文件格式有 ADIF 和 ADTS。

ADIF:Audio Data Interchange Format

音頻數(shù)據(jù)交換格式。這種格式的特征是可以確定的找到這個(gè)音頻數(shù)據(jù)的開始,不需進(jìn)行在音頻數(shù)據(jù)流中間開始的解碼,即它的解碼必須在明確定義的開始處進(jìn)行。故這種格式常用在磁盤文件中。

音頻數(shù)據(jù)交換格式序列包括 ADIF 頭,字節(jié)對齊和實(shí)際數(shù)據(jù)。
FFmpeg 解碼 AAC 格式的音頻

adif_id 表示音頻數(shù)據(jù)交換格式的 ID。它的值是 0x41444946 (最高位在前),這是字符串“ADIF”的 ASCII 表示形式。

copyright_id_present 指示copyright_id是否存在。

copyright_id 該字段由一個(gè)8位的 copyright_identifier 和一個(gè)64位的 copyright_number 組成。

original_copy 參見 ISO/IEC 11172-3 第 2.4.2.3 款對版權(quán)的定義。

home 參見 ISO/IEC 11172-3,第 2.4.2.3 小節(jié)對 original_copy 的定義。

bitstream_type 指明位流類型的標(biāo)志:

“0”恒速率比特流;

“1”可變速率比特流。

bitrate 一個(gè)23位無符號整數(shù),指示在恒定速率的比特流中比特流的比特率,或在可變速率的比特流中最大峰值比特率(每幀測量)。0表示不知道比特率。

num_program_config_element program_config_element() 的數(shù)量。

adif_buffer_fullness 在 adif_sequence() 中對第一個(gè) raw_data_block() 進(jìn)行編碼后 bit reservoir 的狀態(tài)。

ADTS:Audio Data Transport Stream

音頻數(shù)據(jù)傳輸流。這種格式的特征是它是一個(gè)有同步字的比特流,解碼可以在這個(gè)流中任何位置開始。它的特征類似于 mp3 數(shù)據(jù)流格式。

一般情況下 ADTS 的頭信息都是 7 個(gè)字節(jié),分為 2 部分:

adts_fixed_header() —— 固定部

adts_variable_header() —— 可變部分

FFmpeg 解碼 AAC 格式的音頻

FFmpeg 解碼 AAC 格式的音頻?

syncword 同步頭,總是 0xFFF,代表著一個(gè) ADTS 幀的開始。

ID MPEG 版本:0 代表 MPEG-4,1 代表 MPEG-2。

layer 總是 ‘00’。

profile 表示使用哪個(gè)級別的 AAC。

sampling_frequency_index 表示使用的采樣率下標(biāo),通過這個(gè)下標(biāo)在 Sampling Frequencies[] 數(shù)組中查找得知采樣率的值。
FFmpeg 解碼 AAC 格式的音頻

channel_configuration表示聲道數(shù)。

frame_length 一個(gè) ADTS 幀的長度包括 ADTS 頭和 AAC 原始流。

adts_buffer_fullness ADTS 幀編碼過程中 bit reservoir 的狀態(tài) ,0x7FF 說明是碼率可變的碼流。

protection_absent 指示是否存在 error_check() 數(shù)據(jù)。

private_bit 參見 ISO/IEC 11172-3,第 2.4.2.3 條。

copyright_identification_bit 表示 72 位版權(quán)標(biāo)識字段。

copyright_identification_start 表示 copyright_identification_bit

音頻幀是 72 位版權(quán)標(biāo)識的第一個(gè)位。如果沒有版權(quán)標(biāo)識被傳送,這個(gè)位應(yīng)該被保留 “0”。

number_of_raw_data_blocks_in_frame 被復(fù)用的 raw_data_block() 的數(shù)目。
FFmpeg 解碼 AAC 格式的音頻

?

二、AAC 音頻解碼

1.獲取 AAC 解碼器 Codec,調(diào)用 avcodec_find_decoder(AV_CODEC_ID_AAC) 獲取;

2.調(diào)用 avcodec_alloc_context3(…) 分配 AVCodecContext 結(jié)構(gòu),它是解碼器 Codec 上下文;

3.調(diào)用 avcodec_parameters_alloc() 分配 AVCodecParameters 結(jié)構(gòu),可用來給解碼器設(shè)置必要參數(shù);

4.將必要解碼參數(shù)設(shè)置到 AVCodecParameters,采樣率、聲道數(shù)、解碼后的格式(此處需要注意,實(shí)際上 AAC 解碼器默認(rèn)解碼后的格式都是 AV_SAMPLE_FMT_FLTP)等;

5.接下來調(diào)用 avcodec_parameters_to_context(…) 將 AVCodecParameters 結(jié)構(gòu)中的參數(shù)復(fù)制到 AVCodecContext,AVCodecParameters 結(jié)構(gòu)完成使命調(diào)用 avcodec_parameters_free(…) 釋放其內(nèi)存;

6.現(xiàn)在可以調(diào)用 avcodec_open2(…) 打開解碼器。

接下來就可以從 PacketQueue 隊(duì)列(存放 AAC 編碼的幀隊(duì)列,不需要帶 ADTS 頭,因?yàn)榻獯a器中的必要信息已經(jīng)設(shè)置)源源不斷獲取 AAC 編碼后的音頻幀送入解碼器進(jìn)行解碼。將編碼幀送到解碼器是調(diào)用 avcodec_send_packet(…) 實(shí)現(xiàn)的,然后就可以調(diào)用 avcodec_receive_frame(…) 獲取解碼幀。

由于有些平臺并不支持 AV_SAMPLE_FMT_FLTP 格式的 PCM 直接播放,所以需要將 float PCM 轉(zhuǎn)成 AV_SAMPLE_FMT_S16。

轉(zhuǎn)碼流程

1.調(diào)用 swr_alloc() 分配 SwrContext 轉(zhuǎn)碼上下文結(jié)構(gòu);

2.調(diào)用 swr_alloc_set_opts(…) 給轉(zhuǎn)碼上下文結(jié)構(gòu)設(shè)置必要參數(shù);

3.調(diào)用 swr_init(…) 初始化 SwrContext 轉(zhuǎn)碼上下文結(jié)構(gòu);

4.重復(fù)調(diào)用 swr_convert(…) 進(jìn)行轉(zhuǎn)碼。

最后,不在使用的 SwrContext 結(jié)構(gòu)、AVFrame 、AVCodecContext 全部都要調(diào)用其釋放函數(shù)進(jìn)行收尾工作。

FFmpeg 解碼 AAC 格式音頻代碼

將 AAC 解碼封裝到 AudioDecoder 類中。
?

//
// Created by liuhongwei on 2021/12/7.
//
 
#ifndef AUDIODECODER_H
#define AUDIODECODER_H
 
extern "C" {
//編解碼
#include "libavcodec/avcodec.h"
#include <libswresample/swresample.h>
}
 
#include "PacketQueue.h"
#include "cb/FrameDataCallback.h"
 
class AudioDecoder {
public:
    AudioDecoder(PacketQueue *packetQueue);
 
    ~AudioDecoder();
 
    bool open(unsigned int sampleFreq, unsigned int channels, unsigned int profile = 1);
 
    void close();
 
    void decode();
 
    static void *_decode(void *self) {
        static_cast<AudioDecoder *>(self)->decode();
        return nullptr;
    }
 
    void setFrameDataCallback(FrameDataCallback *frameDataCallback);
 
private:
    PacketQueue *pPacketQueue;
    AVCodecContext *pAudioAVCodecCtx;
    AVFrame *pFrame;
    unsigned int gSampleFreq;
 
    bool volatile isDecoding;
    pthread_t decodeThread;
    pthread_mutex_t *pFrameDataCallbackMutex;
    FrameDataCallback *pFrameDataCallback;
 
    SwrContext *pSwrContext;
    uint8_t *pPCM16OutBuf;
};
 
 
#endif //AUDIODECODER_H

?具體實(shí)現(xiàn)

//
// Created by liuhongwei on 2021/12/7.
//
 
#include <unistd.h>
#include "AudioDecoder.h"
 
AudioDecoder::AudioDecoder(PacketQueue *packetQueue) {
    pPacketQueue = packetQueue;
    pFrameDataCallbackMutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
    int ret = pthread_mutex_init(pFrameDataCallbackMutex, nullptr);
    if (ret != 0) {
        LOGE("audio FrameDataCallbackMutex init failed.\n");
    }
 
    pFrameDataCallback = nullptr;
    pSwrContext = nullptr;
    pPCM16OutBuf = nullptr;
}
 
AudioDecoder::~AudioDecoder() {
    pthread_mutex_destroy(pFrameDataCallbackMutex);
 
    if (nullptr != pFrameDataCallbackMutex) {
        free(pFrameDataCallbackMutex);
        pFrameDataCallbackMutex = nullptr;
    }
}
 
bool AudioDecoder::open(unsigned int sampleFreq, unsigned int channels, unsigned int profile) {
    gSampleFreq = sampleFreq;
 
    int ret;
    AVCodec *dec = avcodec_find_decoder(AV_CODEC_ID_AAC);
    LOGI("%s audio decoder name: %s", __FUNCTION__, dec->name);
    enum AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;//注意:設(shè)置為其他值并不生效
    int bytesPerSample = av_get_bytes_per_sample(sample_fmt);
 
    pAudioAVCodecCtx = avcodec_alloc_context3(dec);
 
    if (pAudioAVCodecCtx == nullptr) {
        LOGE("%s AudioAVCodecCtx alloc failed", __FUNCTION__);
        return false;
    }
 
    AVCodecParameters *par = avcodec_parameters_alloc();
    if (par == nullptr) {
        LOGE("%s audio AVCodecParameters alloc failed", __FUNCTION__);
        avcodec_free_context(&pAudioAVCodecCtx);
        return false;
    }
 
    par->codec_type = AVMEDIA_TYPE_AUDIO;
    par->sample_rate = (int) sampleFreq;
    par->channel_layout = av_get_default_channel_layout((int) channels);
    par->channels = (int) channels;
    par->bit_rate = sampleFreq * channels * bytesPerSample;
    par->format = sample_fmt;
    par->profile = (int) profile;
 
    avcodec_parameters_to_context(pAudioAVCodecCtx, par);
    avcodec_parameters_free(&par);
 
    LOGI("%s sample_rate=%d channels=%d bytesPerSample=%d", __FUNCTION__, sampleFreq, channels,
         bytesPerSample);
    ret = avcodec_open2(pAudioAVCodecCtx, dec, nullptr);
    if (ret < 0) {
        LOGE("%s Can not open audio encoder", __FUNCTION__);
        avcodec_free_context(&pAudioAVCodecCtx);
        return false;
    }
    LOGI("%s avcodec_open2 audio SUCC", __FUNCTION__);
    pFrame = av_frame_alloc();
    if (pFrame == nullptr) {
        LOGE("%s audio av_frame_alloc failed", __FUNCTION__);
        avcodec_free_context(&pAudioAVCodecCtx);
        return false;
    }
 
    pSwrContext = swr_alloc();
    if (pSwrContext == nullptr) {
        LOGE("%s swr_alloc failed", __FUNCTION__);
        avcodec_free_context(&pAudioAVCodecCtx);
        av_frame_free(&pFrame);
        return false;
    }
 
    swr_alloc_set_opts(
            pSwrContext,
            pAudioAVCodecCtx->channel_layout,
            AV_SAMPLE_FMT_S16,
            pAudioAVCodecCtx->sample_rate,
            pAudioAVCodecCtx->channel_layout,
            pAudioAVCodecCtx->sample_fmt,
            pAudioAVCodecCtx->sample_rate,
            0, nullptr
    );
 
    ret = swr_init(pSwrContext);
    if (ret != 0) {
        LOGE("%s swr_init failed", __FUNCTION__);
        avcodec_free_context(&pAudioAVCodecCtx);
        av_frame_free(&pFrame);
        swr_free(&pSwrContext);
        return false;
    }
 
    pPCM16OutBuf = (uint8_t *) malloc(
            av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * 1024);
 
    if (pPCM16OutBuf == nullptr) {
        LOGE("%s PCM16OutBufs malloc failed", __FUNCTION__);
        avcodec_free_context(&pAudioAVCodecCtx);
        av_frame_free(&pFrame);
        swr_free(&pSwrContext);
        return false;
    }
 
    isDecoding = true;
    ret = pthread_create(&decodeThread, nullptr, &AudioDecoder::_decode, (void *) this);
    if (ret != 0) {
        LOGE("audio decode-thread create failed.\n");
        isDecoding = false;
        avcodec_free_context(&pAudioAVCodecCtx);
        av_frame_free(&pFrame);
        swr_free(&pSwrContext);
 
        free(pPCM16OutBuf);
        pPCM16OutBuf = nullptr;
        return false;
    }
 
    return true;
}
 
void AudioDecoder::close() {
    isDecoding = false;
    pthread_join(decodeThread, nullptr);
 
    if (pPCM16OutBuf != nullptr) {
        free(pPCM16OutBuf);
        pPCM16OutBuf = nullptr;
        LOGI("%s PCM16OutBuf free", __FUNCTION__);
    }
 
    if (pSwrContext != nullptr) {
        swr_free(&pSwrContext);
        LOGI("%s SwrContext free", __FUNCTION__);
    }
 
    if (pFrame != nullptr) {
        av_frame_free(&pFrame);
        LOGI("%s audio Frame free", __FUNCTION__);
    }
 
    if (pAudioAVCodecCtx != nullptr) {
        avcodec_free_context(&pAudioAVCodecCtx);
        LOGI("%s audio avcodec_free_context", __FUNCTION__);
    }
}
 
void AudioDecoder::setFrameDataCallback(FrameDataCallback *frameDataCallback) {
    pthread_mutex_lock(pFrameDataCallbackMutex);
    pFrameDataCallback = frameDataCallback;
    pthread_mutex_unlock(pFrameDataCallbackMutex);
}
 
void AudioDecoder::decode() {
    int ret;
    unsigned sleepDelta = 1024 * 1000000 / gSampleFreq / 4;// 一幀音頻的 1/4
 
    while (isDecoding) {
        if (pPacketQueue == nullptr) {
            usleep(sleepDelta);
            continue;
        }
 
        AVPacket *pkt = av_packet_alloc();
        if (pkt == nullptr) {
            usleep(sleepDelta);
            continue;
        }
 
        PACKET_STRUCT *packetStruct;
        bool isDone = pPacketQueue->Take(packetStruct);
        if (isDone && packetStruct != nullptr && packetStruct->data != nullptr &&
            packetStruct->data_size > 0) {
            ret = av_new_packet(pkt, packetStruct->data_size);
            if (ret < 0) {
                av_packet_free(&pkt);
                free(packetStruct->data);
                free(packetStruct);
                
                continue;
            }
        } else {
            av_packet_free(&pkt);
            usleep(sleepDelta);
            continue;
        }
 
        memcpy(pkt->data, packetStruct->data, packetStruct->data_size);
 
        pkt->pts = packetStruct->timestamp;
        pkt->dts = packetStruct->timestamp;
 
 
        /* send the packet for decoding */
        ret = avcodec_send_packet(pAudioAVCodecCtx, pkt);
        //LOGD("%s send the audio packet for decoding pkt size=%d", __FUNCTION__, pkt->size);
        free(packetStruct->data);
        free(packetStruct);
 
        av_packet_unref(pkt);
        av_packet_free(&pkt);
 
        if (ret < 0) {
            LOGE("%s Error sending the audio pkt to the decoder ret=%d", __FUNCTION__, ret);
            usleep(sleepDelta);
            continue;
        } else {
            // 編碼和解碼都是一樣的,都是send 1次,然后receive多次, 直到AVERROR(EAGAIN)或者AVERROR_EOF
            while (ret >= 0) {
                ret = avcodec_receive_frame(pAudioAVCodecCtx, pFrame);
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                    usleep(sleepDelta);
                    continue;
                } else if (ret < 0) {
                    LOGE("%s Error receive decoding audio frame ret=%d", __FUNCTION__, ret);
                    usleep(sleepDelta);
                    continue;
                }
 
                // 解碼固定為 AV_SAMPLE_FMT_FLTP,需要轉(zhuǎn)碼為 AV_SAMPLE_FMT_S16
                // 數(shù)據(jù)都裝在 data[0] 中,而大小則為 linesize[0](實(shí)際發(fā)現(xiàn)此處大小并不對,大小計(jì)算見下面)
                int planeNum = 1;
                int dataLen[planeNum];
                /*dataLen[0] = pFrame->nb_samples *
                             av_get_bytes_per_sample((enum AVSampleFormat) (pFrame->format));*/
                // 重采樣轉(zhuǎn)為 S16
                uint8_t *pcmOut[1] = {nullptr};
                pcmOut[0] = pPCM16OutBuf;
                // 音頻重采樣
                int number = swr_convert(
                        pSwrContext,
                        pcmOut,
                        pFrame->nb_samples,
                        (const uint8_t **) pFrame->data,
                        pFrame->nb_samples
                );
 
                if (number != pFrame->nb_samples) {
                    LOGE("%s swr_convert appear problem number=%d", __FUNCTION__, number);
                } else {
                    dataLen[0] = pFrame->nb_samples *
                                 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
                    pthread_mutex_lock(pFrameDataCallbackMutex);
                    if (pFrameDataCallback != nullptr) {
                        //LOGD("%s receive the decode frame size=%d nb_samples=%d", __FUNCTION__, dataLen[0], pFrame->nb_samples);
                        pFrameDataCallback->onDataArrived(StreamType::AUDIO,
                                                          (long long) pFrame->pts,
                                                          (char **) pcmOut,
                                                          dataLen,
                                                          planeNum,
                                                          pAudioAVCodecCtx->channels,
                                                          pAudioAVCodecCtx->sample_rate,
                                                          -1,
                                                          -1);
                    }
                    pthread_mutex_unlock(pFrameDataCallbackMutex);
 
                }
 
 
                av_frame_unref(pFrame);
            }
        }
 
    }
}

?文章來源地址http://www.zghlxwxcb.cn/news/detail-500340.html

到了這里,關(guān)于FFmpeg 解碼 AAC 格式的音頻的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

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

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

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

    2024年02月04日
    瀏覽(25)
  • 使用FFMPEG分離mp4/flv文件中的264視頻和aac音頻

    使用FFMPEG分離mp4/flv文件中的264視頻和aac音頻

    ffmpeg 4.4 一個(gè)MP4或flv格式的視頻文件 大致分為以下幾個(gè)簡單步驟: 1.使用avformat_open_input 函數(shù)打開文件并初始化結(jié)構(gòu)AVFormatContext 2.查找是否存在音頻和視頻信息 3.構(gòu)建一個(gè)h264_mp4toannexb比特流的過濾器,用來給視頻avpaket包添加頭信息 4.打開2個(gè)輸出文件(音頻, 視頻) 5.循環(huán)讀

    2024年02月15日
    瀏覽(18)
  • ffmpeg學(xué)習(xí)之音頻解碼數(shù)據(jù)

    ffmpeg學(xué)習(xí)之音頻解碼數(shù)據(jù)

    音頻數(shù)據(jù)經(jīng)過解碼后會被保存為,pcm數(shù)據(jù)格式。而對應(yīng)的處理流程如下所示。 avcodec_find_encoder()? avcodec_find_encoder_by_name()? avcodec_alloc_context3()? ?設(shè)置對應(yīng)音頻編碼的數(shù)據(jù)類型 設(shè)置編碼的frame的相關(guān)參數(shù) 整個(gè)代碼:

    2024年02月16日
    瀏覽(19)
  • Android FFmpeg 解碼 OpenSL ES 播放音頻

    ?在Android開發(fā)中,OpenSLES(Open Sound Library for Embedded Systems)是一個(gè) C/C++ 音頻庫,提供了底層的音頻功能和處理接口。它是 Android 平臺上用于實(shí)現(xiàn)低延遲和高性能音頻功能的一種選擇。 本文的主線任務(wù)是描述 一個(gè)媒體文件通過 FFmpeg 解碼 后用 OpenSL ES 播放 音頻的過程 因?yàn)榇a

    2024年02月08日
    瀏覽(34)
  • FFmpeg音頻解碼流程詳解及簡單demo參考

    FFmpeg音頻解碼流程詳解及簡單demo參考

    ????????本文主要講解FFmpeg的音頻解碼具體流程,API使用。最后再以一個(gè)非常簡單的demo演示將一個(gè)mp3格式的音頻文件解碼為原始數(shù)據(jù)pcm文件。?本文主要基于FFmpeg音頻解碼新接口。 ???API接口簡單大體講解如下: ????????這一步是ffmpeg的任何程序的第一步都是需要先注

    2023年04月08日
    瀏覽(70)
  • 深入淺出:FFmpeg 音頻解碼與處理AVFrame全解析

    深入淺出:FFmpeg 音頻解碼與處理AVFrame全解析

    FFmpeg 是一個(gè)開源的音視頻處理軟件,它包含了一系列的庫和程序,用于處理音頻、視頻和其他多媒體數(shù)據(jù)。FFmpeg 的名字來源于 “Fast Forward MPEG”,其中 MPEG 是一種常見的音視頻編碼標(biāo)準(zhǔn)。 FFmpeg 項(xiàng)目于 2000 年由 Fabrice Bellard 啟動,他是 QEMU(一種開源的計(jì)算機(jī)模擬器和虛擬機(jī)

    2024年02月04日
    瀏覽(41)
  • Qt-FFmpeg開發(fā)-音頻解碼為PCM文件(9)

    Qt-FFmpeg開發(fā)-音頻解碼為PCM文件(9)

    目錄 音視頻/FFmpeg #Qt Qt-FFmpeg開發(fā)-使用libavcodec API的音頻解碼示例(MP3轉(zhuǎn)pcm) 1、概述 2、實(shí)現(xiàn)效果 3、主要代碼 4、完整源代碼 更多精彩內(nèi)容 ??個(gè)人內(nèi)容分類匯總 ?? ??音視頻開發(fā) ?? 最近研究了一下FFmpeg開發(fā),功能實(shí)在是太強(qiáng)大了,網(wǎng)上ffmpeg3、4的文章還是很多的,但是學(xué)

    2023年04月08日
    瀏覽(48)
  • ExoPlayer(AndroidX Media3) 擴(kuò)展ffmpeg實(shí)現(xiàn)音頻軟解碼

    ExoPlayer(AndroidX Media3) 擴(kuò)展ffmpeg實(shí)現(xiàn)音頻軟解碼

    1.Ubuntu 20.04.4 LTS 2.AndroidNDK版本r26C 3.AndroidStudio 2023.1.1(配置好SDK和JDK 17.0.10) 4.ffmpeg6.0源碼 5.ExoPlayer源碼,AndroidX Media release分支版本 目前官方已廢棄Exopler2,代碼已經(jīng)遷移到AndroidX Media,下載完成設(shè)置FFMPEG_MODULE_PATH變量 1. git clone https://github.com/androidx/media 2. cd media FFMPEG_MODULE_PATH

    2024年04月12日
    瀏覽(162)
  • 【FFmpeg】ffmpeg 命令行參數(shù) ⑦ ( 使用 FFmpeg 提取 PCM 音頻數(shù)據(jù) | PCM 音頻格式 | 提取 PCM 音頻格式常用參數(shù) | 查詢文檔方法 )

    【FFmpeg】ffmpeg 命令行參數(shù) ⑦ ( 使用 FFmpeg 提取 PCM 音頻數(shù)據(jù) | PCM 音頻格式 | 提取 PCM 音頻格式常用參數(shù) | 查詢文檔方法 )

    PCM 全稱 \\\" Pulse Code Modulation \\\" , 脈沖編碼調(diào)制 , 該 音頻數(shù)據(jù) 是未經(jīng)壓縮的 采樣裸數(shù)據(jù) , 只有 知道該數(shù)據(jù)的 采樣率 / 采樣位數(shù) / 通道數(shù) 才能將該音頻數(shù)據(jù)播放出來 ; PCM 數(shù)據(jù)是 最原始的音頻數(shù)據(jù) , 音頻內(nèi)容完全無損 , 但是 PCM 數(shù)據(jù)體積龐大 , 對 PCM 音頻數(shù)據(jù)壓縮 分為 無損壓縮

    2024年04月11日
    瀏覽(31)
  • python使用ffmpeg來制作音頻格式轉(zhuǎn)換工具(優(yōu)化版)

    python使用ffmpeg來制作音頻格式轉(zhuǎn)換工具(優(yōu)化版)

    簡介:一個(gè)使用python加上ffmpeg模塊來進(jìn)行音頻格式轉(zhuǎn)換的工具。 日志: 20231030:第一版,設(shè)置了簡單的UI布局和配色,實(shí)現(xiàn)音頻轉(zhuǎn)為Mp3、AAC、wav、flac四種格式??山馕鲆纛l并顯示信息,可設(shè)置轉(zhuǎn)換后的保存路徑 UI界面: 編程平臺:visual studio code 編程語言:python 3.12.0 模塊:

    2024年02月06日
    瀏覽(38)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包