mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-11 01:55:43 +00:00
15bca36787
Enables hardware-accelerated video for the CDAP/OS-agent rdclient path instead of being stuck on 1-2fps MJPEG, including over plain HTTP (no HTTPS/domain/cert required). Browser viewers (web-nodejs): cdap-adapter.js and cdap-desktop.js now decode video via the shared RDVideo pipeline. WebCodecs (AV1/VP9/H264, hardware-accelerated) is used in secure contexts (HTTPS/localhost); over plain HTTP, H.264 is decoded through JMuxer/MSE using the browser's native (usually GPU) decoder. Viewers advertise decodableCodecs() in the desktop_start init payload so the agent sends a real GPU stream; MJPEG/WebP remain safe fallbacks. cdap-device.ejs preloads jmuxer + RDVideo. Go agent (betterdesk-agent): codec.go + codec_framing.go add multi-codec engine with GPU encoder probing and selection order AV1 -> VP9 -> H264 -> WebP; desktop.go intersects the operator-advertised codec list with local encoder ability and emits honest desktop_meta (format + codec_string); config.go adds codec config fields. Go server (betterdesk-server): cdap_handlers.go + cdap/desktop.go thread the codecs[] / video_codec fields through desktop_start so operator codec advertisement reaches the agent. Tauri agent-client: config.rs/sidecar.rs/commands.rs codec plumbing, SettingsPanel codec dropdown + en/pl/zh i18n, refreshed agent sidecar binary. Note: AV1/VP9 still require WebCodecs (HTTPS/localhost); H.264-over-MSE covers the plain-HTTP case. Self-signed HTTPS (installer SSL menu option C) unlocks all codecs. Fully backward compatible. This commit was made possible thanks to Insolve.
117 lines
5.4 KiB
HTML
117 lines
5.4 KiB
HTML
<%- include('layouts/main', {
|
|
title: _('cdap.device_detail'),
|
|
pageStyles: ['cdap'],
|
|
pageScripts: ['vendor/jmuxer.min', 'rdclient/video', 'cdap-widgets', 'cdap-commands', 'cdap-terminal', 'cdap-desktop', 'cdap-video', 'cdap-filebrowser', 'cdap-audio'],
|
|
currentPage: 'devices',
|
|
breadcrumb: [
|
|
{ label: _('nav.devices'), href: '/devices' },
|
|
{ label: _('cdap.device_detail') }
|
|
],
|
|
body: `
|
|
<div class="cdap-device-page" data-device-id="${deviceId}">
|
|
<!-- Device Header -->
|
|
<div class="cdap-device-header">
|
|
<div class="cdap-device-title">
|
|
<a href="/devices" class="btn-icon cdap-back-btn" title="${_('common.back')}">
|
|
<span class="material-icons">arrow_back</span>
|
|
</a>
|
|
<div class="cdap-device-identity">
|
|
<h1 id="cdap-device-name">${deviceId}</h1>
|
|
<div class="cdap-device-meta" id="cdap-device-meta">
|
|
<span class="cdap-meta-item" id="cdap-device-type">
|
|
<span class="material-icons">memory</span>
|
|
<span>—</span>
|
|
</span>
|
|
<span class="cdap-meta-item" id="cdap-device-version">
|
|
<span class="material-icons">info_outline</span>
|
|
<span>—</span>
|
|
</span>
|
|
<span class="cdap-meta-item" id="cdap-device-uptime">
|
|
<span class="material-icons">schedule</span>
|
|
<span>—</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="cdap-device-status" id="cdap-device-status">
|
|
<span class="cdap-status-dot"></span>
|
|
<span class="cdap-status-text">${_('cdap.loading')}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Connection Banner (shown when disconnected) -->
|
|
<div class="cdap-offline-banner hidden" id="cdap-offline-banner">
|
|
<span class="material-icons">cloud_off</span>
|
|
<span>${_('cdap.device_offline_msg')}</span>
|
|
</div>
|
|
|
|
<!-- Active Alerts Panel -->
|
|
<div class="cdap-alerts-panel hidden" id="cdap-alerts-panel">
|
|
<div class="cdap-alerts-header">
|
|
<h3>
|
|
<span class="material-icons">warning</span>
|
|
${_('cdap.active_alerts')}
|
|
<span class="cdap-alerts-count" id="cdap-alerts-count">0</span>
|
|
</h3>
|
|
</div>
|
|
<div class="cdap-alerts-list" id="cdap-alerts-list">
|
|
<!-- Alert items rendered by cdap-widgets.js -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Linked Devices Panel -->
|
|
<div class="cdap-linked-panel" id="cdap-linked-panel">
|
|
<div class="cdap-linked-header">
|
|
<h3>
|
|
<span class="material-icons">device_hub</span>
|
|
${_('cdap.linked_devices')}
|
|
<span class="cdap-linked-count" id="cdap-linked-count">0</span>
|
|
</h3>
|
|
<button class="btn-sm btn-accent" id="cdap-link-btn" title="${_('cdap.link_device')}">
|
|
<span class="material-icons">add_link</span>
|
|
<span>${_('cdap.link_device')}</span>
|
|
</button>
|
|
</div>
|
|
<div class="cdap-linked-list" id="cdap-linked-list">
|
|
<div class="cdap-linked-empty" id="cdap-linked-empty">
|
|
<span class="material-icons">link_off</span>
|
|
<span>${_('cdap.no_linked_devices')}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Widget Grid -->
|
|
<div class="cdap-widget-grid" id="cdap-widget-grid">
|
|
<!-- Widgets rendered by cdap-widgets.js -->
|
|
<div class="cdap-loading" id="cdap-loading">
|
|
<div class="cdap-loading-spinner"></div>
|
|
<p>${_('cdap.loading_widgets')}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Empty State (no manifest) -->
|
|
<div class="cdap-empty hidden" id="cdap-empty">
|
|
<span class="material-icons cdap-empty-icon">widgets</span>
|
|
<h3>${_('cdap.no_widgets')}</h3>
|
|
<p>${_('cdap.no_widgets_desc')}</p>
|
|
</div>
|
|
|
|
<!-- Command Log -->
|
|
<div class="cdap-command-log hidden" id="cdap-command-log">
|
|
<div class="cdap-command-log-header">
|
|
<h3>
|
|
<span class="material-icons">terminal</span>
|
|
${_('cdap.command_log')}
|
|
</h3>
|
|
<button class="btn-icon" id="cdap-clear-log" title="${_('cdap.clear_log')}">
|
|
<span class="material-icons">delete_sweep</span>
|
|
</button>
|
|
</div>
|
|
<div class="cdap-command-log-entries" id="cdap-log-entries">
|
|
<!-- Command log entries appended by cdap-commands.js -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`
|
|
}) %>
|