欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器

 更新時(shí)間:2024年01月17日 09:35:51   作者:淺笑一斤  
這篇文章主要為大家詳細(xì)介紹了如何利用C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器,并支持軟硬解碼,支持音頻,支持錄像截圖,支持多路播放等,感興趣的可以了解下

一.前言

在瀏覽器中實(shí)現(xiàn)播放RTSP實(shí)時(shí)視頻流,?體上有如下?個(gè)?案:

?案一:瀏覽器插件?案 ActiveX、NPAPI、PPAPI

ActiveX插件適用于IE瀏覽器,NPAPI與PPAPI插件適用于谷歌瀏覽器,不過(guò)這些插件都已經(jīng)不被瀏覽器所支持。

?案二:先轉(zhuǎn)碼再轉(zhuǎn)流?案

?作原理是架設(shè)一個(gè)視頻流轉(zhuǎn)碼服務(wù)器,將RTSP視頻流轉(zhuǎn)換為flv后用Web Socket或WebRTC推送到前端,前端收到后再轉(zhuǎn)換為Video所?持的MP4后播放。這過(guò)程中需要經(jīng)過(guò)2次轉(zhuǎn)碼才播放,畫?延遲時(shí)間?幅增加。如果有多路視頻流時(shí),服務(wù)器端轉(zhuǎn)碼和轉(zhuǎn)流對(duì)CPU、內(nèi)存、?絡(luò)帶寬的壓??幅度增加,長(zhǎng)期使?綜合成本很?,對(duì)?分辨率的視頻流播放經(jīng)常出現(xiàn)花屏、卡頓現(xiàn)象。此?案要求瀏覽器?持流媒體擴(kuò)展特性(MSE),且?法利?本機(jī)硬件加速實(shí)現(xiàn)解碼和渲染播放。優(yōu)點(diǎn)是可兼容移動(dòng)端?頁(yè)播放。此?案在國(guó)內(nèi)有TSINGSEE的免插件EasyPlayer RTSP播放器。

?案三:先轉(zhuǎn)碼再轉(zhuǎn)流?案

?作原理是架設(shè)?個(gè)Web Socket的視頻流轉(zhuǎn)發(fā)服務(wù)器,前端連接到此服務(wù)器后,服務(wù)端不斷把RTSP視頻流通過(guò)Web Socket不斷轉(zhuǎn)發(fā)給前端的JS處理庫(kù),JS處理庫(kù)再把視頻流轉(zhuǎn)換為Video所?持的MP4后播放。此?案不?持IE瀏覽器,最?的問(wèn)題是畫?延遲達(dá)數(shù)秒,?屏內(nèi)容顯?慢,也?法利?本機(jī)硬件加速實(shí)現(xiàn)解碼和渲染播放,CPU占??,播放時(shí)花屏、卡頓現(xiàn)象,體驗(yàn)?較差。此?案的典型代表是Streamedian公司的免插件播放器Html5 RTSP Player。

?案四:Wasm?案

工作原理是通過(guò)Emscripten將音視頻解碼庫(kù)編譯成Js(WebAssembly,簡(jiǎn)稱wasm)運(yùn)行于瀏覽器之中,RTSP視頻流通過(guò)ffmpeg的Wasm版軟解碼成Video所?持的MP4后播放。此方案由于Wasm不?持硬件解碼,對(duì)多路同時(shí)播放來(lái)說(shuō),終端電腦的CPU和內(nèi)存占?會(huì)?較?,性能也堪憂。此方案有Jessibuca,Jessibuca項(xiàng)目地址:https://gitee.com/InternetJava/jessibuca

?案五:網(wǎng)頁(yè)調(diào)用VLC插件方式播放

其原理是底層調(diào)用VLC的ActiveX控件可實(shí)現(xiàn)在網(wǎng)頁(yè)中內(nèi)嵌播放多路RTSP的實(shí)時(shí)視頻流。

?案六:瀏覽器內(nèi)嵌C++播放器

基本原理在瀏覽器?頁(yè)中的指定位置和??,實(shí)現(xiàn)?個(gè)內(nèi)嵌到?頁(yè)中顯?的播放窗?,前端還必須可對(duì)這個(gè)內(nèi)嵌播放窗?進(jìn)?控制,?且播放窗?必須跟隨瀏覽器窗?的移動(dòng)和縮放、?頁(yè)滾動(dòng)、標(biāo)簽頁(yè)切換、關(guān)閉等操作進(jìn)??動(dòng)聯(lián)動(dòng)。播放器可以通過(guò)QT或MFC進(jìn)行實(shí)現(xiàn),可以充分利?終端電腦的硬件加速特性。這個(gè)播放窗?同時(shí)提供Web Socket的服務(wù)端和JSON打包命令的解析執(zhí)?模塊,前端就可以通過(guò)Web Socket連接后發(fā)送JSON打包的控制命令實(shí)現(xiàn)控制播放窗?。通過(guò)這種方案實(shí)現(xiàn)的有大華的視頻插件。

二.瀏覽器內(nèi)嵌C++播放器的實(shí)現(xiàn)

2.1 播放器功能介紹

該播放器仿照大華視頻插件,支持軟硬解碼,支持錄像截圖,支持音頻播放,支持多路播放,支持右鍵菜單欄操作,支持多路分頁(yè)顯示,支持全屏顯示等功能,如下圖:

2.2 播放器部分代碼分享

網(wǎng)頁(yè)部分:

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
    <link rel="stylesheet" type="text/css" href="css/index.css" rel="external nofollow" >
    <link rel="stylesheet" type="text/css" href="css/slider/jquery-ui-slider-pips.min.css" rel="external nofollow" >
    <title>My VideoPlayer For Web</title>
    <script src="js/jquery.min.js"></script>
    <script src="js/myplayer.js"></script>
    <script src="js/index.js"></script>
    <script src="jquery/slider/jquery-plus-ui.min.js"></script>
    <script src="jquery/slider/jquery-ui-slider-pips.js"></script>
    <script src="jquery/slider/slider.js"></script>
  </head>

  <body style="background-color: white; margin-left: 10px">
	<div align="center" class="pageContent">
		<div id="pageVideo" style="float:left" class="pageVideo">	
			<div id="myPlayer"></div>
		</div>
		<div id="pageConfig" class="pageConfig">
			<div id="video_box">
			  <table border="0">
			  	<h1 class="h_font" style="margin-top: 30px;">
					播放器設(shè)置:
			  	</h1>
			    <tr>
			  		<td>
						<label>當(dāng)前窗口: </label>
						<input class="input_style" style="width: 300px" type="number" name="Index" id="windowIndex" value="0"/>
					</td>
			  	</tr>
			  	<tr>
			  		<td>
						<label>    設(shè)備ID: </label>
						<input class="input_style" style="width: 300px" type="text" name="DevID" id="devid" value="0"/>
					</td>
			  	</tr>
				<tr>
					<td class="decode-type">
						<label>軟硬解碼: </label>
						<input type="radio" value="0" name="radioCode"/>
				        <label for="0">軟解</label>
				        <input type="radio" value="1" name="radioCode" checked style="margin-left:30px;"/>
				        <label for="1">硬解</label>
					</td>
				</tr>
				<tr class="real">
					<td class="video-connect">
						<label>連接方式: </label>
						<input type="radio" value="1" name="radioConnect" checked />
				        <label for="1">TCP</label>
						<input type="radio" value="0" name="radioConnect" style="margin-left:30px;"/>
				        <label for="0">UDP</label>
					</td>
				</tr>
				<tr class="real">
					<td>
						<label>碼流地址: </label>
						<input class="input_style" style="width: 300px" type="text" name="RTSP" id="realInput" placeholder=" 請(qǐng)輸入碼流地址" />
					</td>
				</tr>
				<tr class="real">
					<td>
						<input type="button" class="btn_style" onclick="PlayRealStream()" value="播放" />
						<input type="button" class="btn_style" onclick="StopPlay()" value="停止" />
						<input type="button" class="btn_style" onclick="StopAllPlay()" value="全部停止" />
					</td>
				</tr>
				<!--視頻操作-->
				<th colspan="2" class="table_th opetate">
			  		視頻操作:
			  	</th>
			  	<tr class="operate">
			  		<td>
						<input type="button" class="btn_style" onclick="StartRecord()" value="錄像" />
						<input type="button" class="btn_style" onclick="StopRecord()" value="停止錄像" />
						<input type="button" class="btn_style" onclick="Snapshot()" value="截圖" />
						<input type="button" class="btn_style" onclick="OpenAudio()" value="開啟音頻" />
						<input type="button" class="btn_style" onclick="CloseAudio()" value="關(guān)閉音頻" />
					</td>
			  	</tr>
			  	<tr class="operate">
			  		<td>
		  				<div class="tabs-content" style="margin-bottom:30px;">
		  					<label style="margin-top:10px;">音量大小: </label>
	                        <div class="content active" style="margin-left:80px;margin-top:-10px;">
	                            <div id="audioSlier" style="width:190px;"> </div>
	                        </div>
                		</div>	
					</td>
			  	</tr>
			  	<!--窗口操作-->
				<th colspan="2" class="table_th opetate">
			  		窗口操作:
			  	</th>
			  	<tr class="operate">
			  		<td>
			  			<!--
			  			<input type="button" class="btn_style" onclick="initPlayer()" value="窗口創(chuàng)建" />
						<input type="button" class="btn_style" onclick="destroyPlayer()" value="窗口銷毀" />-->
						<input type="button" class="btn_style" onclick="showVideoPlayer()" value="窗口顯示" />
						<input type="button" class="btn_style" onclick="hideVideoPlayer()" value="窗口隱藏" />
						<input type="button" class="btn_style" onclick="setFullScreen()" value="窗口全屏" />
					</td>
			  	</tr>
			  </table>  
			</div>
		</div>
	</div>
  </body>
</html>

index.js

/* 
 * Filename:      	index.js
 * Description:  	界面功能實(shí)現(xiàn)
 * Version:			1.0
 * *******************************************************/

//全局變量
var g_videoPlayer = null
var g_currentIndex = 0
var g_decodeType = 1
var g_protocolType = 1

//初始化
$(function () {
  	initPlayer()
	initUI()
})

//初始化視頻窗口
function initPlayer() {
	if(g_videoPlayer) {
		destroyPlayer()
	}
  	g_currentIndex = 0
  	$('#windowIndex').val(0)
  	g_videoPlayer = new VideoPlayer({
	    videoId: 'myPlayer',
	    num: 4, //初始化創(chuàng)建窗口個(gè)數(shù)
	    windowType: 3,
	    connectSuccess: () => {
			console.log('連接成功')
	    },
	    createSuccess: (e) => {
	      	console.log('窗口創(chuàng)建成功')
	    },
	    clickWindow: (wndIndex) => { //獲取當(dāng)前點(diǎn)擊的窗口
			g_currentIndex = wndIndex
			$('#windowIndex').val(wndIndex)
			console.log("當(dāng)前點(diǎn)擊了第${wndIndex}個(gè)窗口")
	    }
  })
}

//初始化UI組件
function initUI() {
	$('.decode-type :radio').click(function () {
		var type = parseInt($(this).val())
		g_decodeType = type
	})

	$('.video-connect :radio').click(function () {
		var type = parseInt($(this).val())
		g_protocolType = type
	})

	$("#select_record_file").on("change", "input[id='record_file']", function () {
			document.getElementById("record_file_path").value = $(this).val()
	})
}


//顯示視頻窗口
function showVideoPlayer() {
  g_videoPlayer.show()
}

//隱藏視頻窗口
function hideVideoPlayer() {
  g_videoPlayer.hide()
}


//設(shè)置全屏
function setFullScreen() {
  g_videoPlayer.setFullScreen()
}

//銷毀視頻窗口
function destroyPlayer() {
  if (!g_videoPlayer) {
    alert('請(qǐng)先創(chuàng)建視頻窗口')
  }
  g_videoPlayer.destroy()
  g_videoPlayer = null
}


實(shí)時(shí)預(yù)覽
//播放
function PlayRealStream() {

	if(!g_videoPlayer) {
	    alert('請(qǐng)先創(chuàng)建視頻窗口')
	}

	var sUrl = $('#realInput').val()
	if (!sUrl) {
		alert("實(shí)時(shí)地址不能為空")
		return false
	}

	var windowIndex = parseInt($('#windowIndex').val());
	if(windowIndex < 0 || windowIndex > 64) {
		alert("當(dāng)前窗口號(hào)需要設(shè)置(>=0 && <64)的數(shù)字")
		return false
	}

	var devid = $('#devid').val();
	if(!devid) {
		alert("設(shè)備ID不能為空")
		return false
	}
	
	g_videoPlayer.playReal({
		devId: devid,
		winIndex: windowIndex,
		url: sUrl,
		decodeType: g_decodeType,
		connectType: g_protocolType
	})
}

//停止
function StopPlay() {

	if(!g_videoPlayer) {
	    alert('請(qǐng)先創(chuàng)建視頻窗口')
	}

  	var windowIndex = parseInt($('#windowIndex').val());
	if(windowIndex < 0 || windowIndex > 64) {
		alert("當(dāng)前窗口號(hào)需要設(shè)置(>=0 && <64)的數(shù)字")
		return false
	}

	g_videoPlayer.stopVideo(windowIndex)
}


//全部停止
function StopAllPlay() {

	if(!g_videoPlayer) {
	    alert('請(qǐng)先創(chuàng)建視頻窗口')
	}
	g_videoPlayer.stopVideo('')
}


//視頻操作
//開始錄像
function StartRecord() {

	if(!g_videoPlayer) {
		alert('請(qǐng)先創(chuàng)建視頻窗口')
	}

	var windowIndex = parseInt($('#windowIndex').val());
	if(windowIndex < 0 || windowIndex > 64) {
		alert("當(dāng)前窗口號(hào)需要設(shè)置(>=0 && <64)的數(shù)字")
		return false
	}

	g_videoPlayer.enableRecord({
	    winIndex: windowIndex,
	    isEnable: true
  	})
}

//結(jié)束錄像
function StopRecord() {

	if(!g_videoPlayer) {
		alert('請(qǐng)先創(chuàng)建視頻窗口')
	}

	var windowIndex = parseInt($('#windowIndex').val());
	if(windowIndex < 0 || windowIndex > 64) {
		alert("當(dāng)前窗口號(hào)需要設(shè)置(>=0 && <64)的數(shù)字")
		return false
	}
	
	g_videoPlayer.enableRecord({
	    winIndex: windowIndex,
	    isEnable: false
  	})
}


//截圖
function Snapshot() {

	if(!g_videoPlayer) {
		alert('請(qǐng)先創(chuàng)建視頻窗口')
	}

	var windowIndex = parseInt($('#windowIndex').val());
	if(windowIndex < 0 || windowIndex > 64) {
		alert("當(dāng)前窗口號(hào)需要設(shè)置(>=0 && <64)的數(shù)字")
		return false
	}
	g_videoPlayer.snapshot(windowIndex)
}


//開啟音頻
function OpenAudio() {

	if(!g_videoPlayer) {
		alert('請(qǐng)先創(chuàng)建視頻窗口')
	}

	var windowIndex = parseInt($('#windowIndex').val());
	if(windowIndex < 0 || windowIndex > 64) {
		alert("當(dāng)前窗口號(hào)需要設(shè)置(>=0 && <64)的數(shù)字")
		return false
	}
		
	g_videoPlayer.enableAudio({
	    winIndex: windowIndex,
	    isEnable: true
  	})
}

//關(guān)閉音頻
function CloseAudio() {

	if(!g_videoPlayer) {
		alert('請(qǐng)先創(chuàng)建視頻窗口')
	}

	var windowIndex = parseInt($('#windowIndex').val());
	if(windowIndex < 0 || windowIndex > 64) {
		alert("當(dāng)前窗口號(hào)需要設(shè)置(>=0 && <64)的數(shù)字")
		return false
	}
	
	g_videoPlayer.enableAudio({
	    winIndex: windowIndex,
	    isEnable: false
  	})
}

//設(shè)置音量
function SetAudioVolume() {

	var audioVolumn = parseInt($("#audioSlier").slider('value'));
	if(g_videoPlayer) {
		g_videoPlayer.setAudioVolumn({
		    volumn: audioVolumn
  		})
	}
}

C++部分:

MainWindow.cpp

#include <QMessageBox>
#include <QFileDialog>
#include <QMetaType>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ctaudioplayer.h"
#include <QDesktopServices>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDesktopServices>

#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
#include <QScreen>
#else
#include <QDesktopWidget>
#endif

#pragma execution_character_set("utf-8")

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //初始化多路播放器
    InitMul();

    //初始化websocket
    InitWeb();

    //窗口置頂
    this->setWindowFlags(Qt::Widget | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
}

MainWindow::~MainWindow()
{
    if(m_pWebSocketServer)
        m_pWebSocketServer->close();
    delete ui;
}

void MainWindow::InitMul()
{
    qRegisterMetaType<MEDIA_DEV_INFO_T>("MEDIA_DEV_INFO_T");

    connect(this, SIGNAL(sig_setScreenType(int)),
            ui->widget_mulvideo, SLOT(slot_setScreenType(int)));

    connect(this, SIGNAL(sig_playOne(MEDIA_DEV_INFO_T)),
            ui->widget_mulvideo, SLOT(slot_playOne(MEDIA_DEV_INFO_T)));
    connect(this, SIGNAL(sig_stopOne(int)),
            ui->widget_mulvideo, SLOT(slot_stopOne(int)));

    connect(this, SIGNAL(sig_snapshot(int)),
            ui->widget_mulvideo, SLOT(slot_snapshot(int)));
    connect(this, SIGNAL(sig_enableRecord(bool,int)),
            ui->widget_mulvideo, SLOT(slot_enableRecord(bool,int)));

    connect(this, SIGNAL(sig_stopAll()),
            ui->widget_mulvideo, SLOT(slot_stopAll()));

    connect(this, SIGNAL(sig_nextPage()),
            ui->widget_mulvideo, SLOT(slot_NextPage()));
    connect(this, SIGNAL(sig_prevPage()),
            ui->widget_mulvideo, SLOT(slot_PrevPage()));
    connect(ui->widget_mulvideo, SIGNAL(sig_pageInfo(QString)),
            this, SLOT(slot_setPageInfo(QString)));

    connect(ui->widget_mulvideo, SIGNAL(sig_curWinIndex(int)),
            this, SLOT(slot_curWinIndex(int)));

    connect(ui->widget_mulvideo, SIGNAL(sig_playFailTip(QString)),
            this, SLOT(slot_playFailTip(QString)));

    connect(this, SIGNAL(sig_fullscreen(bool)),
            ui->widget_mulvideo, SLOT(slot_fullscreen(bool)));

    connect(ui->widget_mulvideo, SIGNAL(sig_fullscreen(bool)),
            this, SLOT(slot_fullscreen(bool)));


    ui->comboBox_ChangeVideo->setCurrentIndex(1);
    emit sig_setScreenType(1);
}

void MainWindow::InitWeb()
{
    //web param
    m_stWebParam.sInfo = SOFTWARE_VERSION;
    m_stWebParam.sVer = SOFTWARE_VERSION;
    m_stWebParam.nCode = 0;
    m_stWebParam.nHwnd = 0;

    //窗口置頂
    this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);

    //設(shè)置背景
    QColor color("#f0faff");
    QPalette pal(this->palette());
    pal.setColor(QPalette::Background, color);
    this->setAutoFillBackground(true);
    this->setPalette(pal);

    //websocket
    m_pWebSocketServer = new QWebSocketServer("myServer", QWebSocketServer::NonSecureMode);
    connect(m_pWebSocketServer, SIGNAL(newConnection()), this, SLOT(on_newConnection()));

    m_pWebSocketServer->listen(QHostAddress::Any, WEB_LISTEN_PORT);

    InitMethodFun();
}

void MainWindow::InitMethodFun()
{
    METHOD_FUN_T stMethodFun[] =
    {
        {"window.version", MainWindow::GetPlayerVer},
        {"window.create", MainWindow::windowCreate},
        {"window.change", MainWindow::windowChange},
        {"window.show", MainWindow::windowShow},
        {"media.playReal", MainWindow::PlayReal},
        {"media.stop", MainWindow::StopMedia},
        {"media.snapshot", MainWindow::Snapshot},
        {"media.enableRecord", MainWindow::enableRecord},
        {"media.enableAudio", MainWindow::enableAudio},
        {"media.setAudioVolumn", MainWindow::setAudioVolumn},
        {"media.fullscreen", MainWindow::fullScreen},
        {"player.test", NULL},
    };

    for(int i=0; stMethodFun[i].methodFun != NULL;  i++)
    {
        m_hashFun.insert(stMethodFun[i].sMethod, stMethodFun[i].methodFun);
    }
}

void MainWindow::SendJsonData(QJsonObject Json)
{
    //構(gòu)建 Json 文檔
    QJsonDocument document;
    document.setObject(Json);
    QByteArray byteArray = document.toJson(QJsonDocument::Compact);
    QString strJson(byteArray);

    for (int i=0;i<m_clientsList.size();i++)
    {
        m_clientsList.at(i)->sendTextMessage(strJson);
    }
}

void MainWindow::GetPlayerVer(void* pObject, QJsonObject* pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
            MY_DEBUG << "yibin test m_stWebParam.nID:" << pWin->m_stWebParam.nID;

            QJsonObject dataObject;
            dataObject.insert("info", pWin->m_stWebParam.sInfo);
            dataObject.insert("ver", pWin->m_stWebParam.sVer);

            QJsonObject json;
            json.insert("code", pWin->m_stWebParam.nCode);
            json.insert("data", QJsonValue(dataObject));
            json.insert("id", pWin->m_stWebParam.nID);
            json.insert("session", pWin->m_stWebParam.nSession);
            json.insert("success", "true");

            pWin->SendJsonData(json);
        }
    }
}

void MainWindow::windowCreate(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("clientAreaWidth"))
            {
                QJsonValue value = obj.value("clientAreaWidth");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nClientAreaWidth = value.toVariant().toInt();
                }
            }
            if(obj.contains("clientAreaHeight"))
            {
                QJsonValue value = obj.value("clientAreaHeight");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nClientAreaHeight = value.toVariant().toInt();
                }
            }
            if(obj.contains("width"))
            {
                QJsonValue value = obj.value("width");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nWidth = value.toVariant().toInt();
                }
            }
            if(obj.contains("height"))
            {
                QJsonValue value = obj.value("height");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nHeight = value.toVariant().toInt();
                }
            }
            if(obj.contains("left"))
            {
                QJsonValue value = obj.value("left");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nLeft = value.toVariant().toInt();
                }
            }
            if(obj.contains("top"))
            {
                QJsonValue value = obj.value("top");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nTop = value.toVariant().toInt();
                }
            }
            if(obj.contains("num"))
            {
                QJsonValue value = obj.value("num");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nNum = value.toVariant().toInt();
                }
            }
        }
        pWin->move(pWin->m_stWebParam.nScreenX+pWin->m_stWebParam.nLeft, pWin->m_stWebParam.nScreenY+pWin->m_stWebParam.nTop+140);
    }

    QJsonObject dataObject;
    dataObject.insert("bRtsps", pWin->m_stWebParam.bRtsp);
    dataObject.insert("hwnd", pWin->m_stWebParam.nHwnd);

    QJsonObject json;
    json.insert("code", pWin->m_stWebParam.nCode);
    json.insert("data", QJsonValue(dataObject));
    json.insert("id", pWin->m_stWebParam.nID);
    json.insert("session", pWin->m_stWebParam.nSession);
    json.insert("success", "true");

    pWin->SendJsonData(json);
}

void MainWindow::windowChange(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("clientAreaWidth"))
            {
                QJsonValue value = obj.value("clientAreaWidth");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nClientAreaWidth = value.toVariant().toInt();
                }
            }
            if(obj.contains("clientAreaHeight"))
            {
                QJsonValue value = obj.value("clientAreaHeight");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nClientAreaHeight = value.toVariant().toInt();
                }
            }
            if(obj.contains("left"))
            {
                QJsonValue value = obj.value("left");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nLeft = value.toVariant().toInt();
                }
            }
            if(obj.contains("top"))
            {
                QJsonValue value = obj.value("top");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nTop = value.toVariant().toInt();
                }
            }
            if(obj.contains("screenX"))
            {
                QJsonValue value = obj.value("screenX");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nScreenX = value.toVariant().toInt();
                }
            }
            if(obj.contains("screenY"))
            {
                QJsonValue value = obj.value("screenY");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nScreenY = value.toVariant().toInt();
                }
            }
        }
    }
    pWin->move(pWin->m_stWebParam.nScreenX+pWin->m_stWebParam.nLeft, pWin->m_stWebParam.nScreenY+pWin->m_stWebParam.nTop+140);
}

void MainWindow::windowShow(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("show"))
            {
                QJsonValue value = obj.value("show");
                if(value.isBool())
                {
                    pWin->m_stWebParam.bShow = value.toVariant().toBool();
                }
            }
            if(obj.contains("hwnd"))
            {
                QJsonValue value = obj.value("hwnd");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nHwnd = value.toVariant().toInt();
                }
            }
            if(obj.contains("browserType"))
            {
                QJsonValue value = obj.value("browserType");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nBrowserType = value.toVariant().toInt();
                }
            }
        }
    }

    pWin->setVisible(pWin->m_stWebParam.bShow);
}

void MainWindow::PlayReal(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("devId"))
            {
                QJsonValue value = obj.value("devId");
                if(value.isString())
                {
                    pWin->m_stWebParam.sDevId = value.toVariant().toString();
                }
            }
            if(obj.contains("winIndex"))
            {
                QJsonValue value = obj.value("winIndex");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nWinIndex = value.toVariant().toInt();
                }
            }
            if(obj.contains("decodeType"))
            {
                QJsonValue value = obj.value("decodeType");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nDecodeType = value.toVariant().toInt();
                }
            }
            if(obj.contains("connectType"))
            {
                QJsonValue value = obj.value("connectType");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nProtocolType = value.toVariant().toInt();
                }
            }
            if(obj.contains("url"))
            {
                QJsonValue value = obj.value("url");
                if(value.isString())
                {
                    pWin->m_stWebParam.sUrl = value.toVariant().toString();
                }
            }
        }
    }

    if(!pWin->m_stWebParam.sUrl.isEmpty() && !pWin->m_stWebParam.sDevId.isEmpty() &&
            (pWin->m_stWebParam.nWinIndex >= 0 && pWin->m_stWebParam.nWinIndex < MAX_MEDIA_NUM))
    {
        MEDIA_DEV_INFO_T stDev;
        stDev.nChannel = pWin->m_stWebParam.nWinIndex;
        stDev.sDevId = pWin->m_stWebParam.sDevId;
        stDev.sUrl = pWin->m_stWebParam.sUrl;
        stDev.nDecodeType = pWin->m_stWebParam.nDecodeType;
        stDev.nProtocolType = pWin->m_stWebParam.nProtocolType;
        emit pWin->sig_playOne(stDev);
    }

    QJsonObject dataObject;
    QJsonObject json;
    json.insert("code", pWin->m_stWebParam.nCode);
    json.insert("data", QJsonValue(dataObject));
    json.insert("id", pWin->m_stWebParam.nID);
    json.insert("session", pWin->m_stWebParam.nSession);
    json.insert("success", "true");

    pWin->SendJsonData(json);
}

void MainWindow::Snapshot(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("winIndex"))
            {
                QJsonValue value = obj.value("winIndex");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nWinIndex = value.toVariant().toInt();
                }
            }
        }
    }

    emit pWin->sig_snapshot(pWin->m_stWebParam.nWinIndex);
}

void MainWindow::enableRecord(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("winIndex"))
            {
                QJsonValue value = obj.value("winIndex");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nWinIndex = value.toVariant().toInt();
                }
            }
            if(obj.contains("isEnable"))
            {
                QJsonValue value = obj.value("isEnable");
                if(value.isBool())
                {
                    pWin->m_stWebParam.bRecord = value.toVariant().toBool();
                }
            }
        }
    }

    emit pWin->sig_enableRecord(pWin->m_stWebParam.bRecord, pWin->m_stWebParam.nWinIndex);
}

void MainWindow::enableAudio(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("isEnable"))
            {
                QJsonValue value = obj.value("isEnable");
                if(value.isBool())
                {
                    pWin->m_stWebParam.bAudio = value.toVariant().toBool();
                    ctAudioPlayer::getInstance().isPlay(pWin->m_stWebParam.bAudio);
                }
            }
        }
    }
}

void MainWindow::setAudioVolumn(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("volumn"))
            {
                QJsonValue value = obj.value("volumn");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nVolumn = value.toVariant().toDouble();
                    qreal nVal = pWin->m_stWebParam.nVolumn / 100.0;
                    MY_DEBUG << "setAudioVolumn nVal:" << nVal;
                    ctAudioPlayer::getInstance().setVolumn(nVal);
                }
            }
        }
    }
}

void MainWindow::fullScreen(void *pObject, QJsonObject *pJson)
{
    Q_UNUSED(pJson)

    MainWindow* pWin = (MainWindow*)pObject;
    emit pWin->sig_fullscreen(true);
    pWin->slot_fullscreen(true);
}

void MainWindow::StopMedia(void *pObject, QJsonObject *pJson)
{
    MainWindow* pWin = (MainWindow*)pObject;
    if(pJson->contains("id"))
    {
        QJsonValue id = pJson->value("id");
        if(id.isDouble())
        {
            pWin->m_stWebParam.nID = id.toVariant().toInt();
        }
    }

    if(pJson->contains("info"))
    {
        QJsonValue value = pJson->value("info");
        if(value.isObject())
        {
            QJsonObject obj = value.toObject();
            if(obj.contains("winIndex"))
            {
                QJsonValue value = obj.value("winIndex");
                if(value.isDouble())
                {
                    pWin->m_stWebParam.nWinIndex = value.toVariant().toInt();
                }
            }
            if(obj.contains("isAll"))
            {
                QJsonValue value = obj.value("isAll");
                if(value.isBool())
                {
                    pWin->m_stWebParam.bAllStop = value.toVariant().toBool();
                }
            }
        }
    }

    if(pWin->m_stWebParam.bAllStop)
        emit pWin->sig_stopAll();
    else
    {
        if(pWin->m_stWebParam.nWinIndex >= 0 && pWin->m_stWebParam.nWinIndex < MAX_MEDIA_NUM)
        {
            emit pWin->sig_stopOne(pWin->m_stWebParam.nWinIndex);
        }
    }

    QJsonObject dataObject;
    QJsonObject json;
    json.insert("code", pWin->m_stWebParam.nCode);
    json.insert("data", QJsonValue(dataObject));
    json.insert("id", pWin->m_stWebParam.nID);
    json.insert("session", pWin->m_stWebParam.nSession);
    json.insert("success", "true");

    pWin->SendJsonData(json);
}

void MainWindow::parseJson(QString sData)
{
    QJsonParseError jError;
    QJsonDocument jDoc = QJsonDocument::fromJson(sData.toLatin1(), &jError);//轉(zhuǎn)換成文檔對(duì)象
    if(!jDoc.isNull() && jError.error == QJsonParseError::NoError)
    {
        if(jDoc.isObject())
        {
            QJsonObject object = jDoc.object();
            if(object.contains("method"))
            {
                QJsonValue sMethod = object.value("method");
                if(sMethod.isString())
                {
                    QString strMethod = sMethod.toString();

                    QHashMethodFunIterator iter = m_hashFun.begin();
                    for(; iter != m_hashFun.end(); ++iter)
                    {
                        QString sKey = iter.key();
                        if(sKey.contains(strMethod))
                        {
                            MethodFun fun = m_hashFun.value(sKey);
                            fun(this, &object);
                        }
                    }
                }
            }
        }
    }
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Escape)
    {
        if(m_bFullScreen == true)
        {
            emit sig_fullscreen(false);
            slot_fullscreen(false);
            event->accept();
        }
    }
    return QMainWindow::keyPressEvent(event);
}

void MainWindow::sendWinSelect()
{
    QJsonObject infoObject;
    infoObject.insert("wndIndex", m_stWebParam.nWinIndex);
    infoObject.insert("hwnd", m_stWebParam.nHwnd);

    QJsonObject json;
    json.insert("method", "window.clicked");
    json.insert("info", QJsonValue(infoObject));
    json.insert("session", m_stWebParam.nSession);
    json.insert("success", "true");

    SendJsonData(json);
}

void MainWindow::showFullScreen()
{
    m_normalGeo = this->geometry();
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
    QScreen *desk = qApp->screenAt(QCursor::pos());
    QRect rect = desk->availableGeometry();
#else
    QDesktopWidget *desk = qApp->desktop();
    int ScreenNum = desk->screenNumber(QCursor::pos());
    QRect rect = desk->availableGeometry(ScreenNum);
#endif
    setGeometry(rect + QMargins(32,17,17,17));
    QMainWindow::show();
}

void MainWindow::showNormal(const QRect &rect)
{
    if(rect.isNull())
    {
        if(m_normalGeo.isNull())
        {
            m_normalGeo = geometry();
            m_normalGeo.setWidth(geometry().width()/2);
            m_normalGeo.setHeight(geometry().height()/2);
        }

        if(m_normalGeo.width() > width() || m_normalGeo.height() > height())
        {
            m_normalGeo.setWidth(this->width()/2);
            m_normalGeo.setHeight(this->height()/2);
        }

        if(m_normalGeo.y() < 0)
            m_normalGeo.setY(0);

        setGeometry(m_normalGeo);
    }
    else
    {
        setGeometry(m_normalGeo);
    }

    m_bFullScreen = false;

    QMainWindow::show();
}

void MainWindow::on_comboBox_ChangeVideo_activated(int index)
{
    emit sig_setScreenType(index);
}

void MainWindow::on_newConnection()
{
    m_pSocket = m_pWebSocketServer->nextPendingConnection();
    connect(m_pSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(on_processTextMessage(QString)));
    connect(m_pSocket, SIGNAL(disconnected()), this, SLOT(on_socketDisconnected()));

    QString item = m_pSocket->peerAddress().toString();
    MY_DEBUG << item;
    m_clientsList << m_pSocket;
}

void MainWindow::on_socketDisconnected()
{
}

void MainWindow::on_processTextMessage(QString message)
{
    QString time = m_pCurrentDateTime->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
    QString item = m_pSocket->peerAddress().toString();

    //MY_DEBUG << time + "" + item + "\n" + message;

    parseJson(message);
}

void MainWindow::on_pushButton_PrevPage_clicked()
{
    emit sig_prevPage();
}

void MainWindow::on_pushButton_NextPage_clicked()
{
    emit sig_nextPage();
}

void MainWindow::slot_curWinIndex(int nIndex)
{
    m_stWebParam.nWinIndex = nIndex;
    sendWinSelect();
}

void MainWindow::slot_playFailTip(QString sTip)
{
    QMessageBox::critical(this, "myFFmpeg", sTip);
}

void MainWindow::slot_setPageInfo(QString sInfo)
{
    ui->label_PageNumber->setText(sInfo);
}

void MainWindow::slot_fullscreen(bool bFull)
{
    if(bFull)
    {
        m_bFullScreen = true;
        ui->widget_control->hide();
        showFullScreen();
    }
    else
    {
        m_bFullScreen = false;
        ui->widget_control->show();
        showNormal();
    }
}

以上就是C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器的詳細(xì)內(nèi)容,更多關(guān)于Qt音視頻播放器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++簡(jiǎn)單實(shí)現(xiàn)的全排列算法示例

    C++簡(jiǎn)單實(shí)現(xiàn)的全排列算法示例

    這篇文章主要介紹了C++簡(jiǎn)單實(shí)現(xiàn)的全排列算法,結(jié)合實(shí)例形式分析了C++排序操作的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-07-07
  • c++ TCHAR轉(zhuǎn)string導(dǎo)致中文缺失或亂碼問(wèn)題及解決

    c++ TCHAR轉(zhuǎn)string導(dǎo)致中文缺失或亂碼問(wèn)題及解決

    這篇文章主要介紹了c++ TCHAR轉(zhuǎn)string導(dǎo)致中文缺失或亂碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語(yǔ)言中單鏈表(不帶頭結(jié)點(diǎn))基本操作的實(shí)現(xiàn)詳解

    C語(yǔ)言中單鏈表(不帶頭結(jié)點(diǎn))基本操作的實(shí)現(xiàn)詳解

    鏈表是一種物理存儲(chǔ)結(jié)構(gòu)上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)的。本文主要和大家聊聊C語(yǔ)言中單鏈表(不帶頭結(jié)點(diǎn))的基本操作,感興趣的小伙伴可以了解一下
    2022-11-11
  • C++如何獲取鼠標(biāo)點(diǎn)擊位置

    C++如何獲取鼠標(biāo)點(diǎn)擊位置

    這篇文章主要介紹了C++如何獲取鼠標(biāo)點(diǎn)擊位置問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C++ bitset的簡(jiǎn)單使用示例

    C++ bitset的簡(jiǎn)單使用示例

    這篇文章主要介紹了C++ bitset的簡(jiǎn)單使用示例,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-11-11
  • C語(yǔ)言數(shù)據(jù)類型枚舉enum全面詳解示例教程

    C語(yǔ)言數(shù)據(jù)類型枚舉enum全面詳解示例教程

    生活中有很多地方會(huì)用到枚舉,比如一周有7天,可以一一枚舉;性別有男、女...等等都可以可以一一枚舉,今天來(lái)和筆者一起學(xué)習(xí)一下c語(yǔ)言枚舉吧
    2021-10-10
  • 詳解C++泛型裝飾器

    詳解C++泛型裝飾器

    這篇文章主要為大家介紹了C++的泛型裝飾器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-11-11
  • 解析Linux下C++編譯和鏈接

    解析Linux下C++編譯和鏈接

    編譯&鏈接對(duì)C&C++程序員既熟悉又陌生,熟悉在于每份代碼都要經(jīng)歷編譯&鏈接過(guò)程,陌生在于大部分人并不會(huì)刻意關(guān)注編譯&鏈接的原理。本文通過(guò)開發(fā)過(guò)程中碰到的四個(gè)典型問(wèn)題來(lái)探索64位linux下C++編譯&鏈接的那些事。
    2021-05-05
  • C++內(nèi)核對(duì)象封裝單實(shí)例啟動(dòng)程序的類

    C++內(nèi)核對(duì)象封裝單實(shí)例啟動(dòng)程序的類

    這篇文章主要介紹了利用C++內(nèi)核對(duì)象封裝的類,程序只能運(yùn)行單個(gè)實(shí)例,可防止多次啟動(dòng),大家參考使用吧
    2013-11-11
  • C++超詳細(xì)實(shí)現(xiàn)堆和堆排序過(guò)像

    C++超詳細(xì)實(shí)現(xiàn)堆和堆排序過(guò)像

    堆是計(jì)算機(jī)科學(xué)中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱,通常是一個(gè)可以被看做一棵完全二叉樹的數(shù)組對(duì)象。而堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法。本文將通過(guò)圖片詳細(xì)介紹堆排序,需要的可以參考一下
    2022-06-06

最新評(píng)論