Electron媒体播放器实现“打开方式”捕获文件并播放的方法
Got it, let's fix this "Open With" issue for your Electron media player. I've tackled this exact scenario before, so here's a step-by-step breakdown that should get it working smoothly:
Electron passes files opened via "Open With" as command-line arguments, but you need to handle two scenarios: when your app is launching fresh, and when it's already running. Here's how to wire that up in your main process file:
const { app, BrowserWindow } = require('electron'); const path = require('path'); let mainWindow; function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js'), nodeIntegration: false, // Keep this secure contextIsolation: true } }); mainWindow.loadFile('index.html'); } // Handle files passed when the app first launches app.whenReady().then(() => { // Extract the file path (skip Electron's own command-line flags) const initialFile = process.argv.slice(1).find(arg => !arg.startsWith('--')); if (initialFile) sendFileToRenderer(initialFile); createWindow(); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); }); }); // Handle files passed when the app is already running (Windows/macOS) app.on('second-instance', (event, commandLine) => { const filePath = commandLine.slice(1).find(arg => !arg.startsWith('--')); if (filePath && mainWindow) { // Bring the app to focus if it's minimized if (mainWindow.isMinimized()) mainWindow.restore(); mainWindow.focus(); sendFileToRenderer(filePath); } }); // macOS-specific: Handle files opened via Finder's "Open With" app.on('open-file', (event, filePath) => { event.preventDefault(); if (mainWindow) { sendFileToRenderer(filePath); } else { // Wait for the app to finish launching before sending the file app.once('ready', () => sendFileToRenderer(filePath)); } }); // Helper to send the file path to the renderer for playback function sendFileToRenderer(filePath) { if (mainWindow?.webContents) { mainWindow.webContents.send('play-media', filePath); } } app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });
You need a way for the renderer (your UI) to receive the file path from the main process and load it into your media player. Use a preload script to safely expose this functionality:
preload.js
const { ipcRenderer, contextBridge } = require('electron'); contextBridge.exposeInMainWorld('electronAPI', { onPlayMedia: (callback) => { ipcRenderer.on('play-media', (event, filePath) => callback(filePath)); } });
index.html (Renderer UI)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My Media Player</title> </head> <body> <video id="player" controls style="width: 100%; height: 100vh;"></video> <script> const player = document.getElementById('player'); // Listen for file paths from the main process window.electronAPI.onPlayMedia((filePath) => { // Convert Windows backslashes to forward slashes for the video element const formattedPath = `file://${filePath.replace(/\\/g, '/')}`; player.src = formattedPath; player.play().catch(err => console.error('Playback failed:', err)); }); </script> </body> </html>
Your app won't show up in the "Open With" menu unless you register it to handle specific media file types. Use electron-builder (the most common packaging tool) to configure this in your package.json:
"build": { "win": { "target": "nsis", "fileAssociations": [ { "ext": ["mp4", "mov", "avi", "mkv", "flv"], "name": "Video Files", "description": "Play videos with My Media Player", "icon": "assets/icon.ico" } ] }, "mac": { "fileAssociations": [ { "ext": ["mp4", "mov", "avi", "mkv"], "name": "Video", "role": "Viewer" } ] }, "linux": { "target": "deb", "fileAssociations": [ { "ext": ["mp4", "mov", "avi", "mkv"], "name": "Video Files" } ] } }
Important: You can't test "Open With" properly in development mode (Electron's dev process handles arguments differently). Package your app with electron-builder, install it, then right-click a media file → Open With → Select your app. The file should load and play automatically.
A few quick troubleshooting tips:
- On Windows, make sure you run the installed app (not the dev version)
- On macOS, if the app doesn't appear in "Open With", hold the Option key while right-clicking to reveal more options
- Double-check file extensions in your
package.jsonto match the files you're testing with
内容的提问来源于stack exchange,提问作者Joseph

