Skip to content

弹幕遮罩 ​

English

通过人体分割结果生成 CSS 遮罩,让弹幕避开视频中的人物区域。插件处理核心的 .art-danmuku 层,不修改弹幕队列、条目或视频画面。本页描述未发布重构分支,不将在线示例或导航验证视为模型效果验收。

安装和示例 ​

sh
yarn add artplayer artplayer-plugin-danmuku artplayer-plugin-danmuku-mask
js
import Artplayer from 'artplayer';
import artplayerPluginDanmuku from 'artplayer-plugin-danmuku';
import artplayerPluginDanmukuMask from 'artplayer-plugin-danmuku-mask';

script 用法先加载核心及两个插件的 dist 文件,全局名分别为 artplayerPluginDanmuku、artplayerPluginDanmukuMask。原在线示例按此顺序注册,并从站点自己的路径加载 MediaPipe 资源:

▶ Run Code
js
// npm i artplayer-plugin-danmuku-mask
// import artplayerPluginDanmukuMask from 'artplayer-plugin-danmuku-mask';

// npm i @mediapipe/selfie_segmentation
// 把 node_modules/@mediapipe/selfie_segmentation 目录复制到你的项目下

const art = new Artplayer({
  container: '.artplayer-app',
  url: '/assets/sample/steve-jobs.mp4',
  autoSize: true,
  fullscreen: true,
  fullscreenWeb: true,
  autoOrientation: true,
  plugins: [
    artplayerPluginDanmuku({
      danmuku: '/assets/sample/danmuku.xml',
    }),
    artplayerPluginDanmukuMask({
      solutionPath: '/assets/@mediapipe/selfie_segmentation',
    }),
  ],
})

部署时确保 solutionPath 下有匹配的 MediaPipe 资源。复制目录本身不证明所有脚本、模型、WASM、网络策略和浏览器能力都可用。

配置 ​

配置可省略,注册时读取并保存这些值:

字段类型 / 默认值实际用途
solutionPathstringSDK 资源根路径;默认 CDN 未固定版本
modelSelectionnumber / 1历史转发字段,不能据此认为当前模型已切换
smoothSegmentationboolean / true历史转发字段,显式 false 保留
minDetectionConfidencenumber / 0.5历史转发字段
minTrackingConfidencenumber / 0.5历史转发字段
selfieModeboolean / false历史转发字段
drawContourboolean / false传给二值遮罩转换
foregroundThresholdnumber / 0.5传给前景阈值转换
opacitynumber / 1传给 SDK drawMask,不是直接设置弹幕层 opacity
maskBlurAmountnumber / 3传给 SDK drawMask 的模糊量

solutionPath 默认指向未固定版本的 jsDelivr MediaPipe 资源根目录。

除 smoothSegmentation 的 undefined 判断外,默认值沿用 value || default。例如 modelSelection、opacity、threshold、blur 的 0 会回退默认值,不能用于关闭功能;停止遮罩使用 stop。

当前固定选择 runtime: 'mediapipe' 和 modelType: 'general'。已安装的 adapter 把 general 映射为 modelSelection 0,并忽略部分额外转发字段;保留参数不是承诺这些字段都会改变推理。TensorFlow 后端先尝试 webgl,只有拒绝时才尝试 cpu;这也不能证明 MediaPipe 实际使用哪种推理后端。

start、stop 与失败 ​

注册同步返回 { name: 'artplayerPluginDanmukuMask', start, stop },可从 art.plugins.artplayerPluginDanmukuMask 访问。ready 自动启动;如果在 ready 之后安装,需要自行调用 start。

方法行为
start()返回 Promise<void>;初始化并启动调度,不等待第一张完整遮罩
stop()同步返回 undefined;取消当前调度并立刻将层的 maskImage 设为 none

重复 start 不创建重叠推理循环。stop 可在初始化过程中调用,使公共 start 及时结算;不可取消的 SDK 工作仍被观察,迟到结果不再写入遮罩。之后 start 等待旧任务和释放过程结束再重新初始化,不以多个模型并行掩盖停止问题。

模型创建失败会记录错误且 start 可正常结算,但没有可用模型;可显式再次 start 重试。后端或必要 DOM/Canvas 初始化失败仍可能拒绝 start。自动 ready 启动会记录拒绝。推理或像素读取失败记录错误并继续下一次调度,保留上一张可用遮罩。

只在视频播放、未结束且有有效尺寸时执行分割。结果经二值遮罩、drawMask 和 Canvas 像素转换生成 PNG data URL,写入整层 maskImage。没有人物结果时保留之前的遮罩;遮罩精度、性能和跨域像素访问需要实际视频验证。

生命周期和类型 ​

播放器销毁停止运行并移除 ready/destroy 监听器。私有画布归插件所有,SDK 工作完成后重置其尺寸并释放模型。stop 不是 GPU 内存回收完成的 Promise;SDK 的私有资源实际释放完成仍需独立证据。插件不提供公开 destroy、update 或新事件,也不接管其他应用的全局 TensorFlow 生命周期。

根和 /legacy 保留历史声明:可选配置、同步注册、异步 start 和同步 stop;没有 /runtime 子路径。Option/Result 是声明内部类型,可通过工厂提取。下面仅展示 NodeNext ESM 下的类型提取,不执行 .default 调用:

ts
import type MaskModule from 'artplayer-plugin-danmuku-mask';

type MaskFactory = typeof MaskModule.default;
type MaskOptions = Parameters<MaskFactory>[0];
type MaskResult = ReturnType<ReturnType<MaskFactory>>;

const options: MaskOptions = { solutionPath: '/assets/@mediapipe/selfie_segmentation' };
async function restartMask(mask: MaskResult): Promise<void> {
  mask.stop();
  await mask.start();
}

保留的 NodeNext 根类型有模块命名空间行为;这不代表当前运行时工厂有 .default 属性。当前 CommonJS 工厂直接调用,ESM 运行时使用默认导出;不要从类型命名空间推断运行时别名。旧版导出形状、模型真实运行和真机性能各自独立验证。