Ffmpeg音頻轉碼 卡頓(MP2轉AAC)

        最好經手一個小的功能將mp2實時流轉成AAC併發布成rtmp音頻流,自己不是很難的一個需求,php

一個晚上就能將功能開發好。功能開發完畢後,找來一音頻文件利用Ffmpeg命令將音視頻文件推成併發

實時udp格式音頻流,具體的推送命令是:測試

ffmpeg.exe -r -i F:\test.mp2 -acodec copy -f mp2 udp://127.0.0.1:1234

  測試程序以udp://127.0.0.1:1234爲輸入源,rtmp://127.0.0.1/live/stream爲輸出流。從輸入到輸出編碼

通過解碼、過濾器、編碼最後封裝,這些基本的原理及代碼以前的博文已經寫過,也有相關的視頻進行spa

講述,本文再也不贅述。線程

       測試程序運行後,經過ffplay播放輸出音頻流地址rtmp://127.0.0.1/live/stream,開始一分鐘左右能夠code

音頻播放正常,過了一分鐘後聲音出現卡頓。開始覺得是推送的速度問題,對原有的程序作了些改進:將視頻

讀包一單獨線程,編解碼及發送單獨一線程。修改程序後,卡頓的現象還在,顯然沒有找到問題。接下來blog

考慮多是讀udp數據出了問題,增長各類UDP參數設置從新再測試,卡頓的現象依然在。通過多番折騰教程

發現問題出在filter上:filter SRC端每Push一次,SINK端須要一直讀取Frame直到讀取方法返回負值。源

代碼也是這麼寫的,不當心埋了Bug,實際執行的狀況是每次SINK端只讀一次即返回。正常的代碼片斷以下

void Transcode(std::shared_ptr<AVPacket> packet)
{
    int gotOutput = 0;
    AVFrame *pSrcAudioFrame = av_frame_alloc();
    bool  decodeResult = decodeAudio(packet.get(),pSrcAudioFrame);
    if(decodeResult)
    {
        while (true)
        {
            AVFrame *filtFrame  = av_frame_alloc();        
            int ret = av_buffersink_get_frame_flags(buffersinkCtx, filtFrame, 0);
            if(ret < 0)
            {
                av_frame_free(&filtFrame);
                break;
            }
            std::shared_ptr<AVPacket> pkt(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p); });
            av_init_packet(pkt.get());
            pkt->data = NULL;
            pkt->size = 0;

            ret = avcodec_encode_audio2(encodeContext, pkt.get(), filtFrame, &gotOutput);
            if (ret >= 0 && gotOutput)
            {
                WritePacket(pkt);
            }
            av_frame_free(&filtFrame);    
        }
    }
    av_frame_free(&pSrcAudioFrame);
}

 

如需交流可加QQ羣766718184 或者QQ3501870

 博主提供Ffmpeg、GB28181視頻教程

播放地址: http://www.iqiyi.com/u/1426749687

源碼及Demo下載地址:http://www.chungen90.com/index.php?m=text&a=index&classify_id=207視頻下載地址:      http://www.chungen90.com/index.php?m=text&a=index&classify_id=208

相關文章
相關標籤/搜索