N
O
D
E
M
E
D
I
A
Thinking
首页
产品
文档
博客
订单
文档
快速集成
21 次浏览
2026年 5月 29日 下午7:56
## 创建您的第一个应用程序 我们将采用官方推荐的[Electron Forge](http://https://www.electronforge.io/ "Electron Forge")创建应用程序 >Electron Forge 是一套集成的工具,用于打包和分发 Electron 应用程序。它合并了许多单用途包,形成一个完整的构建流程,从安装开始即可使用,包含代码签名、安装程序以及工件发布功能。对于更高级的工作流程,可以通过 Forge 的生命周期中的插件 API添加自定义构建逻辑。定制构建和存储目标则可以通过创建自己的 Makers 和 Publishers 来实现。 ```bash npx create-electron-app@latest my-app ``` >所有选项都使用默认 打开项目,目录结构如下,可以进行 init commit  `npm start` 运行项目, 正常可以看到  ## 1. 安装扩展 执行命令 ``` bash npm i nodeplayer-addon ``` ## 2.编辑index.js (根据项目的不同,也可以是main.js) ```js const { app, BrowserWindow, ipcMain } = require('electron'); const path = require('node:path'); const NodePlayerAddon = require('nodeplayer-addon'); //导入播放器扩展 // Handle creating/removing shortcuts on Windows when installing/uninstalling. if (require('electron-squirrel-startup')) { app.quit(); } const createWindow = () => { // Create the browser window. const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js'), }, }); // and load the index.html of the app. mainWindow.loadFile(path.join(__dirname, 'index.html')); // Open the DevTools. // mainWindow.webContents.openDevTools(); mainWindow.on('closed', () => { NodePlayerAddon.unregisterIpc(ipcMain) }); NodePlayerAddon.registerIpc(ipcMain, { getWindow: () => mainWindow, licensePath: app.isPackaged ? path.join(process.resourcesPath, 'license.dat') : path.join(__dirname, 'license.dat'), }); }; // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.whenReady().then(() => { createWindow(); // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); }); // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and import them here. ``` ## 3.编辑preload.js ```js const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld('electronAPI', { createPlayer: (id) => ipcRenderer.invoke('player:create', id), startPlayer: (id, url) => ipcRenderer.invoke('player:start', id, url), stopPlayer: (id) => ipcRenderer.invoke('player:stop', id), destroyPlayer: (id) => ipcRenderer.invoke('player:destroy', id), startRecord: (id, filePath) => ipcRenderer.invoke('player:startRecord', id, filePath), stopRecord: (id) => ipcRenderer.invoke('player:stopRecord', id), onEvent: (id, callback) => { const channel = `player:event:${id}` const handler = (event, data) => callback(data) ipcRenderer.on(channel, handler) return () => ipcRenderer.removeListener(channel, handler) }, onInfo: (id, callback) => { const channel = `player:info:${id}` const handler = (event, info) => callback(info) ipcRenderer.on(channel, handler) return () => ipcRenderer.removeListener(channel, handler) }, onData: (id, callback) => { const channel = `player:data:${id}` const handler = (event, data) => callback(data) ipcRenderer.on(channel, handler) return () => ipcRenderer.removeListener(channel, handler) }, }) ``` ## 4.编辑index.html ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>NodePlayer Demo</title> <style> body { margin: 0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; } video { width: 100%; max-width: 960px; background: #000; } .controls { position: fixed; bottom: 20px; display: flex; gap: 10px; } .controls input { width: 400px; padding: 6px; } .controls button { padding: 6px 16px; cursor: pointer; } .status { position: fixed; top: 10px; left: 10px; color: #0f0; font-family: monospace; font-size: 14px; } </style> </head> <body> <div class="status" id="status"></div> <video id="video" autoplay muted playsinline></video> <div class="controls"> <input id="url" type="text" placeholder="rtsp://..." value="rtsp://"> <button id="btn-start">播放</button> <button id="btn-stop">停止</button> <button id="btn-record">录像</button> </div> <!-- 在 preload.js 中已通过 contextBridge 暴露 window.electronAPI --> <script src="https://cdn.jsdelivr.net/npm/nodeplayer-addon/dist/video-player.umd.js"></script> <script> const videoEl = document.getElementById('video') const statusEl = document.getElementById('status') const urlInput = document.getElementById('url') const player = new VideoPlayer(videoEl, 'demo', { onStatus(id, text) { statusEl.textContent = text }, onRecord(id, recording) { document.getElementById('btn-record').textContent = recording ? '停止录像' : '录像' } }) document.getElementById('btn-start').onclick = () => player.start(urlInput.value) document.getElementById('btn-stop').onclick = () => player.stop() document.getElementById('btn-record').onclick = () => { player.isRecording ? player.stopRecord() : player.startRecord() } </script> </body> </html> ``` 本例子使用UMD模式加载播放前端,如果是离线部署,可以将 https://cdn.jsdelivr.net/npm/nodeplayer-addon/dist/video-player.umd.js 下载到本地进行加载。 ## 5.再次运行 `npm start` 可以启动页面并输入播放地址 rtsp:// or rtmp://  这样,一个基于NodePlayerAddon 开发的简单Electron播放例子就完成了。不依赖流媒体服务端,直连rtsp,rtmp播放。高性能,硬解码,低延迟。 ## 6.加上样式  ## 联系客服索取demo源码 - QQ: 281269007 - Email: service@nodemedia.cn
嘿,我是小R,需要帮助随时找我哦
QQ客服:281269007
邮件支持
扫码加微信
回到顶部