mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 01:00:29 +08:00
parent
6fbfc2b343
commit
1a13760df0
2
Makefile
2
Makefile
@ -331,7 +331,7 @@ run-nogpio: testenv
|
|||||||
&& cp /usr/share/kvmd/configs.default/kvmd/*.yaml /etc/kvmd \
|
&& cp /usr/share/kvmd/configs.default/kvmd/*.yaml /etc/kvmd \
|
||||||
&& cp /usr/share/kvmd/configs.default/kvmd/*passwd /etc/kvmd \
|
&& cp /usr/share/kvmd/configs.default/kvmd/*passwd /etc/kvmd \
|
||||||
&& cp /usr/share/kvmd/configs.default/kvmd/*.secret /etc/kvmd \
|
&& cp /usr/share/kvmd/configs.default/kvmd/*.secret /etc/kvmd \
|
||||||
&& cp /usr/share/kvmd/configs.default/kvmd/main/$(if $(P),$(P),$(DEFAULT_PLATFORM)).yaml /etc/kvmd/main.yaml \
|
&& cp /usr/share/kvmd/configs.default/kvmd/main.yaml /etc/kvmd/main.yaml \
|
||||||
&& ln -s /testenv/web.css /etc/kvmd/web.css \
|
&& ln -s /testenv/web.css /etc/kvmd/web.css \
|
||||||
&& mkdir -p /etc/kvmd/override.d \
|
&& mkdir -p /etc/kvmd/override.d \
|
||||||
&& cp /testenv/$(if $(P),$(P),$(DEFAULT_PLATFORM)).override.yaml /etc/kvmd/override.yaml \
|
&& cp /testenv/$(if $(P),$(P),$(DEFAULT_PLATFORM)).override.yaml /etc/kvmd/override.yaml \
|
||||||
|
|||||||
@ -18,7 +18,7 @@ kvmd:
|
|||||||
streamer:
|
streamer:
|
||||||
cmd:
|
cmd:
|
||||||
- "/usr/bin/ustreamer"
|
- "/usr/bin/ustreamer"
|
||||||
- "--device=/dev/kvmd-video"
|
- "--device=/dev/video0"
|
||||||
- "--persistent"
|
- "--persistent"
|
||||||
- "--format=mjpeg"
|
- "--format=mjpeg"
|
||||||
- "--resolution={resolution}"
|
- "--resolution={resolution}"
|
||||||
|
|||||||
@ -259,6 +259,11 @@
|
|||||||
<button class="row33" data-force-hide-menu id="stream-screenshot-button" i18n="kvm_text21">• Screenshot</button>
|
<button class="row33" data-force-hide-menu id="stream-screenshot-button" i18n="kvm_text21">• Screenshot</button>
|
||||||
<button class="row33" id="stream-reset-button" i18n="kvm_text22">Reset stream</button>
|
<button class="row33" id="stream-reset-button" i18n="kvm_text22">Reset stream</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="text"><b i18n="kvm_text79">Video Record<br></b><sub i18n="kvm_text80">Record video using the browser API, and will be downloaded automatically</sub></div>
|
||||||
|
<div class="buttons buttons-row">
|
||||||
|
<button class="row50" data-force-hide-menu id="stream-record-start-button" i18n="kvm_text81">• Start recording</button>
|
||||||
|
<button class="row50" data-force-hide-menu id="stream-record-stop-button" i18n="kvm_text82">• End recording</button>
|
||||||
|
</div>
|
||||||
<div class="feature-disabled" id="hid-outputs">
|
<div class="feature-disabled" id="hid-outputs">
|
||||||
<hr>
|
<hr>
|
||||||
<table class="kv">
|
<table class="kv">
|
||||||
@ -897,6 +902,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<canvas class="hidden" id="stream-mjpeg-canvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="window" id="keyboard-window">
|
<div class="window" id="keyboard-window">
|
||||||
<div class="window-header" id="keyboard-window-header">
|
<div class="window-header" id="keyboard-window-header">
|
||||||
|
|||||||
@ -71,6 +71,12 @@ li(id="system-dropdown" class="right")
|
|||||||
button(data-force-hide-menu data-show-window="stream-window" class="row33" i18n="kvm_text20") • Show stream
|
button(data-force-hide-menu data-show-window="stream-window" class="row33" i18n="kvm_text20") • Show stream
|
||||||
button(data-force-hide-menu id="stream-screenshot-button" class="row33" i18n="kvm_text21") • Screenshot
|
button(data-force-hide-menu id="stream-screenshot-button" class="row33" i18n="kvm_text21") • Screenshot
|
||||||
button(id="stream-reset-button" class="row33" i18n="kvm_text22") Reset stream
|
button(id="stream-reset-button" class="row33" i18n="kvm_text22") Reset stream
|
||||||
|
div(class="text")
|
||||||
|
b(i18n="kvm_text79") Video Record#[br]
|
||||||
|
sub(i18n="kvm_text80") Record video using the browser API, and will be downloaded automatically
|
||||||
|
div(class="buttons buttons-row")
|
||||||
|
button(data-force-hide-menu id="stream-record-start-button" class="row50" i18n="kvm_text81") • Start recording
|
||||||
|
button(data-force-hide-menu id="stream-record-stop-button" class="row50" i18n="kvm_text82") • End recording
|
||||||
div(id="hid-outputs" class="feature-disabled")
|
div(id="hid-outputs" class="feature-disabled")
|
||||||
hr
|
hr
|
||||||
table(class="kv")
|
table(class="kv")
|
||||||
|
|||||||
@ -46,3 +46,4 @@ div(id="stream-window" class="window window-resizable")
|
|||||||
div(class="label") Up
|
div(class="label") Up
|
||||||
div(data-code="down" class="key small rounded-right")
|
div(data-code="down" class="key small rounded-right")
|
||||||
div(class="label") Down
|
div(class="label") Down
|
||||||
|
canvas(id="stream-mjpeg-canvas" class="hidden")
|
||||||
|
|||||||
@ -109,6 +109,10 @@
|
|||||||
"kvm_text76":"Connect drive to Server",
|
"kvm_text76":"Connect drive to Server",
|
||||||
"kvm_text77":"Disconnect",
|
"kvm_text77":"Disconnect",
|
||||||
"kvm_text78":"Reset",
|
"kvm_text78":"Reset",
|
||||||
|
"kvm_text79":"Video Record<br>",
|
||||||
|
"kvm_text80":"Record video using the browser API, and will be downloaded automatically",
|
||||||
|
"kvm_text81":"Start recording",
|
||||||
|
"kvm_text82":"End recording",
|
||||||
|
|
||||||
"atx-ask-switch":"Ask click confirmation",
|
"atx-ask-switch":"Ask click confirmation",
|
||||||
"hid-recorder-loop-switch":"Infinite loop playback",
|
"hid-recorder-loop-switch":"Infinite loop playback",
|
||||||
|
|||||||
@ -109,6 +109,10 @@
|
|||||||
"kvm_text76":"连接 MSD 到主机",
|
"kvm_text76":"连接 MSD 到主机",
|
||||||
"kvm_text77":"断开连接",
|
"kvm_text77":"断开连接",
|
||||||
"kvm_text78":"重置",
|
"kvm_text78":"重置",
|
||||||
|
"kvm_text79":"视频录制<br>",
|
||||||
|
"kvm_text80":"使用浏览器 API 录制视频(无音频),结束录制后视频文件会自动下载",
|
||||||
|
"kvm_text81":"开始录制",
|
||||||
|
"kvm_text82":"结束录制",
|
||||||
|
|
||||||
"atx-ask-switch":"点击二次确认",
|
"atx-ask-switch":"点击二次确认",
|
||||||
"hid-recorder-loop-switch":"无限循环重放",
|
"hid-recorder-loop-switch":"无限循环重放",
|
||||||
|
|||||||
@ -97,9 +97,15 @@ export function Streamer() {
|
|||||||
|
|
||||||
tools.el.setOnClick($("stream-screenshot-button"), __clickScreenshotButton);
|
tools.el.setOnClick($("stream-screenshot-button"), __clickScreenshotButton);
|
||||||
tools.el.setOnClick($("stream-reset-button"), __clickResetButton);
|
tools.el.setOnClick($("stream-reset-button"), __clickResetButton);
|
||||||
|
tools.el.setOnClick($("stream-record-start-button"), __clickRecordStartButton);
|
||||||
|
tools.el.setOnClick($("stream-record-stop-button"), __clickRecordStopButton);
|
||||||
|
|
||||||
|
|
||||||
$("stream-window").show_hook = () => __applyState(__state);
|
$("stream-window").show_hook = () => __applyState(__state);
|
||||||
$("stream-window").close_hook = () => __applyState(null);
|
$("stream-window").close_hook = () => __applyState(null);
|
||||||
|
|
||||||
|
//hidden stream-record-stop-button
|
||||||
|
document.getElementById('stream-record-stop-button').disabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
@ -304,6 +310,77 @@ export function Streamer() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var stream_mjpeg_refresh_img;
|
||||||
|
var stream_now_fps
|
||||||
|
let mediaRecorder;
|
||||||
|
var __clickRecordStartButton = function() {
|
||||||
|
wm.confirm("Are you sure you want to record stream?").then(function (ok) {
|
||||||
|
if (ok) {
|
||||||
|
stream_now_fps = tools.slider.getValue($("stream-desired-fps-slider"));
|
||||||
|
let recordedBlobs = [];
|
||||||
|
//"mjpeg" or "janus"
|
||||||
|
let stream_type = document.querySelector('input[name="stream-mode-radio"]:checked').value;
|
||||||
|
if ( stream_type == "mjpeg"){
|
||||||
|
|
||||||
|
var stream_mjpeg_img = document.getElementById('stream-image');
|
||||||
|
var stream_mjpeg_canvas = document.getElementById('stream-mjpeg-canvas');
|
||||||
|
var ctx = stream_mjpeg_canvas.getContext('2d');
|
||||||
|
stream_mjpeg_canvas.width = stream_mjpeg_img.width;
|
||||||
|
stream_mjpeg_canvas.height = stream_mjpeg_img.height;
|
||||||
|
const stream = stream_mjpeg_canvas.captureStream(stream_now_fps); // Capture FPS
|
||||||
|
mediaRecorder = new MediaRecorder(stream);
|
||||||
|
}else{
|
||||||
|
const stream = document.getElementById("stream-video")
|
||||||
|
stream.captureStream = stream.captureStream || stream.mozCaptureStream;
|
||||||
|
mediaRecorder = new MediaRecorder(stream.captureStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mediaRecorder.ondataavailable = function(event) {
|
||||||
|
if (event.data && event.data.size > 0) {
|
||||||
|
recordedBlobs.push(event.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaRecorder.onstop = function() {
|
||||||
|
const blob = new Blob(recordedBlobs, {type: 'video/webm'});
|
||||||
|
var url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
document.body.appendChild(a);
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = ('0' + (now.getMonth() + 1)).slice(-2);
|
||||||
|
const day = ('0' + now.getDate()).slice(-2);
|
||||||
|
const hours = ('0' + now.getHours()).slice(-2);
|
||||||
|
const minutes = ('0' + now.getMinutes()).slice(-2);
|
||||||
|
const seconds = ('0' + now.getSeconds()).slice(-2);//Get now time
|
||||||
|
a.style = "display: none";
|
||||||
|
a.href = url;
|
||||||
|
a.download = stream_type +"_"+ year + month + day + hours + minutes + seconds + ".webm";
|
||||||
|
a.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaRecorder.start();
|
||||||
|
document.getElementById('stream-record-start-button').disabled = true;
|
||||||
|
document.getElementById('stream-record-stop-button').disabled = false;
|
||||||
|
if (stream_type == "mjpeg"){
|
||||||
|
stream_mjpeg_refresh_img = setInterval(function() {
|
||||||
|
ctx.drawImage(stream_mjpeg_img, 0, 0, stream_mjpeg_img.width, stream_mjpeg_img.height);
|
||||||
|
}, 1000 / stream_now_fps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var __clickRecordStopButton = function() {
|
||||||
|
mediaRecorder.stop();
|
||||||
|
clearInterval(stream_mjpeg_refresh_img);
|
||||||
|
document.getElementById('stream-record-start-button').disabled = false;
|
||||||
|
document.getElementById('stream-record-stop-button').disabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
var __sendParam = function(name, value) {
|
var __sendParam = function(name, value) {
|
||||||
tools.httpPost(`/api/streamer/set_params?${name}=${value}`, function(http) {
|
tools.httpPost(`/api/streamer/set_params?${name}=${value}`, function(http) {
|
||||||
if (http.status !== 200) {
|
if (http.status !== 200) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user