摘要:音视频开发除了应用在安防监控、视频网站、各种流媒体app开发之外,还有一个小众的市场,那就是多媒体展厅场景,这个场景目前处于垄断地位的软件是HirenderS3,做的非常早而且非常全面,都是通用的需求,这个场景需求,在播放这块,有几个明显的需求是,播放的视频文
音视频开发除了应用在安防监控、视频网站、各种流媒体app开发之外,还有一个小众的市场,那就是多媒体展厅场景,这个场景目前处于垄断地位的软件是HirenderS3,做的非常早而且非常全面,都是通用的需求,这个场景需求,在播放这块,有几个明显的需求是,播放的视频文件分辨率特别大,一般是4K/8K甚至到16K,展厅的屏幕很大,分辨率小了的话,不够清晰,所以至少会上4K分辨率,一般超过2K的分辨率,一定要上硬解码,不然CPU很可能撑不住,这里问题就来了,在底层(不清楚是操作系统层面还是硬件层面),264只能支持4K硬解,265支持到8K硬解,再往上的分辨率都不支持的,而现在不少的多媒体文件是8K的264格式,12K/16K的265,那怎么办,不开启硬解的话,资源极其紧张,几乎是快占满的节奏,所以要从逻辑层面去优化,一个办法是外接多个显卡对应显示器,文件切割成多个4K或者8K,每个文件指定一个显卡去硬解,显示在指定的显示器上。一个办法是用多个显示窗体拼接,每个播放窗体都可以硬解。
还有个重要需求点是同步问题,如果是本地多个画面拼接,则需要帧同步,不然开起来多画面是不够衔接的,大于1帧的误差能够肉眼可见,多个电脑之间不同播放器也需要帧同步,所以就产生了两种帧同步需求,一个是本地帧同步,一个是网络帧同步,本地帧同步主要是控制同时解码同一帧后同时刷新显示,网络帧同步比较麻烦,因为必须通过网络数据通知当前都是播放第一帧,这个网络通信都是有延迟的,所以还需要考虑延迟的时间。
#include "synclocal.h"#include "qthelper.h"#include "frmplay.h"SINGLETON_IMPL(SyncLocal)QDatetime SyncLocal::SyncTime = QDateTime::currentDateTime.addDays(-1);SyncLocal::SyncLocal(QObject *parent) : QThread(parent){isStop = false;this->reset;syncInterval = 5;syncOffset = 15;syncSleep = 500;updateInterval = 10;}SyncLocal::~SyncLocal{this->stop;}void SyncLocal::run{while (!isStop) {this->checkPosition;this->checkSync;this->checkPause;this->updateWidget;count++;msleep(updateInterval);//qDebug reset;}void SyncLocal::checkPosition{//同步间隔0表示不启用/至少要2个窗体才需要同步int size = frmPlay::widgets.size;if (size isPlaying || widget->isPaused) {return;}//优先执行手动同步指令/-1则同步到第一个窗体/>=0则同步到对应位置if (syncPosition >= -1) {position = (syncPosition == -1 ? widget->position : syncPosition);count = 0;isSync = true;qDebug position;if (position duration - position) position;qDebug = syncOffset) {isSync = true;break;}}}void SyncLocal::checkSync{//同步标志位为真则先同步if (isSync) {count = 0;isSync = false;isPasue = true;SyncTime = QDateTime::currentDateTime;qDebug pause;widget->seek(position);}}}void SyncLocal::checkPause{//暂停阶段说明刚才执行过同步/等待一段时间重新播放if (isPasue) {qint64 time = SyncTime.msecsTo(QDateTime::currentDateTime);if (time >= syncSleep) {foreach (frmPlay *widget, frmPlay::widgets) {widget->next;}count = 0;isPasue = false;syncPosition = -2;emit receiveSync(offset);qDebug updateVideo;}}void SyncLocal::setSyncInterval(int syncInterval){this->reset;this->syncInterval = syncInterval;}void SyncLocal::setSyncOffset(int syncOffset){this->syncOffset = syncOffset;}void SyncLocal::setSyncSleep(int syncSleep){this->syncSleep = syncSleep;}void SyncLocal::setUpdateInterval(int updateInterval){this->updateInterval = updateInterval;}void SyncLocal::stop{if (this->isRunning) {this->isStop = true;this->wait;}}void SyncLocal::reset{this->count = 0;this->isSync = false;this->isPasue = false;this->syncPosition = -2;}//-1则同步到第一个窗体/>=0则同步到对应位置void SyncLocal::sync(qint64 position){//至少要两个窗体才能同步/处于暂停阶段说明上一个同步还没执行完成if (frmPlay::widgets.size >= 2 && !isPasue && syncPosition == -2) {this->syncPosition = position;}}国内站点:https://gitee.com/feiyangqingyun国际站点:https://github.com/feiyangqingyun个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652文件地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_video_sync。实时帧同步,本地无缝拼接多个视频。支持网络同步,可选主控端和被控端,主控端将本地播放的进度实时同步到被控端。网络同步支持组播、广播、单播三种模式,默认组播,既可以跨网段,也可以避免广播数据风暴。默认开启自动同步,也可以手动同步和复位同步,手动同步是立即执行一次同步,将第一个视频的进度同步到其他视频文件,复位同步是将所有视频播放进度切换到最开始0的位置。支持各种视音频文件,包括但不限于mp4/mov/mkv/rmvb/avi等格式。硬解码和GPU绘制,最大化利用硬件资源,支持qsv/cuda/dxva2/d3d11va/vaapi等硬解码。极低的CPU占用,8K30fps只占不到1%的CPU,解码和绘制全部交给GPU。提供示例按照行列生成多个视频播放窗口,每个窗口可以选择不同的视频文件,在手动同步模式下,可以切换任意一个视频播放进度,会将所有的视频按照这个进度同步。自动循环播放视频文件,无缝切换循环播放,看起来非常丝滑。支持Qt4/Qt5/Qt6所有版本,支持各种操作系统包括国产OS和嵌入式OS。来源:Qt自定义控件