TDN-M commited on
Commit
658eafa
·
verified ·
1 Parent(s): 8c33d19

Create scripts.js

Browse files
Files changed (1) hide show
  1. scripts.js +187 -0
scripts.js ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Elements
2
+ const videoElement = document.getElementById("live-preview");
3
+ const canvas = document.getElementById("output-canvas");
4
+ const ctx = canvas.getContext("2d");
5
+ const videoSourceSelect = document.getElementById("video-source");
6
+ const videoStatus = document.getElementById("video-status");
7
+ const enableBgRemoval = document.getElementById("enable-bg-removal");
8
+ const showPreview = document.getElementById("show-preview");
9
+ const modelQuality = document.getElementById("model-quality");
10
+ const edgeSmoothness = document.getElementById("edge-smoothness");
11
+ const backgroundBlur = document.getElementById("background-blur");
12
+ const foregroundBrightness = document.getElementById("foreground-brightness");
13
+ const processingTimeDisplay = document.getElementById("processing-time");
14
+ const fpsDisplay = document.getElementById("fps");
15
+ const copyUrlButton = document.getElementById("copy-url");
16
+ const customImageInput = document.getElementById("custom-image-input");
17
+ const customVideoInput = document.getElementById("custom-video-input");
18
+
19
+ // Canvas setup
20
+ canvas.width = 1920;
21
+ canvas.height = 1080;
22
+
23
+ // Variables
24
+ let customImage = null;
25
+ let customVideo = null;
26
+ let lastFrameTime = performance.now();
27
+ let currentBackground = "transparent";
28
+
29
+ // Populate video sources
30
+ async function populateVideoSources() {
31
+ try {
32
+ const devices = await navigator.mediaDevices.enumerateDevices();
33
+ videoSourceSelect.innerHTML = '<option value="">Select a video source</option>';
34
+ devices
35
+ .filter((device) => device.kind === "videoinput")
36
+ .forEach((device) => {
37
+ const option = document.createElement("option");
38
+ option.value = device.deviceId;
39
+ option.text = device.label || `Camera ${videoSourceSelect.options.length}`;
40
+ videoSourceSelect.appendChild(option);
41
+ });
42
+ } catch (err) {
43
+ console.error("Lỗi khi liệt kê thiết bị video:", err);
44
+ videoStatus.textContent = "Không thể liệt kê thiết bị video.";
45
+ }
46
+ }
47
+
48
+ // Start video stream
49
+ async function startVideo(deviceId) {
50
+ try {
51
+ const stream = await navigator.mediaDevices.getUserMedia({
52
+ video: { deviceId: deviceId ? { exact: deviceId } : undefined },
53
+ });
54
+ videoElement.srcObject = stream;
55
+ videoElement.play();
56
+ videoStatus.textContent = "";
57
+ processFrame();
58
+ } catch (err) {
59
+ console.error("Lỗi khi truy cập webcam:", err);
60
+ videoStatus.textContent = "Không thể truy cập webcam. Vui lòng kiểm tra quyền camera.";
61
+ }
62
+ }
63
+
64
+ // Simulated background removal (replace with real AI model in production)
65
+ function simulateBackgroundRemoval(imageData) {
66
+ const data = imageData.data;
67
+ for (let i = 0; i < data.length; i += 4) {
68
+ // Simple green-screen-like removal (replace with AI model output)
69
+ const r = data[i];
70
+ const g = data[i + 1];
71
+ const b = data[i + 2];
72
+ // Example: Remove pixels with high green value
73
+ if (g > 150 && r < 100 && b < 100) {
74
+ data[i + 3] = 0; // Set alpha to 0 (transparent)
75
+ }
76
+ }
77
+ return imageData;
78
+ }
79
+
80
+ // Process video frame
81
+ function processFrame() {
82
+ const startTime = performance.now();
83
+
84
+ // Draw video to canvas
85
+ ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
86
+
87
+ // Apply background removal if enabled
88
+ if (enableBgRemoval.checked) {
89
+ let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
90
+ imageData = simulateBackgroundRemoval(imageData); // Replace with AI model
91
+ ctx.putImageData(imageData, 0, 0);
92
+
93
+ // Apply background
94
+ const tempCanvas = document.createElement("canvas");
95
+ tempCanvas.width = canvas.width;
96
+ tempCanvas.height = canvas.height;
97
+ const tempCtx = tempCanvas.getContext("2d");
98
+
99
+ // Draw background
100
+ if (currentBackground === "solid-black") {
101
+ tempCtx.fillStyle = "black";
102
+ tempCtx.fillRect(0, 0, canvas.width, canvas.height);
103
+ } else if (currentBackground === "solid-gray") {
104
+ tempCtx.fillStyle = "gray";
105
+ tempCtx.fillRect(0, 0, canvas.width, canvas.height);
106
+ } else if (currentBackground === "solid-green") {
107
+ tempCtx.fillStyle = "green";
108
+ tempCtx.fillRect(0, 0, canvas.width, canvas.height);
109
+ } else if (currentBackground === "custom-image" && customImage) {
110
+ tempCtx.drawImage(customImage, 0, 0, canvas.width, canvas.height);
111
+ } else if (currentBackground === "custom-video" && customVideo) {
112
+ tempCtx.drawImage(customVideo, 0, 0, canvas.width, canvas.height);
113
+ } else if (currentBackground === "blurred") {
114
+ tempCtx.filter = `blur(${backgroundBlur.value}px)`;
115
+ tempCtx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
116
+ }
117
+
118
+ // Draw foreground
119
+ tempCtx.globalCompositeOperation = "destination-over";
120
+ tempCtx.drawImage(canvas, 0, 0);
121
+
122
+ // Apply brightness
123
+ tempCtx.filter = `brightness(${foregroundBrightness.value})`;
124
+ tempCtx.drawImage(tempCanvas, 0, 0);
125
+
126
+ // Copy to main canvas
127
+ ctx.filter = `blur(${edgeSmoothness.value}px)`; // Edge smoothness
128
+ ctx.drawImage(tempCanvas, 0, 0);
129
+ }
130
+
131
+ // Update performance metrics
132
+ const endTime = performance.now();
133
+ const processingTime = endTime - startTime;
134
+ processingTimeDisplay.textContent = `${processingTime.toFixed(2)} ms`;
135
+ fpsDisplay.textContent = `${(1000 / processingTime).toFixed(2)}`;
136
+ lastFrameTime = endTime;
137
+
138
+ // Continue processing
139
+ requestAnimationFrame(processFrame);
140
+ }
141
+
142
+ // Event listeners
143
+ videoSourceSelect.addEventListener("change", () => {
144
+ startVideo(videoSourceSelect.value);
145
+ });
146
+
147
+ showPreview.addEventListener("change", () => {
148
+ videoElement.style.display = showPreview.checked ? "block" : "none";
149
+ });
150
+
151
+ document.querySelectorAll('input[name="background"]').forEach((input) => {
152
+ input.addEventListener("change", () => {
153
+ currentBackground = input.value;
154
+ });
155
+ });
156
+
157
+ customImageInput.addEventListener("change", (e) => {
158
+ const file = e.target.files[0];
159
+ if (file) {
160
+ customImage = new Image();
161
+ customImage.src = URL.createObjectURL(file);
162
+ currentBackground = "custom-image";
163
+ document.querySelector('input[value="custom-image"]').checked = true;
164
+ }
165
+ });
166
+
167
+ customVideoInput.addEventListener("change", (e) => {
168
+ const file = e.target.files[0];
169
+ if (file) {
170
+ customVideo = document.createElement("video");
171
+ customVideo.src = URL.createObjectURL(file);
172
+ customVideo.loop = true;
173
+ customVideo.play();
174
+ currentBackground = "custom-video";
175
+ document.querySelector('input[value="custom-video"]').checked = true;
176
+ }
177
+ });
178
+
179
+ copyUrlButton.addEventListener("click", () => {
180
+ const url = window.location.href;
181
+ navigator.clipboard.writeText(url).then(() => {
182
+ alert("Đã sao chép URL nguồn trình duyệt OBS!");
183
+ });
184
+ });
185
+
186
+ // Initialize
187
+ populateVideoSources();