Qt+FFmpeg網絡視頻流播放

  • init?函數用于初始化 FFmpeg,包括設置參數、打開輸入、初始化視頻和音頻等。
  • initOption?函數用于設置 FFmpeg 的參數選項。
bool FFmpegThread::init()
{if (url.isEmpty()) {return false;}//判斷該攝像機是否能聯通if (checkConn && isRtsp) {if (!checkUrl(url, checkTime)) {return false;}}//啟動計時QElapsedTimer time;time.start();//初始化參數this->initOption();//初始化輸入if (!initInput()) {return false;}//初始化視頻if (!initVideo()) {return false;}//初始化音頻if (!initAudio()) {return false;}//初始化其他this->initOther();QString useTime = QString::number((float)time.elapsed() / 1000, 'f', 3);qDebug() << TIMEMS << fileFlag << QString("初始化完 -> 用時: %1 秒  地址: %2").arg(useTime).arg(url);return true;
}bool FFmpegThread::initInput()
{//實例化格式處理上下文formatCtx = avformat_alloc_context();//設置超時回調,有些不存在的地址或者網絡不好的情況下要卡很久formatCtx->interrupt_callback.callback = AVInterruptCallBackFun;formatCtx->interrupt_callback.opaque = this;//必須要有tryOpen標志位來控制超時回調,由他來控制是否繼續阻塞tryOpen = false;tryRead = true;//先判斷是否是本地設備(video=設備名字符串),打開的方式不一樣QByteArray urlData = url.toUtf8();AVInputFormat *ifmt = nullptr;if (isUsbCamera) {
#if defined(Q_OS_WIN)ifmt = av_find_input_format("dshow");
#elif defined(Q_OS_LINUX)//ifmt = av_find_input_format("v4l2");ifmt = av_find_input_format("video4linux2");
#elif defined(Q_OS_MAC)ifmt = av_find_input_format("avfoundation");
#endif}//設置 avformat_open_input 非阻塞默認阻塞 不推薦這樣設置推薦采用回調//formatCtx->flags |= AVFMT_FLAG_NONBLOCK;int result = avformat_open_input(&formatCtx, urlData.data(), ifmt, &options);tryOpen = true;if (result < 0) {qDebug() << TIMEMS << fileFlag << "open input error" << getError(result) << url;emit ffmpegDecodeSignal(fileFlag + " open input error " + getError(result));return false;}//釋放設置參數if (options != nullptr) {av_dict_free(&options);}//根據自己項目需要開啟下面部分代碼加快視頻流打開速度
#if 0//接口內部讀取的最大數據量,從源文件中讀取的最大字節數//默認值5000000導致這里卡很久最耗時,可以調小來加快打開速度formatCtx->probesize = 50000;//從文件中讀取的最大時長,單位為 AV_TIME_BASE unitsformatCtx->max_analyze_duration = 5 * AV_TIME_BASE;//內部讀取的數據包不放入緩沖區//formatCtx->flags |= AVFMT_FLAG_NOBUFFER;
#endif//獲取流信息result = avformat_find_stream_info(formatCtx, nullptr);if (result < 0) {qDebug() << TIMEMS << fileFlag << "find stream info error" << getError(result);emit ffmpegDecodeSignal(fileFlag + " find stream info error " + getError(result));return false;}return true;
}
  • run?函數是線程的運行函數,用于循環讀取音視頻數據包,并進行解碼和播放。
void FFmpegThread::run()
{//記住開始解碼的時間用于用視頻同步startTime = av_gettime();while (!stopped) {//根據標志位執行初始化操作if (isPlay) {if (init()) {//這里也需要更新下最后的時間lastTime = QDateTime::currentDateTime();initSave();//初始化完成變量放在這里,繪制那邊判斷這個變量是否完成才需要開始繪制if (videoIndex >= 0) {isInit = true;}emit receivePlayStart();} else {emit receivePlayError();break;}isPlay = false;continue;}//處理暫停 本地文件才會執行到這里 視頻流的暫停在其他地方處理if (isPause) {//這里需要假設正常,暫停期間繼續更新時間lastTime = QDateTime::currentDateTime();msleep(1);continue;}//QMutexLocker locker(&mutex);//解碼隊列中幀數過多暫停讀取 下面這兩個值可以自行調整 表示緩存的大小if (videoSync->getPacketCount() >= 100 || audioSync->getPacketCount() >= 100) {msleep(1);continue;}//必須要有tryRead標志位來控制超時回調,由他來控制是否繼續阻塞tryRead = false;//下面還有個可以改進的地方就是如果是視頻流暫停情況下只要保證 av_read_frame 一直讀取就行無需解碼處理frameFinish = av_read_frame(formatCtx, packet);//qDebug() << TIMEMS << fileFlag << "av_read_frame" << frameFinish;if (frameFinish >= 0) {tryRead = true;//更新最后的解碼時間 錯誤計數清零errorCount = 0;lastTime = QDateTime::currentDateTime();//判斷當前包是視頻還是音頻int index = packet->stream_index;if (index == videoIndex) {//qDebug() << TIMEMS << fileFlag << "videoPts" << qint64(getPtsTime(formatCtx, packet) / 1000) << packet->pts << packet->dts;decodeVideo(packet);} else if (index == audioIndex) {//qDebug() << TIMEMS << fileFlag << "audioPts" << qint64(getPtsTime(formatCtx, packet) / 1000) << packet->pts << packet->dts;decodeAudio(packet);}} else if (!isRtsp) {//如果不是視頻流則說明是視頻文件播放完畢if (frameFinish == AVERROR_EOF) {//當同步隊列中的數量為0才需要跳出 表示解碼處理完成if (videoSync->getPacketCount() == 0 && audioSync->getPacketCount() == 0) {//循環播放則重新設置播放位置,在這里執行的代碼可以做到無縫切換循環播放if (playRepeat) {this->position = 0;videoSync->reset();audioSync->reset();videoSync->start();audioSync->start();QMetaObject::invokeMethod(this, "setPosition", Q_ARG(qint64, position));qDebug() << TIMEMS << fileFlag << "repeat" << url;} else {break;}}}} else {//下面這種情況在攝像機掉線后出現,如果想要快速識別這里直接break即可//一般3秒鐘才會執行一次錯誤累加errorCount++;//qDebug() << TIMEMS << fileFlag << "errorCount" << errorCount << url;if (errorCount >= 3) {errorCount = 0;break;}}free(packet);msleep(2);}QMetaObject::invokeMethod(this, "stopSave");//線程結束后釋放資源msleep(100);free();freeAudioDevice();emit receivePlayFinsh();//qDebug() << TIMEMS << fileFlag << "stop ffmpeg thread" << url;
}

以上是部分代碼,這個類的主要目的是使用 FFmpeg 庫來處理多媒體數據,包括視頻和音頻的解碼、播放、保存等操作。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88671.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88671.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88671.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【SpringBoot】Spring Boot 高并發優化終極指南,涵蓋線程模型、JVM 調優、數據庫訪問、緩存策略等 15+ 核心模塊

Spring Boot 高并發優化終極指南&#xff0c;涵蓋線程模型、JVM 調優、數據庫訪問、緩存策略等 15 核心模塊一、線程模型深度調優&#xff08;核心瓶頸突破&#xff09;1. Tomcat 線程池原子級配置2. 異步任務線程池隔離策略二、JVM 層終極調參&#xff08;G1GC 深度優化&#…

linux(CentOS-7-x86_64:NAT模式下解決yum無法使用:更新yum源的詳細操作步驟2025)

目錄 一、CentOS-7-x86_64的NAT模式下解決yum無法使用。&#xff08;更新可用的yum&#xff09; &#xff08;1&#xff09;首先保證能夠ping通&#xff0c;也就是NAT模式下虛擬機有網絡。 &#xff08;2&#xff09;錯誤&#xff1a;無法使用yum。比如我現在無法yum search if…

C++11的整理筆記

Lambda 表達式Lambda 表達式是 C11 引入的一種強大的功能&#xff0c;它允許你在代碼中直接定義匿名函數對象。Lambda 表達式可以捕獲上下文中的變量&#xff0c;并在需要時使用它們。它們通常用于簡化代碼&#xff0c;尤其是那些需要傳遞函數對象作為參數的場景&#xff08;如…

MS1826+MS9332 4K@30Hz HD4×2視頻分割器

MS1826MS9332是一款支持4K30Hz分辨率的HD42視頻分割器方案。支持四路HD輸入兩路HD輸出&#xff0c;最高支持4K30Hz分辨率。該方案具有Scaler、OSD、畫面分割、無縫切換、淡入淡出及旋轉等功能。該方案現已實現量產&#xff0c;并提供完善的技術支持&#xff0c;適用于各類高清視…

用 MATLAB 模擬傳染病傳播:從 SI 模型到 SIS 模型的可視化之旅

在公共衛生研究中&#xff0c;數學模型是理解傳染病傳播規律的重要工具。通過數值模擬&#xff0c;我們能直觀看到 “易感人群” 和 “感染人群” 隨時間的變化趨勢&#xff0c;甚至能預測疫情發展的關鍵節點。今天就帶大家用 MATLAB 實現兩個經典的傳染病模型 ——SI 模型和SI…

Ruby如何采集直播數據源地址

在當今數字化的時代&#xff0c;實時獲取并處理信息變得尤為重要。特別是在體育賽事、新聞報道等領域&#xff0c;及時獲取最新的直播數據源對于提升用戶體驗至關重要。本文將介紹如何使用Ruby語言來采集特定網站的數據源地址 一、準備工作 首先&#xff0c;確保你的環境中已…

【fitz+PIL】PDF圖片文字顏色加深

文章目錄0 引言1 解決思路及流程1.1 思路1.2 代碼實現2 完整代碼與效果3 總結0 引言 沒錯&#xff0c;這是連續劇。女友對上一篇【fitzOpenCV】去除PDF圖片中的水印得到的去水印效果很滿意&#xff0c;于是問我可不可以再幫她處理一下另一個PDF文件&#xff0c;我二話不說答應…

tp8.0\jwt接口安全驗證

環境&#xff1a;php8.3\tp8.1\firebase-jwt6.1app\middleware\JwtAuth<?php namespace app\middleware;use app\common\library\JwtHandler; use think\Request; use think\facade\Env;class JwtAuth {public function handle(Request $request, \Closure $next){// 獲取當…

ReactNative【實戰系列教程】我的小紅書 5 -- 文章詳情(含輪播圖 ImageSlider,點亮紅心動畫 Heart,嵌套評論等)

最終效果 安裝依賴 npm i dayjs用于對時間進行格式化 必備組件 輪播圖 ImageSlider https://blog.csdn.net/weixin_41192489/article/details/149224510 點亮紅心動畫 Heart components/Heart.tsx import AntDesign from "expo/vector-icons/AntDesign"; import …

嗶哩嗶哩第三方TV-BBLL最新版

—————【下 載 地 址】——————— 【?本章下載一】&#xff1a;https://pan.xunlei.com/s/VOUtUcaymd9rpgurgDKS9pswA1?pwdp76n# 【?本章下載二】&#xff1a;https://pan.xunlei.com/s/VOUtUcaymd9rpgurgDKS9pswA1?pwdp76n# 【百款黑科技】&#xff1a;https://uc…

用YOLOv5系列教程(1)-用YOLOv5輕松實現設備狀態智能監控!工業級教程來了

用YOLOv5輕松實現設備狀態智能監控&#xff01;工業級教程來了設備運維革命&#xff1a;15分鐘教會你的攝像頭看懂指示燈狀態工業現場各種設備狀態指示燈是工程師的"眼睛"——紅燈報警、綠燈運行、黃燈待機。但人工巡檢耗時費力&#xff0c;關鍵故障容易漏檢&#xf…

筆記-分布式計算基礎

Distributed Computing 劃分數據并行&#xff08;DataParallelism&#xff09;將數據分為n份&#xff0c;發送到n個GPU上&#xff0c;每個GPU上都存在一個完整的大模型 缺點&#xff1a; 模型太大Pipeline Parallelism&#xff08;串行的&#xff09;將模型做split,每個GPU負責…

Android Studio 2024,小白入門喂飯級教程

一、下載Android Studio 1、從安卓官網安卓官網下載Android Studio。 ? ? 二、安裝Android Studio 1、雙擊android-studio-2024.3.2.15-windows.exe。 ? ?? ? ? ? ? 三、新建工程 1、雙擊桌面圖標? 打開Android Studio。 ? 選“Empty Views Activity…

AI智能體 | 使用Coze制作一鍵生成單詞洗腦循環視頻,一天批量生成100條視頻不是夢!(附保姆級教程)

目錄 一、整體工作流設計 二、制作工作流 2.1 開始節點 2.2 大模型-單詞 2.3 大模型_圖像生成 2.4 輸出 2.5 圖像生成_1 2.6 輸出_2 2.7 畫板_2 2.8 文本處理 2.9 輸出_3 2.10 speech_synthesis_1x5 2.11 get_audio_duration_1 2.12 代碼 2.13 get_audio_durati…

質量屬性場景(Quality Attribute Scenario)深度解析

本質定義:質量屬性場景(Quality Attribute Scenario)是精確描述軟件系統質量要求的結構化方法,通過標準化的場景模板將抽象的質量屬性轉化為可測量、可驗證的具體行為描述,為架構設計提供客觀評估基準。 一、質量屬性場景核心結構 1. 六元組標準模板 #mermaid-svg-AGbvPVRu…

Java_Springboot技術框架講解部分(一)

首先講解一下&#xff1a;Java技術棧中&#xff0c;目前Spring Boot在國內的關注趨勢也日漸超過Spring。Spring Boot是Spring家族中的一個全新的框架&#xff0c;它用來簡化Spring應用程序的創建和開發過程。采用Spring Boot可以非常容易和快速的構建基于Spring框架的應用程序&…

從OpenMV到執行器:當PID算法開始“調教”舵機

如果到現在還不會驅動舵機——朋友&#xff0c;電賽的元器件清單每年都在對你“明示”&#xff0c;二維云臺都快成祖傳考題了&#xff01;補課&#xff1f;現在&#xff01;立刻&#xff01;&#xff08;當然&#xff0c;如果你臉皮夠厚&#xff0c;也可以私信騷擾作者&#xf…

xml映射文件的方式操作mybatis

映射文件 在Java spring中使用mybatis有兩種方式&#xff0c;一種是注釋的方式&#xff0c;一種是xml映射文件的方式。在簡單的功能需求可以使用注釋&#xff0c;方便簡潔。而在大的功能邏輯上&#xff0c;更推薦使用xml映射文件&#xff0c;方便管理且結構清晰。 首先xml文件結…

Carla自動駕駛仿真_快速安裝與運行Carla

大家好&#xff0c;我是橙子&#xff0c;今天給大家介紹Carla的基礎安裝和使用 目錄 1.Carla介紹 2.Carla的安裝與使用 3.Carla0.9.15安裝包下載&#xff1a; ?編輯 4.運行Demo 5.運行一個簡單場景&#xff1a; 6.相關資源 1.Carla介紹 Carla 是一個開源的自動駕駛仿…

遠程登錄docker執行shell報錯input is not a terminal問題

背景 最近要遠程去k8s docker里面獲取信息&#xff0c;于是&#xff0c;寫了一個如下的命令&#xff0c;執行完之后&#xff0c;報錯了。 ssh 192.168.100.2 sudo crictl exec -it xxx.docker /usr/bin/lscpu --online --extended錯誤信息如下&#xff1a; time“2025-07-11T21…