Files
traepro-videoserver/main.js
2025-07-24 22:34:02 +08:00

143 lines
3.4 KiB
JavaScript

const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cors = require('cors');
let mainWindow;
let streamingServer;
let io;
// 创建主窗口
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
webSecurity: false
},
icon: path.join(__dirname, 'assets', 'icon.svg'),
title: 'Trae Video Server'
});
mainWindow.loadFile('index.html');
// 开发模式下打开开发者工具
if (process.argv.includes('--dev')) {
mainWindow.webContents.openDevTools();
}
}
// 创建流媒体服务器
function createStreamingServer() {
const app = express();
app.use(cors());
app.use(express.static(path.join(__dirname, 'public')));
const server = http.createServer(app);
io = socketIo(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
// 提供网页预览接口
app.get('/preview', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'preview.html'));
});
// Socket.IO连接处理
io.on('connection', (socket) => {
console.log('客户端连接到流媒体服务');
socket.on('disconnect', () => {
console.log('客户端断开连接');
});
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`流媒体服务器运行在 http://localhost:${PORT}`);
});
return server;
}
// 获取视频设备列表
ipcMain.handle('get-video-devices', async () => {
try {
const devices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = devices.filter(device => device.kind === 'videoinput');
return videoDevices.map(device => ({
deviceId: device.deviceId,
label: device.label || `摄像头 ${device.deviceId.slice(0, 8)}...`
}));
} catch (error) {
console.error('获取设备列表失败:', error);
return [];
}
});
// 开始预览
ipcMain.handle('start-preview', async (event, deviceId) => {
try {
// 如果流媒体服务器还没启动,则启动它
if (!streamingServer) {
streamingServer = createStreamingServer();
}
return {
success: true,
streamUrl: 'http://localhost:3000/preview',
message: '预览已启动,流媒体服务已就绪'
};
} catch (error) {
console.error('启动预览失败:', error);
return {
success: false,
message: '启动预览失败: ' + error.message
};
}
});
// 停止预览
ipcMain.handle('stop-preview', async () => {
try {
if (io) {
io.emit('stop-stream');
}
return { success: true, message: '预览已停止' };
} catch (error) {
console.error('停止预览失败:', error);
return { success: false, message: '停止预览失败: ' + error.message };
}
});
// 广播视频帧到所有连接的客户端
ipcMain.on('broadcast-frame', (event, frameData) => {
if (io) {
io.emit('video-frame', frameData);
}
});
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (streamingServer) {
streamingServer.close();
}
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});