From 372c59e2c828d3c8399cb1431c099b611ca97c2b Mon Sep 17 00:00:00 2001
From: KiritoFD <2896197024@qq.com>
Date: Thu, 23 Jan 2025 12:43:20 +0800
Subject: [PATCH 1/3] added room management
---
config/settings.py | 37 ++
frontend/pages/display.html | 329 +++++++++++++++++-
model/xiadie/1.png | Bin 0 -> 35020 bytes
model/xiadie/2.bmp | Bin 0 -> 327414 bytes
model/xiadie/234.jpg | Bin 0 -> 20893 bytes
model/xiadie/31.bmp | Bin 0 -> 327414 bytes
model/xiadie/SP0d_20190820_005614.bmp | Bin 0 -> 1920054 bytes
model/xiadie/a4.bmp | Bin 0 -> 196662 bytes
model/xiadie/ah1.bmp | Bin 0 -> 66614 bytes
model/xiadie/bq.png | Bin 0 -> 135773 bytes
model/xiadie/mc1.png | Bin 0 -> 64509 bytes
model/xiadie/mc3.png | Bin 0 -> 17432 bytes
model/xiadie/toon3.png | Bin 0 -> 3863 bytes
model/xiadie/toon4.png | Bin 0 -> 3697 bytes
model/xiadie/xiadie_model.py | 40 +++
...7\347\224\250\350\247\204\345\210\231.txt" | 15 +
...\342\200\224\351\201\220\350\235\2662.pmx" | Bin 0 -> 3376163 bytes
.../xiadie/\347\204\260\350\211\262_UV.png" | Bin 0 -> 930286 bytes
"model/xiadie/\350\241\243+.png" | Bin 0 -> 5098457 bytes
"model/xiadie/\350\241\243.png" | Bin 0 -> 5386002 bytes
"model/xiadie/\350\241\2432+.png" | Bin 0 -> 2162871 bytes
"model/xiadie/\350\241\2432.png" | Bin 0 -> 1992716 bytes
"model/xiadie/\351\242\234.png" | Bin 0 -> 190528 bytes
"model/xiadie/\351\242\234\350\265\244.tga" | Bin 0 -> 4194348 bytes
"model/xiadie/\351\253\252.png" | Bin 0 -> 1763300 bytes
"model/xiadie/\351\273\221.jpg" | Bin 0 -> 3178 bytes
render/test_expressions.py | 1 +
run.py | 68 +++-
28 files changed, 481 insertions(+), 9 deletions(-)
create mode 100644 model/xiadie/1.png
create mode 100644 model/xiadie/2.bmp
create mode 100644 model/xiadie/234.jpg
create mode 100644 model/xiadie/31.bmp
create mode 100644 model/xiadie/SP0d_20190820_005614.bmp
create mode 100644 model/xiadie/a4.bmp
create mode 100644 model/xiadie/ah1.bmp
create mode 100644 model/xiadie/bq.png
create mode 100644 model/xiadie/mc1.png
create mode 100644 model/xiadie/mc3.png
create mode 100644 model/xiadie/toon3.png
create mode 100644 model/xiadie/toon4.png
create mode 100644 model/xiadie/xiadie_model.py
create mode 100644 "model/xiadie/\344\275\277\347\224\250\350\247\204\345\210\231.txt"
create mode 100644 "model/xiadie/\346\230\237\347\251\271\351\223\201\351\201\223\342\200\224\351\201\220\350\235\2662.pmx"
create mode 100644 "model/xiadie/\347\204\260\350\211\262_UV.png"
create mode 100644 "model/xiadie/\350\241\243+.png"
create mode 100644 "model/xiadie/\350\241\243.png"
create mode 100644 "model/xiadie/\350\241\2432+.png"
create mode 100644 "model/xiadie/\350\241\2432.png"
create mode 100644 "model/xiadie/\351\242\234.png"
create mode 100644 "model/xiadie/\351\242\234\350\265\244.tga"
create mode 100644 "model/xiadie/\351\253\252.png"
create mode 100644 "model/xiadie/\351\273\221.jpg"
diff --git a/config/settings.py b/config/settings.py
index 40a60cf..4711aae 100644
--- a/config/settings.py
+++ b/config/settings.py
@@ -132,4 +132,41 @@
'edge': 0.3
}
}
+}
+
+XIADIE_CONFIG = {
+ 'model_path': 'model/xiadie/model.pth',
+ 'device': 'cuda', # 或 'cpu'
+ 'batch_size': 1,
+ 'input_size': (256, 256),
+ # 其他配置参数...
+}
+
+# 添加 Jitsi Meet 配置
+JITSI_CONFIG = {
+ 'domain': 'meet.jit.si',
+ 'options': {
+ 'width': '100%',
+ 'height': '100%',
+ 'configOverwrite': {
+ 'startWithAudioMuted': False,
+ 'startWithVideoMuted': True,
+ 'disableDeepLinking': True
+ },
+ 'interfaceConfigOverwrite': {
+ 'TOOLBAR_BUTTONS': [
+ 'microphone', 'camera', 'closedcaptions', 'desktop',
+ 'fullscreen', 'hangup', 'chat', 'settings', 'raisehand',
+ 'videoquality', 'filmstrip', 'shortcuts'
+ ]
+ }
+ }
+}
+
+# 添加 WebSocket 配置
+SOCKET_CONFIG = {
+ 'ping_timeout': 60,
+ 'ping_interval': 25,
+ 'cors_allowed_origins': '*',
+ 'max_http_buffer_size': 1e8
}
\ No newline at end of file
diff --git a/frontend/pages/display.html b/frontend/pages/display.html
index 3b81075..67700a2 100644
--- a/frontend/pages/display.html
+++ b/frontend/pages/display.html
@@ -6,6 +6,7 @@
Meeting Scene Saver
+
@@ -618,6 +681,7 @@ Meeting Scene Saver
![摄像头预览]()
+
@@ -714,7 +778,16 @@
相机参数设置
-
+
+
+
姿态会议
+
+
+
+
+
+
+
@@ -769,7 +842,18 @@
音频流状态
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1039,6 +1123,247 @@
音频流状态
}
});
});
+
+ let xiaoDieActive = false;
+
+ async function startXiaoDie() {
+ xiaoDieActive = true;
+ while (xiaoDieActive) {
+ try {
+ const response = await fetch('/process_frame', {
+ method: 'POST'
+ });
+ const data = await response.json();
+
+ if (data.success) {
+ updateDisplay(data.result);
+ }
+ } catch (error) {
+ console.error('处理失败:', error);
+ }
+ await new Promise(r => setTimeout(r, 100)); // 控制处理频率
+ }
+ }
+
+ function stopXiaoDie() {
+ xiaoDieActive = false;
+ }
+
+ function updateDisplay(result) {
+ // 更新界面显示
+ const display = document.querySelector('.result-display');
+ // 根据结果更新显示内容
+ }
+
+ let jitsiApi = null;
+ let poseSocket = null;
+
+ // 添加重连逻辑
+ let reconnectAttempts = 0;
+ const MAX_RECONNECT_ATTEMPTS = 3;
+
+ function handleConnectionError() {
+ if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
+ console.log(`尝试重连... (${reconnectAttempts + 1}/${MAX_RECONNECT_ATTEMPTS})`);
+ reconnectAttempts++;
+ setTimeout(() => {
+ startPoseMeeting();
+ }, 2000 * reconnectAttempts);
+ } else {
+ alert('连接失败,请检查网络后重试');
+ leavePoseMeeting();
+ }
+ }
+
+ // 添加网络质量监控
+ function monitorNetworkQuality() {
+ if (jitsiApi) {
+ jitsiApi.addEventListener('connectionQualityChanged', (quality) => {
+ if (quality === 'poor') {
+ // 网络质量差时降低姿态数据发送频率
+ adjustPoseDataRate(0.5); // 降低50%发送率
+ } else {
+ adjustPoseDataRate(1.0); // 恢复正常发送率
+ }
+ });
+ }
+ }
+
+ function adjustPoseDataRate(factor) {
+ const newInterval = Math.round(
+ JITSI_CONFIG.options.configOverwrite.poseDataInterval / factor
+ );
+ if (poseTransmissionInterval) {
+ clearInterval(poseTransmissionInterval);
+ startPoseDataTransmission(newInterval);
+ }
+ }
+
+ // 使用现有的姿态检测系统
+ let poseDetector = null;
+ let poseBinder = null;
+ let poseDeformer = null;
+ let poseTransmissionInterval = null;
+
+ async function initPoseSystem() {
+ try {
+ // 初始化姿态检测器
+ poseDetector = new PoseDetector({
+ ...MEDIAPIPE_CONFIG.pose
+ });
+
+ // 初始化姿态绑定器
+ poseBinder = new PoseBinder();
+
+ // 初始化变形器
+ poseDeformer = new PoseDeformer();
+
+ return true;
+ } catch (error) {
+ console.error('初始化姿态系统失败:', error);
+ return false;
+ }
+ }
+
+ async function startPoseMeeting() {
+ // 1. 初始化姿态系统
+ if (!await initPoseSystem()) {
+ alert('姿态系统初始化失败');
+ return;
+ }
+
+ // 2. 启动 Jitsi Meet
+ const options = {
+ ...JITSI_CONFIG.options,
+ roomName: 'PoseMeeting_' + Math.random().toString(36).substring(7),
+ parentNode: document.querySelector('#meetContainer'),
+ configOverwrite: {
+ startWithAudioMuted: false,
+ startWithVideoMuted: true // 关闭视频,只传输姿态
+ }
+ };
+
+ document.getElementById('meetContainer').style.display = 'block';
+ jitsiApi = new JitsiMeetExternalAPI(domain, options);
+
+ // 3. 启动姿态捕捉和传输
+ startPoseCapture();
+ }
+
+ function startPoseCapture() {
+ if (!poseDetector || !poseBinder || !poseDeformer) {
+ console.error('姿态系统未初始化');
+ return;
+ }
+
+ poseTransmissionInterval = setInterval(async () => {
+ try {
+ // 1. 获取当前帧
+ const frame = await captureFrame();
+
+ // 2. 检测姿态
+ const poseData = await poseDetector.detectPose(frame);
+
+ // 3. 处理姿态数据
+ if (poseData) {
+ // 创建或更新绑定
+ const binding = poseBinder.createBinding(frame, poseData);
+
+ // 应用变形
+ const deformedFrame = poseDeformer.deformFrame(frame, poseData, binding);
+
+ // 压缩数据
+ const compressedData = compressPoseData({
+ pose: poseData,
+ binding: binding,
+ timestamp: Date.now()
+ });
+
+ // 发送数据
+ sendPoseData(compressedData);
+
+ // 更新性能监控
+ performanceMonitor.update(JSON.stringify(compressedData).length);
+ }
+ } catch (error) {
+ console.error('姿态捕捉错误:', error);
+ }
+ }, 1000 / 30); // 30fps
+ }
+
+ function renderRemotePose(data) {
+ const { pose, binding, sender } = data;
+
+ // 获取或创建渲染容器
+ let canvas = remoteContainers.get(sender);
+ if (!canvas) {
+ createRemotePoseContainer(sender);
+ canvas = remoteContainers.get(sender);
+ }
+
+ const ctx = canvas.getContext('2d');
+
+ // 清空画布
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ // 使用变形器渲染姿态
+ poseDeformer.renderPose(ctx, pose, binding);
+ }
+
+ // 优化数据压缩
+ function compressPoseData(data) {
+ return {
+ pose: {
+ keypoints: data.pose.keypoints.map(kp => ({
+ x: Math.round(kp.x * 100) / 100,
+ y: Math.round(kp.y * 100) / 100,
+ z: Math.round(kp.z * 100) / 100,
+ score: Math.round(kp.score * 100) / 100
+ })),
+ bbox: data.pose.bbox
+ },
+ binding: {
+ points: data.binding.points,
+ reference: data.binding.reference
+ },
+ timestamp: data.timestamp
+ };
+ }
+
+ class PerformanceMonitor {
+ constructor() {
+ this.stats = {
+ fps: 0,
+ latency: 0,
+ dataSize: 0
+ };
+ this.lastUpdate = Date.now();
+ this.frameCount = 0;
+ }
+
+ update(dataSize) {
+ this.frameCount++;
+ const now = Date.now();
+ const elapsed = now - this.lastUpdate;
+
+ if (elapsed >= 1000) {
+ this.stats.fps = Math.round(this.frameCount * 1000 / elapsed);
+ this.stats.dataSize = Math.round(dataSize / 1024); // KB
+ this.frameCount = 0;
+ this.lastUpdate = now;
+ this.updateDisplay();
+ }
+ }
+
+ updateDisplay() {
+ document.getElementById('performanceStats').innerHTML = `
+ FPS: ${this.stats.fps} |
+ 数据大小: ${this.stats.dataSize}KB/s
+ `;
+ }
+ }
+
+ const performanceMonitor = new PerformanceMonitor();