基于RK3568/3588/全志H3/飞腾/音视频通话程序/语音对讲

B站影视 内地电影 2025-05-30 19:39 1

摘要:近期收到几个需求都是做音视频通话,很多人会选择用webrtc的方案,这个当然是个不错的方案,但是依赖的东西太多,而且相关组件代码量很大,开发难度大。所以最终选择自己属性的方案,那就是推流拉流,采集端负责采集本地摄像头或者桌面,编码推流到流媒体服务器,然后要拉取

近期收到几个需求都是做音视频通话,很多人会选择用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;}支持局域网和外网音视频实时通话,延迟极低,资源占用极低。自动获取本地所有视音频输入设备,本地摄像头设备自动罗列所有支持的分辨率、帧率、采集格式等信息。可以指定采集的视频设备和音频输入设备,自由组合,视频设备可以设置不同的分辨率、帧率、采集格式。支持本地桌面屏幕作为视频设备采集,支持多个屏幕,自动识别屏幕分辨率。可以选择不同的声卡设备播放声音。内置自动重连机制,视音频设备支持热插拔。支持固定画中画功能,可交换主画面和浮窗画面,可设置画面左右排列等布局方式。可自定义悬浮画面位置,指定左上角、右上角、左下角、右下角、自定义位置和大小。内置流媒体服务程序,程序启动后自动启动流媒体服务,自动推拉流。视音频流数据支持rtsp/rtmp/http/webrtc等方式拉流,可以直接网页上打开视频画面。实时显示本地音频振幅和远程音量振幅,可以分别对输入输出音量设置静音,方便测试。支持自定义水印,包括文字和图片水印,支持多个水印,指定任意位置。支持不同的视音频设备组合,比如本地摄像头加电脑麦克风而不是摄像头的麦克风,比如本地电脑桌面屏幕加摄像头的麦克风等。纯Qt+ffmpeg编写,支持windows和linux以及macos等系统,支持所有Qt版本、所有系统、所有编译器。支持嵌入式linux板子和树莓派香橙派等,以及国产linux系统。

来源:Qt自定义控件

相关推荐