這篇文章將為大家詳細(xì)講解有關(guān)Qt如何實(shí)現(xiàn)ffmpeg音視頻同步,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
在綠園等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作按需定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),全網(wǎng)整合營(yíng)銷推廣,外貿(mào)網(wǎng)站制作,綠園網(wǎng)站建設(shè)費(fèi)用合理。
用ffmpeg來(lái)做音視頻同步,個(gè)人認(rèn)為這個(gè)是ffmpeg基礎(chǔ)處理中最難的一個(gè),無(wú)數(shù)人就卡在這里,怎么也不準(zhǔn),本人也是嘗試過(guò)網(wǎng)上各種demo,基本上都是渣渣,要么僅僅支持極其少量的視頻文件比如收到的數(shù)據(jù)包是一幀視頻一幀音頻的,要么根本沒(méi)法同步歪七八糟的,要么進(jìn)度跳過(guò)去直接蹦蹦蹦崩潰的,其實(shí)最完美的音視頻同步處理demo就是ffplay,我親測(cè)過(guò)幾十種各種各樣的音視頻本地文件,數(shù)十種視頻流文件,都是非常完美,當(dāng)然啦這是親生的啦,不完美還玩?zhèn)€屁。
如果僅僅是播放視頻流(不帶音頻流),可能不需要音視頻同步,所以最開始只做rtsp視頻流播放的時(shí)候根本沒(méi)有考慮同步的問(wèn)題,因?yàn)闆](méi)遇到也不需要,等到后期發(fā)現(xiàn)各種rtmp、http、m3u8這種視頻流的時(shí)候,問(wèn)題大了去了,他是hls格式的視頻流文件一次性過(guò)來(lái)的,一個(gè)個(gè)小視頻文件過(guò)來(lái)的,如果沒(méi)有同步的話,意味著突然之間刷刷刷的圖片過(guò)去很多,下一次來(lái)的又是刷刷的,這就需要自己計(jì)算同步了,上次接收到的數(shù)據(jù)包放入隊(duì)列,到了需要顯示的時(shí)候就顯示。
常用的音視頻同步方法:
通過(guò)fps來(lái)控制,fps表示一秒鐘播放多少幀,比如25幀,可以自行計(jì)算一幀解碼用掉的時(shí)間,一幀占用(1000/25=40毫秒),通過(guò)延時(shí)來(lái)處理,這其實(shí)是最渣渣的辦法。
記住開始解碼的時(shí)間startTime,通過(guò)av_rescale_q計(jì)算pts時(shí)間,兩者的差值就是需要延時(shí)的時(shí)間,調(diào)用av_usleep來(lái)延時(shí),這種只有部分文件正常,很多時(shí)候不正常。
音頻同步到視頻,視頻時(shí)鐘作為主時(shí)鐘,沒(méi)試過(guò),網(wǎng)上很多人說(shuō)這個(gè)辦法不好。
視頻同步到音頻,音頻時(shí)鐘作為主時(shí)鐘,沒(méi)試過(guò),據(jù)說(shuō)大部分人采用的此辦法。
音視頻同步到外部時(shí)鐘,外部時(shí)鐘作為主時(shí)鐘,最終采用的辦法,容易理解互不干擾,各自按照外部時(shí)鐘去同步自己。
ffplay自身內(nèi)置了三種同步策略,可以通過(guò)參數(shù)來(lái)控制采用何種策略,默認(rèn)是視頻同步到音頻。
多線程實(shí)時(shí)播放視頻流+本地視頻+USB攝像頭等。
支持windows+linux+mac,支持ffmpeg3和ffmpeg4,支持32位和64位。
多線程顯示圖像,不卡主界面。
自動(dòng)重連網(wǎng)絡(luò)攝像頭。
可設(shè)置邊框大小即偏移量和邊框顏色。
可設(shè)置是否繪制OSD標(biāo)簽即標(biāo)簽文本或圖片和標(biāo)簽位置。
可設(shè)置兩種OSD位置和風(fēng)格。
可設(shè)置是否保存到文件以及文件名。
可直接拖曳文件到ffmpegwidget控件播放。
支持h365視頻流+rtmp等常見(jiàn)視頻流。
可暫停播放和繼續(xù)播放。
支持存儲(chǔ)單個(gè)視頻文件和定時(shí)存儲(chǔ)視頻文件。
自定義頂部懸浮條,發(fā)送單擊信號(hào)通知,可設(shè)置是否啟用。
可設(shè)置畫面拉伸填充或者等比例填充。
可設(shè)置解碼是速度優(yōu)先、質(zhì)量?jī)?yōu)先、均衡處理。
可對(duì)視頻進(jìn)行截圖(原始圖片)和截屏。
錄像文件存儲(chǔ)支持裸流和MP4文件。
音視頻完美同步,采用外部時(shí)鐘同步策略。
支持seek定位播放位置。
支持qsv、dxva2、d3d11va等硬解碼。
支持opengl繪制視頻數(shù)據(jù),極低CPU占用。
支持安卓和嵌入式linux,交叉編譯即可。

void FFmpegSync::run()
{
reset();
while (!stopped) {
//暫停狀態(tài)或者隊(duì)列中沒(méi)有幀則不處理
if (!thread->isPause && packets.count() > 0) {
mutex.lock();
AVPacket *packet = packets.first();
mutex.unlock();
//h364的裸流文件同步有問(wèn)題,獲取不到pts和dts,暫時(shí)用最蠢的辦法延時(shí)解決
if (thread->formatName == "h364") {
int sleepTime = (1000 / thread->videoFps) - 5;
msleep(sleepTime);
}
//計(jì)算當(dāng)前幀顯示時(shí)間 外部時(shí)鐘同步
ptsTime = getPtsTime(thread->formatCtx, packet);
if (!this->checkPtsTime()) {
msleep(1);
continue;
}
//顯示當(dāng)前的播放進(jìn)度
checkShowTime();
//0-表示音頻 1-表示視頻
if (type == 0) {
thread->decodeAudio(packet);
} else if (type == 1) {
thread->decodeVideo(packet);
}
//釋放資源并移除
thread->free(packet);
mutex.lock();
packets.removeFirst();
mutex.unlock();
}
msleep(1);
}
clear();
stopped = false;
}
bool FFmpegSync::checkPtsTime()
{
bool ok = false;
if (ptsTime > 0) {
if (ptsTime > offsetTime + 100000) {
bufferTime = ptsTime - offsetTime + 100000;
}
int offset = (type == 0 ? 1000 : 5000);
offsetTime = av_gettime() - startTime + bufferTime;
if ((offsetTime <= ptsTime && ptsTime - offsetTime <= offset) || (offsetTime > ptsTime)) {
ok = true;
}
} else {
ok = true;
}
return ok;
}關(guān)于“Qt如何實(shí)現(xiàn)ffmpeg音視頻同步”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
當(dāng)前題目:Qt如何實(shí)現(xiàn)ffmpeg音視頻同步
網(wǎng)頁(yè)路徑:http://chinadenli.net/article28/jpsgcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、企業(yè)建站、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站排名、面包屑導(dǎo)航、小程序開發(fā)
聲明:本網(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í)需注明來(lái)源: 創(chuàng)新互聯(lián)