npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

electron-mpv-video

v0.1.1

Published

Bring libmpv's broad video format support to Electron with shared-texture and software rendering pipelines.

Readme

electron-mpv-video

English | 简体中文

将 libmpv 广泛的编解码器和容器格式支持引入 Electron,在支持播放更多视频格式的同时,让视频继续由 Chromium 渲染,因此应用可以方便地在视频上方放置 HTML 控件和其他界面。

electron-mpv-video 示例预览

本包提供三个集成入口:

  • electron-mpv-video/main:主进程生命周期与 IPC 服务。
  • electron-mpv-video/preload:可组合的 contextBridge API。
  • electron-mpv-video/renderer:不包含 UI 的 <mpv-video> 自定义元素。

本包目前以从源码构建的原生插件形式分发。安装时需要外部 libmpv SDK/运行时;支持的平台提供约定默认路径,也可以通过环境变量覆盖。本仓库不存放 libmpv 二进制文件。

媒体格式支持

播放能力来自应用使用的 libmpv,以及其编译时链接的 FFmpeg 库。常见输入包括:

  • 视频容器: MP4/MOV、Matroska(MKV/WebM)、AVI、MPEG-TS/M2TS、MPEG-PS/VOB、FLV 和 Ogg。
  • 视频编码: H.264/AVC、H.265/HEVC、AV1、VP9、VP8、MPEG-2 Video 和 MPEG-4 Part 2。
  • 音频格式和编码: MP3、AAC/M4A、FLAC、Opus、Vorbis、WAV/PCM、AC-3/E-AC-3 和 DTS。
  • 流媒体格式和协议: HLS(.m3u8)、MPEG-DASH(.mpd)、HTTP/HTTPS 直链、RTSP/RTP、RTMP 和 SRT。

实际可用范围取决于 libmpv 和 FFmpeg 的构建配置。可以查看完整的格式和编解码器列表,网络播放的详细说明请参阅 mpv 协议文档

支持的平台

当前已实现的原生目标平台包括:

  • macOS arm64
  • Windows x64

暂不支持 Linux。

Electron 兼容性

本包目前有意不声明 Electron peer dependency。

  • shared-texture 需要 Electron 40 或更高版本,并使用 electron.sharedTexture 和基于 WebGPU 的 VideoFrame 渲染器。目前使用 Electron 40.10.5 进行测试。
  • webgl 使用软件 libmpv 渲染管线,并将 RGBA 帧上传到 WebGL2。它不会调用 Electron 的共享纹理 API。
  • canvas2d 使用相同的软件管线,并通过 Canvas 2D 绘制 RGBA 帧。它不会调用 Electron 的共享纹理 API。

当前验证基线仅包含 Electron 40.10.5。即使使用软件渲染模式,也不保证兼容更早的 Electron 版本。

原生构建要求

  • Node.js 22+
  • Python 和可正常工作的 node-gyp 工具链
  • 与目标平台和架构匹配的 libmpv SDK/运行时

构建使用以下默认路径:

| 平台 | 头文件 | 链接库 | 运行库目录 | | --- | --- | --- | --- | | macOS arm64 | /opt/homebrew/include | /opt/homebrew/lib/libmpv.dylib | /opt/homebrew/opt/mpv/lib | | Windows x64 | %USERPROFILE%\libmpv\include | %USERPROFILE%\libmpv\lib\mpv.lib | %USERPROFILE%\libmpv\bin |

如有需要,可以覆盖任意默认值:

  • MPV_INCLUDE_DIR:包含 mpv/client.h 的目录
  • MPV_LIB:链接器输入文件的完整路径,即 libmpv.dylibmpv.lib
  • MPV_RUNTIME_DIR:包含运行时 dylib/DLL 文件的目录

npm run build:native 会验证解析后的路径、构建插件,并将运行时文件复制到 mpv_addon.node 旁边。

macOS arm64

安装 libmpv,使用 Homebrew 安装时不需要额外设置环境变量:

brew install mpv
npm install electron-mpv-video

在本仓库中开发时,安装后运行 npm installnpm run build:native。 如果使用自定义 libmpv 构建,可以显式设置环境变量:

export MPV_INCLUDE_DIR=/custom/include
export MPV_LIB=/custom/lib/libmpv.dylib
export MPV_RUNTIME_DIR=/custom/lib

构建后步骤会把运行库目录中的 dylib 复制到插件旁边,将插件对 libmpv 的 直接引用改写为 @loader_path/libmpv.dylib,并对复制出的 libmpv 执行 ad-hoc 签名。Homebrew 的 libmpv 仍可能引用其他 Homebrew 动态库;要生成 可移植的安装包,还必须随应用打包并重定位全部非系统依赖。

共享纹理实现使用 OpenGL 和 IOSurface。binding.gyp 当前的最低部署目标 为 macOS 12.0,实际最低版本还取决于所选择的 libmpv 构建。

下载/安装参考:

  • https://brew.sh/
  • https://formulae.brew.sh/formula/mpv
  • https://mpv.io/installation/

Windows x64

  1. 安装 Visual Studio Build Tools,并勾选 Desktop development with C++ 工作负载。
  2. 打开 Shinchiro Windows builds 的最新 Release,下载非 v3mpv-dev-x86_64-...7z
  3. 将解压后的文件整理到当前用户目录:
%USERPROFILE%\libmpv\
├── include\mpv\...
├── lib\mpv.lib
└── bin\libmpv-2.dll

下载参考:

  • https://github.com/shinchiro/mpv-winbuild-cmake/releases/latest
  • https://mpv.io/installation/

开发包包含头文件、libmpv-2.dll 和 MinGW 导入库 libmpv.dll.a。 将头文件复制到 include\mpv,DLL 复制到 bin。本项目使用 MSVC 构建,因此构建前需要根据 DLL 生成 lib\mpv.lib

# 在 Visual Studio x64 Native Tools Command Prompt 中运行。
powershell -ExecutionPolicy Bypass `
  -File .\scripts\create-libmpv-import-lib.ps1

npm install electron-mpv-video

辅助脚本默认使用 %USERPROFILE%\libmpv 目录结构。自定义位置时仍可使用 环境变量:

$env:MPV_INCLUDE_DIR = 'D:\sdk\libmpv\include'
$env:MPV_LIB = 'D:\sdk\libmpv\lib\mpv.lib'
$env:MPV_RUNTIME_DIR = 'D:\sdk\libmpv\bin'

也可以直接向导入库辅助脚本传入 -DllPath-OutputPath。构建成功后, 解析出的运行库目录中的所有 DLL 都会复制到 mpv_addon.node 旁边。

安装

npm install electron-mpv-video

本包的安装脚本会运行 npm run build:native。只有覆盖平台默认路径时才需要设置环境变量。

在本仓库中进行开发:

npm install
npm run build
npm run dev

Electron 集成

主进程

为 Electron 应用创建一个服务,并将所有可能创建播放器的窗口连接到该服务:

import { app, BrowserWindow } from 'electron'
import { createMpvMain } from 'electron-mpv-video/main'

const mpv = createMpvMain()

async function createWindow() {
  const window = new BrowserWindow({
    webPreferences: {
      preload: '/absolute/path/to/your-preload.cjs',
      contextIsolation: true,
      nodeIntegration: false,
      sandbox: false,
    },
  })

  mpv.attachWindow(window)
  await window.loadFile('index.html')
}

app.on('before-quit', () => {
  void mpv.dispose()
})

attachWindow() 会授权该窗口的渲染进程创建会话。会话按其所属的 webContents 隔离,并在窗口关闭时销毁。

对于自定义构建目录,可以指定可选的插件路径:

const mpv = createMpvMain({
  addonPath: '/absolute/path/to/mpv_addon.node',
})

Preload

在应用现有的 preload 脚本中调用 exposeMpvApi()

import { exposeMpvApi } from 'electron-mpv-video/preload'

exposeMpvApi()

该函数会将 API 暴露为:

window._electronMpvVideo

preload 会在渲染进程代码创建播放器之前注册共享纹理接收器。当前从源码构建的集成方式使用 sandbox: false,以便应用的 preload 脚本加载 npm 包。

渲染进程

显式注册自定义元素:

import { defineMpvVideoElement } from 'electron-mpv-video/renderer'

// 可以安全地多次调用。
defineMpvVideoElement()

然后在 HTML 中创建该元素:

<mpv-video render-mode="shared-texture" volume="80"></mpv-video>

该元素仅包含渲染画布及其所需的最少布局样式,不附带控件、主题或外部 CSS 文件。元素尺寸和周边 UI 由应用控制:

.player-frame {
  position: relative;
  width: 960px;
  aspect-ratio: 16 / 9;
}

.player-frame mpv-video {
  position: absolute;
  inset: 0;
}
const video = document.querySelector('mpv-video')!

await video.open('/absolute/path/to/video.mkv')
await video.play()
await video.pause()
await video.seek(30)
await video.setVolume(70)

shared-texturesoftware(webgl/canvas2d) 之间切换时,会重新创建原生播放器并恢复:

  • 媒体源
  • 当前播放时间
  • 音量
  • 暂停或播放状态
  • 停止状态

webglcanvas2d 之间切换时,会保留同一个软件原生播放器,仅更换渲染画布。

元素属性和方法

属性:

  • src
  • loop
  • volume
  • mode
  • currentTime
  • duration
  • videoWidth
  • videoHeight
  • rendererName
  • playerId

方法:

  • open(source)
  • play()
  • pause()
  • stop()
  • seek(seconds)
  • setVolume(value)
  • setRenderMode(mode)
  • destroy()

事件:

  • mpv-state:标准化后的播放器和渲染器状态
  • mpv-event:标准化后的原始 libmpv 事件
  • mpv-error:渲染器、事件泵或原生渲染错误

底层渲染器 API

不希望使用自定义元素的应用可以直接使用 preload 会话:

const player = await window._electronMpvVideo.create({
  renderMode: 'webgl',
  width: 960,
  height: 540,
})

const disposeFrame = player.onFrame((frame) => {
  // 将 frame.rgba 绘制到应用自行管理的表面。
})

await player.open('/absolute/path/to/video.mp4')
await player.play()

// 稍后:
disposeFrame()
await player.destroy()

应用打包

原生模块及其相邻的动态库无法直接从 asar 归档中加载。请配置应用打包工具解包以下文件:

node_modules/electron-mpv-video/native/mpv-addon/build/Release/*.{node,dylib,dll}

如果打包工具不支持大括号展开,请分别添加 *.node*.dylib*.dll 模式。解包后的包必须保持相同的相对路径,因为主进程加载器会从该位置解析插件,而运行时加载器会解析插件旁边已放置的 libmpv 文件。

在 macOS 上,只有当 libmpv.dylib 的其他所有非系统依赖也都可被找到时,才可以仅打包该文件。在 Windows 上,请将所选 libmpv 构建中的所有 DLL 一同保留在同一个解包目录中。

示例应用

仓库根目录下的 demo 应用与外部 Electron 应用一样,使用相同的公共子路径导出:

npm run dev

生产构建:

npm run build
npm start

粘贴媒体文件的绝对路径,或使用示例应用的文件选择器。文件选择器属于示例应用,不是库 API 的一部分。

验证

npm run check
npm run build:native
npm run test:native
npm pack --dry-run

仓库还包含一个 Electron 运行时测试。该测试会打开生成的或本地的媒体文件,并在暂停和播放状态下切换软件管线与共享纹理管线:

MPV_SMOKE_SOURCE=/absolute/path/to/video.mp4 npm run test:electron

该测试需要图形会话、受支持的 Electron/macOS 或 Electron/Windows 运行环境,以及可正常工作的 libmpv 安装。

许可证

原始的 electron-mpv-video 源代码采用 MIT 许可证

libmpv 是外部运行时/构建依赖,不包含在本仓库或 npm 包中,也不受本项目 MIT 许可证覆盖。mpv 默认采用 GPL-2.0-or-later 许可证;排除仅适用于 GPL 的组件后,也可以构建为 LGPL-2.1-or-later。实际适用的许可证还取决于具体 libmpv 构建所链接的库。在随应用分发 libmpv 之前,请参阅第三方声明