您好,登錄后才能下訂單哦!
這篇文章主要介紹“Qt fmpeg保存裸流怎么實(shí)現(xiàn)”,在日常操作中,相信很多人在Qt fmpeg保存裸流怎么實(shí)現(xiàn)問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Qt fmpeg保存裸流怎么實(shí)現(xiàn)”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
最開始做的ffmpeg保存視頻文件,就是直接保存的裸流數(shù)據(jù),裸流數(shù)據(jù)一般是H264格式的數(shù)據(jù),這種數(shù)據(jù)文件可以用部分播放器播放,由于不是標(biāo)準(zhǔn)的格式,很多播放器其實(shí)不支持的,需要安裝對(duì)應(yīng)的解碼器才行。后面發(fā)現(xiàn)安裝好K-Lite解碼器后,連系統(tǒng)自帶的播放器都可以正常播放H264視頻流文件,而且如果同步保存了同名文件的aac音頻文件放在同目錄下的話,聲音都能正常同步播放,可能這是播放器做的處理吧。
直接保存裸流基本上沒有什么難度,大致流程就是先打開文件,然后在循環(huán)解碼的地方直接將解碼好的數(shù)據(jù)write到文件即可,如果采用的是定時(shí)存儲(chǔ)的話,那就開個(gè)定時(shí)器,到了點(diǎn)就先關(guān)閉文件,然后重新打開新的名字的文件,這里要注意的是,rtmp視頻流的話,需要添加pps sps等信息,所以在每幀寫入文件前,要先用AVBitStreamFilter采用h364_mp4toannexb處理下才行。
多線程實(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等常見視頻流。
可暫停播放和繼續(xù)播放。
支持存儲(chǔ)單個(gè)視頻文件和定時(shí)存儲(chǔ)視頻文件。
自定義頂部懸浮條,發(fā)送單擊信號(hào)通知,可設(shè)置是否啟用。
可設(shè)置畫面拉伸填充或者等比例填充。
可設(shè)置解碼是速度優(yōu)先、質(zhì)量?jī)?yōu)先、均衡處理。
可對(duì)視頻進(jìn)行截圖(原始圖片)和截屏。
錄像文件存儲(chǔ)支持裸流和MP4文件。
支持qsv、dxva2、d3d11va等硬解碼。
支持opengl繪制視頻數(shù)據(jù),極低CPU占用。
支持嵌入式linux,交叉編譯即可。
void FFmpegThread::initSave() { if (!saveFile) { return; } //如果存儲(chǔ)間隔大于0說明需要定時(shí)存儲(chǔ) if (saveInterval > 0) { QString dirName = QString("%1/%2").arg(savePath).arg(QDATE); newDir(dirName); fileName = QString("%1/%2_%3.mp4").arg(dirName).arg(fileFlag).arg(STRDATETIME); emit sig_startSave(); } if (saveMp4) { saveVideoMp4(fileName); } else { saveVideoH264(fileName); } } void FFmpegThread::startSave() { timerSave->start(saveInterval * 1000); } void FFmpegThread::stopSave() { //停止存儲(chǔ)文件以及存儲(chǔ)定時(shí)器 closeVideo(); if (timerSave->isActive()) { timerSave->stop(); } } void FFmpegThread::saveVideo() { if (!saveFile) { return; } //重新設(shè)置文件名稱 QString dirName = QString("%1/%2").arg(savePath).arg(QDATE); newDir(dirName); fileName = QString("%1/%2_%3.mp4").arg(dirName).arg(fileFlag).arg(STRDATETIME); if (saveMp4) { saveVideoMp4(fileName); } else { saveVideoH264(fileName); } } void FFmpegThread::closeVideo() { if (!saveFile) { return; } if (saveMp4) { if (formatOut != NULL) { //寫入結(jié)束標(biāo)識(shí) av_write_trailer(formatOut); avcodec_close(formatOut->streams[0]->codec); av_freep(&formatOut->streams[0]->codec); av_freep(&formatOut->streams[0]); avio_close(formatOut->pb); av_free(formatOut); initSaveOk = false; formatOut = NULL; } } else { if (fileVideo.isOpen()) { fileVideo.close(); } if (fileAudio.isOpen()) { fileAudio.close(); } } } void FFmpegThread::saveVideoH264(const QString &fileName) { QMutexLocker locker(&mutex); closeVideo(); if (videoStreamIndex >= 0) { fileVideo.setFileName(fileName); fileVideo.open(QFile::WriteOnly); } //存在音頻文件則同時(shí)保存音頻文件 if (audioStreamIndex >= 0 && playAudio) { QString audioName = fileName; audioName = audioName.replace(QFileInfo(audioName).suffix(), "aac"); fileAudio.setFileName(audioName); fileAudio.open(QFile::WriteOnly); } }
到此,關(guān)于“Qt fmpeg保存裸流怎么實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。