ue 切換像素流分辨率

參考文檔

https://docs.unrealengine.com/4.27/zh-CN/SharingAndReleasing/PixelStreaming/PixelStreamingIntro/

https://docs.unrealengine.com/5.0/zh-CN/unreal-engine-pixel-streaming-reference/

準備工作

信令服務 和 前端

可以先把信令服務起起來,如

image-20231206093226748

至於前端的話,參考:

https://www.cnblogs.com/makalochen/p/17803468.html

這裏不做贅述

前端示例

<!DOCTYPE html>
<html>

<head>
	<!-- 該文件處理瀏覽器和虛幻引擎應用間的通信,接受並顯示來自服務器的媒體流。在非必要的情況下,請勿修改此JavaScript文件 -->
	<script type="text/javascript" src="../scripts/webRtcPlayer.js"></script>
	<!-- 此文件將設置處理鍵盤、鼠標和觸摸事件的事件監聽器 -->
	<script type="text/javascript" src="../scripts/app.js"></script>


	<link rel="shortcut icon" href="../images/favicon.ico" type="image/x-icon">
	<link rel="icon" type="../image/png" sizes="96x96" href="/images/favicon-96x96.png">
	<link rel="icon" type="../image/png" sizes="32x32" href="/images/favicon-32x32.png">
	<link rel="icon" type="../image/png" sizes="16x16" href="/images/favicon-16x16.png">
	<link type="text/css" rel="stylesheet" href="player.css">
	<title>myUI</title>
</head>

<body onload="load()">
	<div>
		<button onclick="ueSend('1', '1', '')">晴天</button>
		<button onclick="ueSend('1', '2', '')">雨天</button>
		<button onclick="ueSend('1', '3', '')">雪天</button>
		<button onclick="ueSend('1', '4', '')">霧天</button>
		<button onclick="ueSend2()">設置時間</button> <input type="text" id='setTime'>
		<button onclick="ueSend3('3', '-2', '')">切換到 -2 樓 </button>
		<button onclick="ueSend3('3', '-1', '')">切換到 -1 樓 </button>
		<button onclick="ueSend3('3', '1', '')">切換到 1 樓 </button>
		<button onclick="ueSend3('3', '2', '')">切換到 2 樓 </button>
		<button onclick="ueSend3('3', '3', '')">切換到 3 樓 </button>
		<button onclick="ueSend3('3', '4', '')">切換到 4 樓 </button>
		<button onclick="ueSend3('3', '5', '')">切換到 5 樓 </button>
		<button onclick="ueSend3('3', '6', '')">關閉樓層掀蓋 </button>

		<button id="480P" type="button" class="btn btn-secondary" onclick="setRes(854, 480)">
			<span>480P</span>
		</button>
		<button id="720p" type="button" class="btn btn-secondary" onclick="setRes(1280, 720)">
			<span>720p</span>
		</button>
		<button id="1080p" type="button" class="btn btn-secondary" onclick="setRes(1920, 1080)">
			<span>1080p</span>
		</button>
		<button id="720p" type="button" class="btn btn-secondary" onclick="setRes(2560,1440)">
			<span>2K</span>
		</button>
		<button id="4k" type="button" class="btn btn-secondary" onclick="setRes(3840, 2160)">
			<span>4k</span>
		</button>
	</div>
	<div id="playerUI">
		<div id="player"></div>
		<div id="overlay" class="overlay text-light bg-dark">
		<!-- <div id="overlay" class="overlay text-light bg-dark" hidden="hidden"> -->
			<div>
				<div id="qualityStatus" class="greyStatus">&#9679</div>
				<div id="overlayButton">+</div>
			</div>
			<div id="overlaySettings">
				<div id="kickOthers">
					<div class="settings-text">Kick all other players</div>
					<label class="btn-overlay">
						<input type="button" id="kick-other-players-button" class="overlay-button btn-flat"
							value="Kick">
					</label>
				</div>
				<div id="fillWindow">
					<div class="settings-text">Enlarge Display to Fill Window</div>
					<label class="tgl-switch">
						<input type="checkbox" id="enlarge-display-to-fill-window-tgl" class="tgl tgl-flat" checked>
						<!-- <input type="checkbox" id="enlarge-display-to-fill-window-tgl" class="tgl tgl-flat"> -->
						<div class="tgl-slider"></div>
					</label>
				</div>
				<div id="qualityControlOwnership">
					<div class="settings-text">Quality control ownership</div>
					<label class="tgl-switch">
						<input type="checkbox" id="quality-control-ownership-tgl" class="tgl tgl-flat">
						<div class="tgl-slider"></div>
					</label>
				</div>
				<br>

				<!-- 編碼設置 -->
				<section id="encoderSettings">
					<div class="settings-text">Encoder Settings</div>
					<div id="encoderParamsContainer" class="collapse">
						<div class="form-group">
							<label for="encoder-rate-control" class="settings-text">Rate Control</label>
							<select id="encoder-rate-control">
								<option value="CBR" selected>CBR</option>
								<option value="VBR">VBR</option>
								<option value="ConstQP">ConstQP</option>
							</select>
							<label for="encoder-target-bitrate-text">Target Bitrate (kbps)</label>
							<input type="number" class="form-control" id="encoder-target-bitrate-text" value="0" min="0"
								max="100000" />
							<label for="encoder-max-bitrate-text">Max Bitrate (kbps)</label>
							<input type="number" class="form-control" id="encoder-max-bitrate-text" value="0" min="0"
								max="100000" />
							<label for="encoder-min-qp-text">Min QP</label>
							<input type="number" class="form-control" id="encoder-min-qp-text" value="0" min="0"
								max="999" />
							<label for="encoder-max-qp-text">Max QP</label>
							<input type="number" class="form-control" id="encoder-max-qp-text" value="0" min="0"
								max="999" />
							<label for="encoder-multipass" class="settings-text">Multipass</label>
							<select id="encoder-multipass">
								<option value="DISABLED" selected>DISABLED</option>
								<option value="QUARTER">QUARTER</option>
								<option value="FULL">FULL</option>
							</select>
							<div class="settings-text">Filler Data</div>
							<label class="tgl-switch">
								<input type="checkbox" id="encoder-filler-data-tgl" class="tgl tgl-flat">
								<div class="tgl-slider"></div>
							</label>
						</div>
						<input id="encoder-params-submit" class="btn btn-primary btn-lg mt-3" type="button"
							value="Apply">
					</div>
					<br>
				</section>

				<!-- webRTC 設置 -->
				<section id="webRTCSettings">
					<div class="settings-text">WebRTC Settings</div>
					<div id="webrtcParamsContainer" class="collapse">
						<div class="form-group">
							<label for="webrtc-degradation-pref">Degradation Pref</label>
							<select id="webrtc-degradation-pref">
								<option value="BALANCED">BALANCED</option>
								<option value="MAINTAIN_FRAMERATE">MAINTAIN_FRAMERATE</option>
								<option value="MAINTAIN_RESOLUTION">MAINTAIN_RESOLUTION</option>
							</select>
							<label for="webrtc-max-fps-text">Max FPS</label>
							<input type="number" class="form-control" id="webrtc-max-fps-text" value="1" min="1"
								max="999" />
							<label for="webrtc-min-bitrate-text">Min Bitrate (kbps)</label>
							<input type="number" class="form-control" id="webrtc-min-bitrate-text" value="0" min="0"
								max="100000" />
							<label for="webrtc-max-bitrate-text">Max Bitrate (kbps)</label>
							<input type="number" class="form-control" id="webrtc-max-bitrate-text" value="0" min="0"
								max="100000" />
							<label for="webrtc-low-qp-text">Low QP Threshold</label>
							<input type="number" class="form-control" id="webrtc-low-qp-text" value="0" min="0"
								max="999" />
							<label for="webrtc-high-qp-text">High QP Threshold</label>
							<input type="number" class="form-control" id="webrtc-high-qp-text" value="0" min="0"
								max="999" />
						</div>
						<input id="webrtc-params-submit" class="btn btn-primary btn-lg mt-3" type="button"
							value="Apply">
					</div>
				</section>
				<br>

				<!-- 顯示FPS -->
				<div id="showFPS">
					<div class="settings-text">Show FPS</div>
					<label class="btn-overlay">
						<input type="button" id="show-fps-button" class="overlay-button btn-flat" value="Toggle">
					</label>
				</div>
				<div id="matchViewportResolution">
					<div class="settings-text">Match Viewport Resolution</div>
					<label class="tgl-switch">
						<input type="checkbox" id="match-viewport-res-tgl" class="tgl tgl-flat">
						<div class="tgl-slider"></div>
					</label>
				</div>

				<div id="statsPanel">
					<div class="settings-text">Show Stats</div>
					<label class="tgl-switch">
						<!-- <input type="checkbox" id="show-stats-tgl" class="tgl tgl-flat" checked> -->
						<input type="checkbox" id="show-stats-tgl" class="tgl tgl-flat">
						<div class="tgl-slider"></div>
					</label>
					<div id="statsContainer" class="statsContainer">
						<div id="stats" class="stats"></div>
					</div>
					<br>
				</div>

				<div id="latencyTest">
					<div class="settings-text">Latency Stats</div>
					<label class="btn-overlay">
						<input type="button" id="test-latency-button" class="overlay-button btn-flat"
							value="Test Latency">
					</label>
					<div id="latencyStatsContainer" class="statsContainer">
						<div id=LatencyStats class="stats">No stats yet...</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</body>
<script>
	// 發送到ue
	function api_send(type, action, param, callback) {
		let data = { type, action, param };
		console.log('data ----------->', data);
		// 發送
		emitUIInteraction(data);
		// 註冊ue response 監聽函數
		addResponseEventListener("handle_responses", callback);
	}
	// 發送ue消息-天氣切換
	function ueSend(type, action, param) {
		console.log(`type : ${type}, action : ${action}, param : ${param}`);
		api_send(type, action, param, (info) => {
			console.log(info);
		});
	}
	// 發送ue消息-設置時間
	function ueSend2() {
		const setTime = document.getElementById('setTime').value;
		console.log(`setTime ---------------->, ${setTime}`);
		api_send('2', '', setTime, (info) => {
			console.log(info);
		});
	}
	// 發送ue消息-切換樓層
	function ueSend3(type, action, param) {
		console.log(`type : ${type}, action : ${action}, param : ${param}`);
		api_send(type, action, param, (info) => {
			console.log(info);
		});
	}

	// 重置分辨率
	function setRes(width, height) {
		const param = 'r.' + 'setRes ' + width + 'x' + height + 'w'
		console.log('setRes ->>>>>>>>', param);
		api_send('4', '', param, (info) => {
			console.log(info);
		});
	}
</script>

</html>

創建基礎項目

這裏我們隨便創建了建築可視化項目

image-20231206094511270

ue 的像素流插件

必須先啓用像素流插件

image-20231206093643217

設置獨立進程啓動參數

設置 編輯器偏好設置 -> 關卡編輯器 ->播放 -> 額外啓動參數

-AudioMixer -PixelStreamingIP=localhost -PixelStreamingPort=8888 -forceres -ResX=3840 -ResY=2160

image-20231206093955221

上面的意思是 像素流送 強制 以4K 運行

切換分辨率實現

其實切換分辨率 主要是ue 控制檯使用

r.setRes 1920x1080w

命令實現,上面例子 表示切換到 1080P,所以接下來就是要接收h5 傳過來的消息,並且執行

json結構

假設前端傳過來的,消息結構如下

{
  "type":"4",    // 4 - 表示分辨率切換
  "param": "r.setRes 1920x1080w"    // 分辨率命令 和 參數
}

ue 基礎藍圖功能

新建遊戲基礎模式

image-20231206104423763

image-20231206104452887

GameBaseModel

image-20231206104513796

遊戲模式重載

image-20231206110358218

添加像素流組件

雙擊打開的遊戲模式

image-20231206104731828

image-20231206104750629

添加像素流輸入事件

image-20231206104837751

image-20231206104849456

添加基本的藍圖功能

下面的藍圖功能很簡單就是:

接收前端傳過來的數據,並且 加上 ue response:+ 前端傳過來的數據 返回

image-20231206105110945

我們先測試鏈路通不通

運行測試

image-20231206105318687

image-20231206110526443

可以看到 已經有ue 的返回了

ue 切換分辨率

在上面我們已經實現了,像素流的接收和返回,保證鏈路沒問題,接下來我們就按照json 結構執行切換分辨率的命令

藍圖如下

image-20231206111220016

運行測試

可以看到480P 畫質 有點糊

image-20231206112308918

再看 4K畫質

image-20231206112511090

應該能看出明顯的區別

需要注意的地方

啓動參數

關於虛幻引擎啓動參數,也就是快捷方式啓動參數

4.27 版本官網這塊沒有,但是5.0有,也可以用

參考:

https://docs.unrealengine.com/5.0/zh-CN/unreal-engine-pixel-streaming-reference/

-forceres -ResX=3840 -ResY=2160

需要加上這個,如果不加,使用

r.setRes

是改變不了分辨率的,只會改變獨立進程的窗口大小,在我理解 ,可能像素流插件默認有一個推送分辨率,只會啓動的時候設置,但是如果啓動參數加上

-forceres -ResX=3840 -ResY=2160

這個參數,就會以4K 分辨率推流

r.setRes

則可以修改,接收的分辨率,兩個可以配合使用,缺一不可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章