前端新增播放音效
This commit is contained in:
@@ -6,6 +6,24 @@ import socket
|
|||||||
class APIHandler(SimpleHTTPRequestHandler):
|
class APIHandler(SimpleHTTPRequestHandler):
|
||||||
# 设置超时,避免长时间占用连接
|
# 设置超时,避免长时间占用连接
|
||||||
timeout = 30
|
timeout = 30
|
||||||
|
|
||||||
|
# MIME 类型映射
|
||||||
|
MIME_TYPES = {
|
||||||
|
'.html': 'text/html; charset=utf-8',
|
||||||
|
'.css': 'text/css',
|
||||||
|
'.js': 'application/javascript',
|
||||||
|
'.json': 'application/json',
|
||||||
|
'.png': 'image/png',
|
||||||
|
'.jpg': 'image/jpeg',
|
||||||
|
'.jpeg': 'image/jpeg',
|
||||||
|
'.gif': 'image/gif',
|
||||||
|
'.svg': 'image/svg+xml',
|
||||||
|
'.ico': 'image/x-icon',
|
||||||
|
'.mp3': 'audio/mpeg',
|
||||||
|
'.wav': 'audio/wav',
|
||||||
|
'.mp4': 'video/mp4',
|
||||||
|
'.txt': 'text/plain; charset=utf-8',
|
||||||
|
}
|
||||||
|
|
||||||
def log_message(self, format, *args):
|
def log_message(self, format, *args):
|
||||||
# 自定义日志格式
|
# 自定义日志格式
|
||||||
@@ -31,7 +49,13 @@ class APIHandler(SimpleHTTPRequestHandler):
|
|||||||
# 默认访问使用 api=1
|
# 默认访问使用 api=1
|
||||||
self.serve_file('index.html', query='api=1')
|
self.serve_file('index.html', query='api=1')
|
||||||
else:
|
else:
|
||||||
self.send_error(404, 'Not Found')
|
# 处理静态文件请求
|
||||||
|
# 移除开头的 /
|
||||||
|
filename = path.lstrip('/')
|
||||||
|
if os.path.exists(filename):
|
||||||
|
self.serve_static_file(filename)
|
||||||
|
else:
|
||||||
|
self.send_error(404, 'Not Found')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error handling request: {e}")
|
print(f"Error handling request: {e}")
|
||||||
self.send_error(500, 'Internal Server Error')
|
self.send_error(500, 'Internal Server Error')
|
||||||
@@ -67,6 +91,26 @@ class APIHandler(SimpleHTTPRequestHandler):
|
|||||||
print(f"Error serving file: {e}")
|
print(f"Error serving file: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def serve_static_file(self, filename):
|
||||||
|
"""提供静态文件服务"""
|
||||||
|
try:
|
||||||
|
# 获取文件扩展名
|
||||||
|
ext = os.path.splitext(filename)[1].lower()
|
||||||
|
content_type = self.MIME_TYPES.get(ext, 'application/octet-stream')
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type', content_type)
|
||||||
|
self.send_header('Access-Control-Allow-Origin', '*')
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
with open(filename, 'rb') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
self.wfile.write(content)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error serving static file: {e}")
|
||||||
|
self.send_error(500, 'Internal Server Error')
|
||||||
|
|
||||||
def check_port_available(port):
|
def check_port_available(port):
|
||||||
"""检查端口是否可用"""
|
"""检查端口是否可用"""
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
|||||||
@@ -169,6 +169,26 @@
|
|||||||
color: #60a5fa;
|
color: #60a5fa;
|
||||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||||
}
|
}
|
||||||
|
.enable-sound-btn {
|
||||||
|
padding: 4px 12px;
|
||||||
|
background: #3b82f6;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
.enable-sound-btn:hover {
|
||||||
|
background: #2563eb;
|
||||||
|
}
|
||||||
|
.enable-sound-btn:disabled {
|
||||||
|
background: #1f2937;
|
||||||
|
color: #6b7280;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -176,7 +196,10 @@
|
|||||||
<main>
|
<main>
|
||||||
<aside class="left-panel">
|
<aside class="left-panel">
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<div class="sidebar-header">异常消息</div>
|
<div class="sidebar-header" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
异常消息
|
||||||
|
<button id="enableSoundBtn" class="enable-sound-btn">🔔 启用提示音</button>
|
||||||
|
</div>
|
||||||
<div id="messageList" class="message-list"></div>
|
<div id="messageList" class="message-list"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="log-panel">
|
<div class="log-panel">
|
||||||
@@ -221,6 +244,7 @@
|
|||||||
|
|
||||||
const WS_PORT = config.port;
|
const WS_PORT = config.port;
|
||||||
const WS_HOST = '29.1.70.11';
|
const WS_HOST = '29.1.70.11';
|
||||||
|
<!-- const WS_HOST = '127.0.0.1';-->
|
||||||
|
|
||||||
const liveImage = document.getElementById('liveImage');
|
const liveImage = document.getElementById('liveImage');
|
||||||
const statusBar = document.getElementById('status');
|
const statusBar = document.getElementById('status');
|
||||||
@@ -231,11 +255,41 @@
|
|||||||
let ws = null;
|
let ws = null;
|
||||||
let wsConnected = false;
|
let wsConnected = false;
|
||||||
let currentDetectedActions = [];
|
let currentDetectedActions = [];
|
||||||
|
let audioEnabled = false;
|
||||||
|
let alertAudio = null;
|
||||||
|
|
||||||
function setMode(newMode) {
|
function setMode(newMode) {
|
||||||
// 模式切换功能已禁用
|
// 模式切换功能已禁用
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function enableSound() {
|
||||||
|
alertAudio = new Audio('/sfx_alert.mp3');
|
||||||
|
alertAudio.volume = 0.5;
|
||||||
|
|
||||||
|
alertAudio.play().then(() => {
|
||||||
|
audioEnabled = true;
|
||||||
|
const btn = document.getElementById('enableSoundBtn');
|
||||||
|
btn.textContent = '🔔 提示音已启用';
|
||||||
|
btn.disabled = true;
|
||||||
|
addLog('提示音已启用', 'success');
|
||||||
|
|
||||||
|
alertAudio.currentTime = 0;
|
||||||
|
alertAudio.pause();
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('音频播放失败:', err);
|
||||||
|
addLog('提示音启用失败,请检查音频文件', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function playAlertSound() {
|
||||||
|
if (audioEnabled && alertAudio) {
|
||||||
|
alertAudio.currentTime = 0;
|
||||||
|
alertAudio.play().catch(err => {
|
||||||
|
console.error('音频播放失败:', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function renderMessages() {
|
function renderMessages() {
|
||||||
messageListEl.innerHTML = '';
|
messageListEl.innerHTML = '';
|
||||||
for (const msg of alerts.slice().reverse()) {
|
for (const msg of alerts.slice().reverse()) {
|
||||||
@@ -364,7 +418,7 @@
|
|||||||
|
|
||||||
<!-- if (!existingAlert) {-->
|
<!-- if (!existingAlert) {-->
|
||||||
alerts.push(alertMsg);
|
alerts.push(alertMsg);
|
||||||
|
playAlertSound();
|
||||||
renderMessages();
|
renderMessages();
|
||||||
<!-- }-->
|
<!-- }-->
|
||||||
}
|
}
|
||||||
@@ -376,6 +430,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
|
document.getElementById('enableSoundBtn').addEventListener('click', enableSound);
|
||||||
|
|
||||||
addLog('AI督察系统启动', 'info');
|
addLog('AI督察系统启动', 'info');
|
||||||
addLog('界面初始化完成', 'success');
|
addLog('界面初始化完成', 'success');
|
||||||
addLog(`接口参数: api=${apiParam}`, 'info');
|
addLog(`接口参数: api=${apiParam}`, 'info');
|
||||||
|
|||||||
Reference in New Issue
Block a user