143 lines
3.4 KiB
JavaScript
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();
|
|
}
|
|
}); |