基于RK3568/RK3588/全志H3/飛騰芯片/音視頻通話程序/語音對講/視頻對講/實時性好/極低延遲

一、前言說明

近期收到幾個需求都是做音視頻通話,很多人會選擇用webrtc的方案,這個當然是個不錯的方案,但是依賴的東西太多,而且相關組件代碼量很大,開發難度大。所以最終選擇自己屬性的方案,那就是推流拉流,采集端負責采集本地攝像頭或者桌面,編碼推流到流媒體服務器,然后要拉取對方的視音頻,就是播放對應的rtsp地址即可,其實也可以是rtmp等地址,一般流媒體服務程序還提供各種http/flv等格式的拉流,方便各種場景需求,比如網頁上可以直接播放flv或者webrtc的流。

為了使得使用更方便,還特意增加了可自定義懸浮畫面位置,指定左上角、右上角、左下角、右下角、自定義位置和大小。還支持固定畫中畫功能,可交換主畫面和浮窗畫面,可設置畫面左右排列等布局方式。考慮到客戶的實際需求,還支持自定義水印,包括文字和圖片水印,支持多個水印,指定任意位置。

二、效果圖

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

三、相關代碼

#include "frmconfig.h"
#include "frmmain.h"
#include "ui_frmmain.h"
#include "qthelper.h"
#include "apphelper.h"
#include "osdgraph.h"
#include "ffmpegthread.h"
#include "ffmpegthreadcheck.h"frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain)
{ui->setupUi(this);this->initForm();this->installEventFilter(this);QMetaObject::invokeMethod(this, "formChanged", Qt::QueuedConnection);
}frmMain::~frmMain()
{delete ui;
}void frmMain::savePos()
{AppConfig::FormMax = this->isMaximized();if (!AppConfig::FormMax) {AppConfig::FormGeometry = this->geometry();}AppConfig::writeConfig();
}bool frmMain::eventFilter(QObject *watched, QEvent *event)
{//尺寸發生變化或者窗體移動位置記住窗體位置int type = event->type();if (type == QEvent::Resize || type == QEvent::Move) {QMetaObject::invokeMethod(this, "savePos", Qt::QueuedConnection);} else if (type == QEvent::Close) {audioInput->stop(false);audioOutput->stop(false);exit(0);}//尺寸發生變化重新調整小預覽窗體的位置if (this->isVisible() && type == QEvent::Resize) {this->formChanged();}return QWidget::eventFilter(watched, event);
}void frmMain::initForm()
{//初始化輸入輸出視頻控件int decodeType = AppConfig::DecodeType;AppHelper::initVideoWidget(ui->videoInput, decodeType);AppHelper::initVideoWidget(ui->videoOutput, decodeType);//初始化輸入輸出音頻線程audioInput = new FFmpegThread(this);audioOutput = new FFmpegThread(this);checkInput = new FFmpegThreadCheck(audioInput, this);AppHelper::initAudioThread(audioInput, ui->levelInput, decodeType);AppHelper::initAudioThread(audioOutput, ui->levelOutput, decodeType);//輸入打開成功后立即推流connect(audioInput, SIGNAL(receivePlayStart(int)), this, SLOT(receivePlayStart(int)));connect(ui->videoInput, SIGNAL(sig_receivePlayStart(int)), this, SLOT(receivePlayStart(int)));ui->ckInput->setChecked(AppConfig::MuteInput ? Qt::Checked : Qt::Unchecked);ui->ckOutput->setChecked(AppConfig::MuteOutput ? Qt::Checked : Qt::Unchecked);if (AppConfig::StartServer) {on_btnStart_clicked();}
}void frmMain::clearLevel()
{ui->levelInput->setLevel(0);ui->levelOutput->setLevel(0);
}void frmMain::formChanged()
{AppHelper::changeWidget(ui->videoInput, ui->videoOutput, ui->gridLayout, NULL);
}void frmMain::receivePlayStart(int time)
{QObject *obj = sender();if (obj == ui->videoInput) {
#ifdef betaversionOsdGraph::testOsd(ui->videoInput);
#endifui->videoInput->recordStart(AppConfig::VideoPush);} else if (obj == audioInput) {audioInput->recordStart(AppConfig::AudioPush);}
}void frmMain::on_btnStart_clicked()
{if (ui->btnStart->text() == "啟動服務") {if (AppConfig::VideoUrl == "video=" || AppConfig::AudioUrl == "audio=") {QtHelper::showMessageBoxError("請先打開系統設置, 選擇對應的視音頻設備");//return;}ui->videoInput->open(AppConfig::VideoUrl);ui->videoOutput->open(AppConfig::VideoPull);audioInput->setMediaUrl(AppConfig::AudioUrl);audioOutput->setMediaUrl(AppConfig::AudioPull);audioInput->play();audioOutput->play();checkInput->start();ui->btnStart->setText("停止服務");} else {ui->videoInput->stop();ui->videoOutput->stop();audioInput->stop();audioOutput->stop();checkInput->stop();ui->btnStart->setText("啟動服務");QMetaObject::invokeMethod(this, "clearLevel", Qt::QueuedConnection);}AppConfig::StartServer = (ui->btnStart->text() == "停止服務");AppConfig::writeConfig();
}void frmMain::on_btnConfig_clicked()
{static frmConfig *config = NULL;if (!config) {config = new frmConfig;connect(config, SIGNAL(formChanged()), this, SLOT(formChanged()));}config->show();config->activateWindow();
}void frmMain::on_ckInput_stateChanged(int arg1)
{bool muted = (arg1 != 0);audioInput->setMuted(muted);AppConfig::MuteInput = muted;AppConfig::writeConfig();
}void frmMain::on_ckOutput_stateChanged(int arg1)
{bool muted = (arg1 != 0);audioOutput->setMuted(muted);AppConfig::MuteOutput = muted;AppConfig::writeConfig();
}

四、相關地址

  1. 國內站點:https://gitee.com/feiyangqingyun
  2. 國際站點:https://github.com/feiyangqingyun
  3. 個人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
  4. 文件地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取碼:01jf 文件名:bin_video_call。

五、功能特點

  1. 支持局域網和外網音視頻實時通話,延遲極低,資源占用極低。
  2. 自動獲取本地所有視音頻輸入設備,本地攝像頭設備自動羅列所有支持的分辨率、幀率、采集格式等信息。
  3. 可以指定采集的視頻設備和音頻輸入設備,自由組合,視頻設備可以設置不同的分辨率、幀率、采集格式。
  4. 支持本地桌面屏幕作為視頻設備采集,支持多個屏幕,自動識別屏幕分辨率。
  5. 可以選擇不同的聲卡設備播放聲音。
  6. 內置自動重連機制,視音頻設備支持熱插拔。
  7. 支持固定畫中畫功能,可交換主畫面和浮窗畫面,可設置畫面左右排列等布局方式。
  8. 可自定義懸浮畫面位置,指定左上角、右上角、左下角、右下角、自定義位置和大小。
  9. 內置流媒體服務程序,程序啟動后自動啟動流媒體服務,自動推拉流。
  10. 視音頻流數據支持rtsp/rtmp/http/webrtc等方式拉流,可以直接網頁上打開視頻畫面。
  11. 實時顯示本地音頻振幅和遠程音量振幅,可以分別對輸入輸出音量設置靜音,方便測試。
  12. 支持自定義水印,包括文字和圖片水印,支持多個水印,指定任意位置。
  13. 支持不同的視音頻設備組合,比如本地攝像頭加電腦麥克風而不是攝像頭的麥克風,比如本地電腦桌面屏幕加攝像頭的麥克風等。
  14. 純Qt+ffmpeg編寫,支持windows和linux以及macos等系統,支持所有Qt版本、所有系統、所有編譯器。
  15. 支持嵌入式linux板子和樹莓派香橙派等,以及國產linux系統。

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

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

相關文章

AI+爆款文案,提示詞腳本 ——衛朋

目錄 簡介 提示詞 作者簡介 簡介 用好AI的前提是腦子里面要有框架。 AI就像是一個剛出生的小孩,沒有判斷力,瘋狂接收世界上的各類信息。 如果沒有從小的規則框架約束、沒有道德約束,最終的結果就一定是混亂無序的。 AI也是一樣&#x…

芯片:數字時代的算力引擎——鯤鵬、升騰、海光、Intel 全景解析

在大模型爆炸的時代,芯片如同現代文明的“數字心臟”,驅動著從智能手機、數據中心到人工智能和超級計算的每一個關鍵進程。在這場算力競賽中,華為鯤鵬、升騰、海光以及行業巨頭Intel各自扮演著獨特而至關重要的角色。本文將深入解析這些核心算…

傳輸層協議TCP(上)

上一篇https://blog.csdn.net/Small_entreprene/article/details/148143494?fromshareblogdetail&sharetypeblogdetail&sharerId148143494&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link 上文學習了傳輸層的協議之一UDP,接下來…

關于ios點擊分享自動復制到粘貼板的問題

前言 Android 系統沒有什么特別的要求,實現這個也比較容易。但ios在某些情況下就會出現問題。 如果ios是點擊之后,請求接口,再把接口的內容賦值給粘貼板肯定行不通,會被ios系統攔截,導致賦值失敗或者賦值為空。建議使…

SAP Business One:無錫哲訊科技助力中小企業數字化轉型的智慧之選

數字化轉型,中小企業的必經之路 在當今競爭激烈的商業環境中,數字化轉型已不再是大型企業的專利,越來越多的中小企業開始尋求高效、靈活的管理系統來優化業務流程、提升運營效率。作為全球領先的企業管理軟件,SAP Business One…

【孫悟空喝水】2022-2-7

緣由C編程問題求解:9634: 孫悟空喝水-編程語言-CSDN問答 void 孫悟空喝水() {//緣由https://ask.csdn.net/questions/7639865?spm1005.2025.3001.5141int x 2&#xff0c; n 0; double s 0, ss 0;std::cin >> n;while ((int)s < n)s 1.0 / x, ss (x - 1.0) / …

OCC筆記:BRepMesh_IncrementalMesh的使用

1. 函數接口 2. 線性偏轉與角度偏轉 2.1. theLineDeflection&#xff1a;線性偏轉 根據文檔推導下 isRelative傳入Standard_True時&#xff0c;theLineDeflection為相對值。 參看isRelative說明 //! param isRelative if TRUE deflection used for discretization of //! ea…

Visual Studio+SQL Server數據挖掘

這里寫自定義目錄標題 工具準備安裝Visual studio 2017安裝SQL Server安裝SQL Server Management Studio安裝analysis service SSMS連接sql serverVisual studio新建項目數據源數據源視圖挖掘結構部署模型設置挖掘預測 部署易錯點 工具準備 Visual studio 2017 analysis servi…

如何遷移SOS數據庫和修改sos服務的端口號

一. 遷移SOS數據庫。 1. 對SOS整個庫進行拷貝。壓縮拷貝等都可以 2. 找到SOS安裝目錄下的這個目錄 /SOS7/SERVERS7/LOCAL/ 在此目錄下會發現&#xff0c;有SOS服務庫的文件夾。拷貝你要遷移的SOS數據庫 3. 進入該文件夾&#xff0c;找到&#xff1a;serverdb.cfg 打開后&…

Oracle向PG轉移建議以及注意點

Oracle向PG轉移建議以及注意點 ? 一、語法差異與遷移建議 1. 包結構&#xff08;Package&#xff09; Oracle 支持 PACKAGE 和 PACKAGE BODY 分離定義。PostgreSQL 不支持包結構&#xff0c;需將每個函數/過程單獨定義。 遷移建議&#xff1a; 將 PACKAGE 包中的每個函數…

PCIe-PCI、PCIe中斷機制概述

PCI、PCIe中斷概述 PCIe 中斷機制在繼承 PCI 傳統中斷&#xff08;INTx&#xff09;的基礎上&#xff0c;引入了更高效的 MSI/MSI-X 方案&#xff0c;以提升設備性能并減少 CPU 輪詢開銷。以下是核心要點及技術演進&#xff1a; ?? ??一、PCIe 中斷類型與演進?? ??IN…

改進自己的圖片 app

1. 起因&#xff0c; 目的: 前面我寫過一個圖片 app &#xff0c; 最新做了些改動。 把原來的一列&#xff0c;改為3列&#xff0c; 繼續使用瀑布流手機上使用&#xff0c;更流暢&#xff0c;橫屏顯示為2列。 2. 先看效果 3. 過程: 過程太細碎了&#xff0c;這里只是做一下…

【HTML-15】HTML表單:構建交互式網頁的基石

表單是HTML中最強大的功能之一&#xff0c;它允許網頁收集用戶輸入并與服務器進行交互。無論是簡單的搜索框、登錄頁面&#xff0c;還是復雜的多步驟調查問卷&#xff0c;表單都是實現這些功能的核心元素。本文將深入探討HTML表單的各個方面&#xff0c;幫助您構建高效、用戶友…

關于智能體接入后端,在Apifox能夠傳參數給智能體的測試

from flask import Flask, request, jsonify, render_template import requests import json # 用于解析嵌套的 JSON 字符串app Flask(__name__)COZE_BOT_ID 7508736911423963162 COZE_API_KEY pat_cHXqrFzcvtktfmmlp4pjF3O2qmjioQW46uU8UNbUugyvSlFZclklpunc53DbR8ws COZE…

SQL進階之旅 Day 8:窗口函數實用技巧

【SQL進階之旅 Day 8】窗口函數實用技巧 在現代數據庫開發中&#xff0c;處理復雜的業務邏輯和大規模數據時&#xff0c;僅僅依靠傳統的GROUP BY和JOIN操作已經無法滿足需求。**窗口函數&#xff08;Window Function&#xff09;**作為SQL標準的一部分&#xff0c;為開發者提供…

編譯rustdesk,使用flutter、hwcodec硬件編解碼

目錄 安裝相應的環境安裝visual studio安裝vpkg安裝rust開發環境安裝llvm和clang編譯源碼下載源碼使用Sciter作為UI的(已棄用)使用flutter作為UI的(主流)下載flutter sdk橋接靜默安裝最近某desk免費的限制越來越多,實在沒辦法,平時遠程控制用的比較多,只能用rustdesk了,…

由反匯編代碼確定結構體的完整聲明

C程序中遇到下面的代碼 typedef struct {int left;a_struct a[CNT];int right; } b_struct;void test( int i, b_struct *bp) {int nbp->leftbp->right;a_struct *ap&bp->a[i];ap->x[ap->idx]n; } 下面是test函數的反匯編代碼 結合C程序中的代碼與test函數…

鴻蒙OSUniApp復雜表單與動態驗證實踐:打造高效的移動端表單解決方案#三方框架 #Uniapp

UniApp復雜表單與動態驗證實踐&#xff1a;打造高效的移動端表單解決方案 引言 在移動應用開發中&#xff0c;表單處理一直是一個既常見又具有挑戰性的任務。隨著HarmonyOS生態的蓬勃發展&#xff0c;越來越多的開發者開始關注跨平臺解決方案。本文將深入探討如何使用UniApp框…

Python學習(2) ----- Python的數據類型及其集合操作

在 Python 中&#xff0c;一切皆對象&#xff0c;每個對象都有類型。下面是 Python 中的常見內置類型分類和示例&#xff1a; &#x1f7e1; 1. 數字類型&#xff08;Numeric Types&#xff09; 類型說明示例int整數5, -42float浮點數3.14, -0.5complex復數1 2j a 10 …

深入解析Go語言數據類型:從底層到高級應用

引言 Go語言的數據類型系統設計體現了??簡潔性??與??高效性??的完美平衡。作為靜態編譯型語言&#xff0c;Go提供了豐富的數據類型支持&#xff0c;從基礎數值類型到高級并發原語&#xff0c;都經過精心設計。本文將深入剖析Go語言數據類型體系&#xff0c;揭示其底層…