菜单

18 视频-四路RTSP视频流播放

下载

实现1分屏,2 分屏,3分屏,4分屏之间切换

主界面如下,按下[1路]按钮,则切换为1分屏,再次按下[1路]按钮,则切换下一个视频流

主要代码

language 复制代码
#include "Frm01.h"

Frm01::Frm01(HmiApp* app, STTWidget *par, const string& id, const string& desc) : STTPage(app->getRuntime(), par, id, desc) {
	hmiApp = app;
}

Frm01::~Frm01() {
}

void Frm01::onInit(){
}

void Frm01::createParts() {
	setMainArg(0, 0, 1024, 600);
	setMainStyle(0, 0xffffff, 0xffffff, 0, 255, 0, 0xc0c0c0);

	/*----------------------------- Video : wMVideo1                     -----------------------------*/
	wMVideo1 = new STTFFmpeg(p_rt, this, "wMVideo1");
	wMVideo1->channel = 0;
	wMVideo1->setRotate(0);
	wMVideo1->setMainArg(40, 95, 448, 216, "rtsp://192.168.1.101:8554/stream1");
	wMVideo1->setAutoRestart(true);
	wMVideo1->setVolume(50);

	/*----------------------------- Video : wMVideo2                     -----------------------------*/
	wMVideo2 = new STTFFmpeg(p_rt, this, "wMVideo2");
	wMVideo2->channel = 1;
	wMVideo2->setRotate(0);
	wMVideo2->setMainArg(524, 95, 448, 216, "rtsp://192.168.1.101:8554/stream2");
	wMVideo2->setAutoRestart(true);
	wMVideo2->setVolume(50);

	/*----------------------------- Video : wMVideo3                     -----------------------------*/
	wMVideo3 = new STTFFmpeg(p_rt, this, "wMVideo3");
	wMVideo3->channel = 2;
	wMVideo3->setRotate(0);
	wMVideo3->setMainArg(40, 344, 448, 216, "rtsp://192.168.1.101:8554/stream3");
	wMVideo3->setAutoRestart(true);
	wMVideo3->setVolume(50);

	/*----------------------------- Video : wMVideo4                     -----------------------------*/
	wMVideo4 = new STTFFmpeg(p_rt, this, "wMVideo4");
	wMVideo4->channel = 3;
	wMVideo4->setRotate(0);
	wMVideo4->setMainArg(524, 344, 448, 216, "rtsp://192.168.1.101:8554/stream4");
	wMVideo4->setAutoRestart(true);
	wMVideo4->setVolume(50);

	/*----------------------------- Button : wMButton1                   -----------------------------*/
	wMButton1 = new STTButton(p_rt, this, "wMButton1", 0);
	wMButton1->setMainArg(41, 23, 98, 48, false);
	wMButton1->setPressedArg("1路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton1->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton1->setReleasedArg("1路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton1->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton1->onEventHandler(Event::CLICKED, this, (EHandler) &Frm01::wMButton1_clk_cb);

	/*----------------------------- Button : wMButton2                   -----------------------------*/
	wMButton2 = new STTButton(p_rt, this, "wMButton2", 0);
	wMButton2->setMainArg(157, 22, 98, 48, false);
	wMButton2->setPressedArg("2路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton2->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton2->setReleasedArg("2路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton2->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton2->onEventHandler(Event::CLICKED, this, (EHandler) &Frm01::wMButton2_clk_cb);

	/*----------------------------- Button : wMButton3                   -----------------------------*/
	wMButton3 = new STTButton(p_rt, this, "wMButton3", 0);
	wMButton3->setMainArg(273, 23, 98, 48, false);
	wMButton3->setPressedArg("3路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton3->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton3->setReleasedArg("3路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton3->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton3->onEventHandler(Event::CLICKED, this, (EHandler) &Frm01::wMButton3_clk_cb);

	/*----------------------------- Button : wMButton4                   -----------------------------*/
	wMButton4 = new STTButton(p_rt, this, "wMButton4", 0);
	wMButton4->setMainArg(389, 23, 98, 48, false);
	wMButton4->setPressedArg("4路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton4->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton4->setReleasedArg("4路", 0x0, "文泉驿微米黑", 16, 0);
	wMButton4->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
	wMButton4->onEventHandler(Event::CLICKED, this, (EHandler) &Frm01::wMButton4_clk_cb);

	/*called after widget created.*/

	return; //createParts END
}

vector<STTFFmpeg *> vecFFmpeg;
int istart = 0;//切换时第1个视频控件的RTSP列表的索引,实现轮巡
int ishow = 4;//当前显示的视频数
static int x0 = 40, y0=95;//第1个视频左上角坐标
static int x1 = 524, y1=344;//第4个视频左上角坐标
static int w0 = 448, h0=216;//分4路显示时的宽高
static int w1 = 932, h1 = 465;//分1路显示时的宽高

vector<string> vecRrsp = {
	"rtsp://192.168.1.101:8554/stream1"
	,"rtsp://192.168.1.101:8554/stream2"
	,"rtsp://192.168.1.101:8554/stream3"
	,"rtsp://192.168.1.101:8554/stream4"
};

void plays() {
	for(int i=0;i<vecFFmpeg.size();i++) {
		vecFFmpeg[i]->play(200 + i * 300);
	}
}

//切换到播放1路
void play1() {
	if(ishow == 1) istart++;
	ishow = 1;
	for(int i=0;i<vecFFmpeg.size();i++) {
		//尺寸设为一致,被第1个覆盖,则看上去就是1路视频;当前istart为第1个播放器的源
		vecFFmpeg[i]->setMainArg(x0, y0, w1, h1, vecRrsp[(i+istart)%4]);
	}
	plays();
}

void play2() {
	if(ishow == 2) istart++;
	ishow = 2;
	//左侧
	vecFFmpeg[0]->setMainArg(x0,y0,w0,h1, vecRrsp[(0+istart)%4]);
	//右侧
	vecFFmpeg[1]->setMainArg(x1,y0,w0,h1, vecRrsp[(1+istart)%4]);

	//同0大小,被0覆盖
	vecFFmpeg[2]->setMainArg(x0,y0,w0,h1, vecRrsp[(0+istart)%4]);
	//同1大小,被1覆盖
	vecFFmpeg[3]->setMainArg(x1,y0,w0,h1, vecRrsp[(1+istart)%4]);
	plays();
}

void play3() {
	if(ishow == 3) istart++;
	ishow = 3;
	//左侧合并
	vecFFmpeg[0]->setMainArg(x0,y0,w0,h1, vecRrsp[(0+istart)%4]);
	vecFFmpeg[2]->setMainArg(x0,y0,w0,h1, vecRrsp[(0+istart)%4]);
	//右侧2个不变
	vecFFmpeg[1]->setMainArg(x1,y0,w0,h0, vecRrsp[(1+istart)%4]);
	vecFFmpeg[3]->setMainArg(x1,y1,w0,h0, vecRrsp[(2+istart)%4]);
	plays();
}

void play4() {
	if(ishow == 4) istart++;
	ishow = 4;
	vecFFmpeg[0]->setMainArg(x0,y0,w0,h0, vecRrsp[(0+istart)%4]);
	vecFFmpeg[1]->setMainArg(x1,y0,w0,h0, vecRrsp[(1+istart)%4]);
	vecFFmpeg[2]->setMainArg(x0,y1,w0,h0, vecRrsp[(2+istart)%4]);
	vecFFmpeg[3]->setMainArg(x1,y1,w0,h0, vecRrsp[(3+istart)%4]);
	plays();
}

void Frm01::onLoad(){
	vecFFmpeg.push_back(wMVideo1);
	vecFFmpeg.push_back(wMVideo2);
	vecFFmpeg.push_back(wMVideo3);
	vecFFmpeg.push_back(wMVideo4);

	plays();
}

bool Frm01::onClosing(){
	return true;
}

void Frm01::onDispose(){
}

void Frm01::wMButton1_clk_cb(uint16_t code, LvEvent e) {
	/*wMButton1(1路)的点击事件*/
	play1();
}

void Frm01::wMButton2_clk_cb(uint16_t code, LvEvent e) {
	/*wMButton2(2路)的点击事件*/
	play2();
}

void Frm01::wMButton3_clk_cb(uint16_t code, LvEvent e) {
	/*wMButton3(3路)的点击事件*/
	play3();
}

void Frm01::wMButton4_clk_cb(uint16_t code, LvEvent e) {
	/*wMButton4(4路)的点击事件*/
	play4();
}

工程下载

视频演示

最近修改: 2026-08-23Powered by