内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

FFMPEG音頻封裝編碼

FFMPEG 4.0 for Android 準(zhǔn)備工作

創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比二道江網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式二道江網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋二道江地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。

FFMPEG4.0 音頻解碼解封裝

下面的函數(shù)方法基于最新的FFMPEG 4.0(4.X):

本文主要講如何從一個(gè)pcm文件中拿到原始數(shù)據(jù),用原始數(shù)據(jù)生成一個(gè)我們需要的音頻格式文件,結(jié)合上一篇的FFMPEG4.0 音頻解碼解封裝,你將能夠?qū)崿F(xiàn)音頻格式轉(zhuǎn)換.

從PCM文件中讀取數(shù)據(jù)生成MP3格式文件。
一、初始化輸出

 AVFormatContext *fmt_ctx;
    int ret = avformat_alloc_output_context2(&fmt_ctx,NULL,NULL,out_file);
 ret = avio_open(&fmt_ctx->pb,out_file,AVIO_FLAG_WRITE);

下面的變量不是必須的,里面存了輸出格式的信息,包含生成的音視頻編碼格式。

AVOutputFormat *ofmt;
ofmt = fmt_ctx->oformat;

二、準(zhǔn)備編碼器、流,設(shè)置編碼參數(shù)

encodec = avcodec_find_encoder(AV_CODEC_ID_MP3);//可通過ofmt->audio_codec得到格式
st = avformat_new_stream(fmt_ctx,encodec);
encodec_ctx = avcodec_alloc_context3(encodec);

encodec_ctx->sample_rate = 44100;
encodec_ctx->bit_rate = 64000;
encodec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
encodec_ctx->channel_layout = AV_CH_LAYOUT_STEREO;
encodec_ctx->channels = av_get_channel_layout_nb_channels(encodec_ctx->channel_layout);

三、打開編碼器,得到一幀數(shù)據(jù)的采樣數(shù)

ret = avcodec_open2(encodec_ctx,encodec,NULL);
int encode_nb_sample = encodec_ctx->frame_size;

四、初始化frame與packet

    frame = av_frame_alloc();
    pkt = av_packet_alloc();
    frame->nb_samples = encode_nb_sample;
    frame->format = encodec_ctx->sample_fmt;
    frame->channel_layout = encodec_ctx->channel_layout;

    //frame.data 需要申請(qǐng)的字節(jié)數(shù)
    int size = av_samples_get_buffer_size(NULL,encodec_ctx->channels,encode_nb_sample,encodec_ctx->sample_fmt,1);
    uint8_t *frame_buf = (uint8_t *) av_malloc(size);
avcodec_fill_audio_frame(frame,encodec_ctx->channels,encodec_ctx->sample_fmt,frame_buf,size,1);

上面的給frame內(nèi)data分配內(nèi)存的方法可以通過調(diào)用如下方法達(dá)到(sample內(nèi)方法):
ret = av_frame_get_buffer(frame, 0);

重采樣的數(shù)據(jù)從pcm文件中讀取,這里根據(jù)生成的一幀數(shù)據(jù)的樣本數(shù)計(jì)算得出轉(zhuǎn)換一幀數(shù)據(jù)需要讀取的樣本數(shù)(pcm樣本的采樣率是44100)(網(wǎng)絡(luò)上的示例這里都是錯(cuò)的!他們的例子在不改變采樣率時(shí)沒問題,一改變就有播放時(shí)間變化):
int in_nb_sample = av_rescale_rnd(frame->nb_samples,44100,encodec_ctx->sample_rate,AV_ROUND_UP);

計(jì)算轉(zhuǎn)換需要的一幀數(shù)據(jù)buf大?。?/p>

int readSize = in_nb_sample * av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO) * av_get_bytes_per_sample(in_fmt);
char *read_buf = (char*)malloc(readSize);

五、復(fù)制參數(shù)、寫頭信息

    avcodec_parameters_from_context(st->codecpar,encodec_ctx);
    avformat_write_header(fmt_ctx,NULL);

六、設(shè)置重采樣參數(shù)

    swc = swr_alloc();
    av_opt_set_int(swc,"in_channel_layout",AV_CH_LAYOUT_STEREO,0);
    av_opt_set_int(swc,"in_sample_rate",in_sample_rate,0);
    av_opt_set_sample_fmt(swc,"in_sample_fmt",in_fmt,0);

    av_opt_set_int(swc,"out_channel_layout",encodec_ctx->channel_layout,0);
    av_opt_set_int(swc,"out_sample_rate",encodec_ctx->sample_rate,0);
    av_opt_set_sample_fmt(swc,"out_sample_fmt",encodec_ctx->sample_fmt,0);
ret = swr_init(swc);

七、編碼(下面是一幀編碼,實(shí)際編碼過程應(yīng)該是反復(fù)循環(huán)下面的行為,直到文件讀完)
1.讀取pcm文件,準(zhǔn)備重采樣的數(shù)組指針,有些做法是利用ffmpeg的接口生成frame,對(duì)frame進(jìn)行data內(nèi)存分配,實(shí)質(zhì)都是一樣:

        if (fread(read_buf, 1, readSize, infile) < 0) {
            printf("文件讀取錯(cuò)誤!\n");
            return -1;
        } else if (feof(infile)) {
            break;
        }
        //重采樣源數(shù)據(jù)
        const uint8_t *indata[AV_NUM_DATA_POINTERS] = {0};
        indata[0] = (uint8_t *) read_buf;

2.重采樣,設(shè)置pts

        int len = swr_convert(swc, frame->data, frame->nb_samples,indata, in_nb_sample);
        LOGV("len = %d\n",len);
        frame->pts = apts;
        apts += av_rescale_q(len,(AVRational){1,encodec_ctx->sample_rate},encodec_ctx->time_base);

3.編碼(也許不用while循環(huán)。注意文件讀完后還需呀send一次,frame傳NULL,主要為了flush編碼器)

ret = avcodec_send_frame(encodec_ctx, frame);

        while(ret >= 0) {
            LOGV("receiver\n");
            ret = avcodec_receive_packet(encodec_ctx, pkt);
            if (ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "%s,ret = %d\n", "avcodec_receive_packet!error ",ret);
                break;
            }
            pkt->stream_index = st->index;
            av_log(NULL, AV_LOG_DEBUG, "第%d幀\n", i);
            pkt->pts = av_rescale_q(pkt->pts, encodec_ctx->time_base, st->time_base);
            pkt->dts = av_rescale_q(pkt->dts, encodec_ctx->time_base, st->time_base);
            pkt->duration = av_rescale_q(pkt->duration, encodec_ctx->time_base, st->time_base);
            LOGV("duration = %d,dts=%d,pts=%d\n",pkt->duration,pkt->dts,pkt->pts);
            ret = av_write_frame(fmt_ctx, pkt);
            if (ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "av_write_frame error!");
            }
            av_packet_unref(pkt);
        }

4.寫結(jié)束符
av_write_trailer(fmt_ctx);

網(wǎng)站欄目:FFMPEG音頻封裝編碼
鏈接分享:http://www.rwnh.cn/article38/phodsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、網(wǎng)站制作、微信公眾號(hào)、Google、網(wǎng)站維護(hù)、用戶體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計(jì)公司
错那县| 麟游县| 乐清市| 台中县| 营山县| 孝义市| 陈巴尔虎旗| 台州市| 桐柏县| 分宜县| 巴东县| 连南| 荔波县| 康保县| 吉安市| 合山市| 林周县| 襄城县| 类乌齐县| 肇州县| 沾化县| 武隆县| 凤冈县| 新和县| 柳河县| 宣城市| 会宁县| 洞头县| 柳江县| 奇台县| 友谊县| 宿迁市| 门头沟区| 舟山市| 定安县| 射洪县| 彭泽县| 麟游县| 昌宁县| 永春县| 邹城市|