You need to enable JavaScript to run this app.
文档中心
视频点播

视频点播

复制全文
下载 pdf
进阶功能
蒙版弹幕
复制全文
下载 pdf
蒙版弹幕

蒙版弹幕可以在弹幕经过画面中的主体区域(如人像)时将其隐藏,实现“弹幕绕人走”的效果,避免弹幕遮挡视频主体,效果如下图所示。本文介绍如何基于应用已有的弹幕渲染功能,接入 HarmonyOS NEXT 播放器 SDK 的蒙版弹幕能力。

Image

技术原理

蒙版弹幕由播放器 SDK 与业务弹幕渲染模块协作完成:SDK 按播放时间输出 SVG 蒙版,业务将 SVG 解析为路径,并在弹幕画布中完成坐标映射和图形合成。

Image

  1. SDK 输出蒙版信息:SDK 负责加载蒙版资源,并根据当前播放 PTS 输出对应蒙版帧的 SVG 字符串。SVG 中有像素的区域表示弹幕允许显示区,人物轮廓是其中的透明镂空区域。
    <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
     width="455px" height="256px" viewBox="0 0 455 256"
     preserveAspectRatio="xMidYMid meet">
    <g transform="translate(0,256) scale(0.1,-0.1)" fill="#000000">
    <path d="M0 1280 l0 -1280 694 0 695 0 19 53 c11 28 36 84 55 122 20 39 45 104 56 145 18 67 48 157 96 290 9 25 22 52 30 60 42 49 89 220 99 363 7 100 51 230 89 264 12 11 63 33 112 47 50 15 117 35 150 45 56 17 60 20 63 51 3 30 -10 73 -61 195 -11 28 -24 70 -27 95 -4 25 -13 66 -21 92 -10 38 -11 61 0 125 14 91 17 187 7 224 -6 18 -3 31 9 42 20 21 68 22 84 3 25 -30 66 -29 133 5 112 57 218 33 288 -65 19 -27 61 -78 92 -113 36 -40 60 -77 64 -98 7 -37 -8 -121 -31 -169 -8 -17 -21 -59 -29 -94 -8 -34 -23 -77 -35 -95 -68 -108 -71 -126 -23 -164 20 -16 69 -47 107 -68 39 -20 106 -61 150 -90 44 -29 99 -62 122 -74 23 -11 48 -30 56 -41 11 -16 21 -19 40 -15 38 10 91 -11 132 -53 46 -47 57 -73 44 -110 -22 -65 -123 -81 -154 -24 l-14 27 -1 -35 c0 -19 7 -67 15 -105 8 -39 15 -86 15 -105 1 -33 4 -36 65 -64 119 -53 150 -110 120 -218 -17 -63 -87 -220 -111 -248 -12 -15 -114 -190 -114 -196 0 -2 331 -4 735 -4 l735 0 0 1280 0 1280 -2275 0 -2275 0 0 -1280z"/>
    </g>
    </svg>
    
    上述 SVG 的可视化效果如下:黑色区域对应 SVG 的有像素区域,表示弹幕允许显示区;白色人物区域实际为透明镂空,表示弹幕需要避让的主体区域。
    Image
  2. 业务解析 SVG:解析 viewBox、g transform、path d 和 fill-rule,将路径转换为 HarmonyOS Canvas 可绘制的 Path2D 或等价路径对象。未声明 fill-rule 时按 nonzero 处理,同时须支持 fill-rule="evenodd"。
  3. 映射到视频显示区域:根据视频缩放模式,将 SVG 的 viewBox 映射到视频内容的实际显示区域。存在黑边时需要计算内容偏移,不能直接使用播放器组件的全部尺寸;缩放和平移应使用一致的坐标单位,避免混用 px 和 vp。
  4. 绘制弹幕并应用蒙版:在独立的弹幕图层中先绘制弹幕,再将 globalCompositeOperation 设置为 destination-in,绘制变换后的蒙版路径,仅保留蒙版有像素区域中的弹幕。恢复画布状态后,将合成结果叠加到视频渲染层上方。
    Image

说明

SDK 负责蒙版资源加载、时间轴同步和 SVG 回调,不负责创建弹幕、解析 SVG 或绘制弹幕。业务可以使用自研弹幕组件或选择第三方弹幕组件(推荐鸿蒙官网 “DanmakuFlameMaster” 弹幕组件)。

前提条件

  • 已集成 HarmonyOS NEXT 播放器 SDK,版本为 3.8.1-tob 或更高版本。
  • 已购买并配置有效的高级版或企业版 License,详见 License 管理。基础版不支持蒙版弹幕。
  • 使用 VePlayer 自有播放器内核,而非系统 AVPlayer。
  • 应用已具备弹幕渲染能力。
  • 已通过视频点播媒体处理服务为视频生成蒙版弹幕文件。
  • 如果使用 Vid 模式播放,应用服务端在签发 PlayAuthToken 时,须额外签入 "NeedBarrageMask": true,详见通过临时播放 Token 播放。

接入步骤

步骤 1:实现蒙版信息监听器

实现 MaskInfoListener,在回调中将 SVG 和 PTS 交给业务弹幕渲染模块。回调线程不应被假定为 UI 线程;更新 ArkUI 状态时,应切换到业务使用的 UI 调度上下文。

import { MaskInfoListener } from '@simplayer/simkit_api'

class BusinessMaskInfoListener implements MaskInfoListener {
  onMaskInfoCallback(
    sourceID: string | undefined,
    code: number,
    pts: number,
    svg: string
  ): void {
    // 将当前蒙版帧交给业务弹幕渲染模块
    updateBarrageMask(sourceID, code, pts, svg)
  }
}

updateBarrageMask 为业务实现的方法,渲染流程示意请参见步骤 4:渲染 SVG 蒙版。

步骤 2:设置播放源并开启蒙版弹幕

根据播放方式选择以下一种配置。

Vid 模式

SDK 会从 VideoModel 的 BarrageMaskInfo 自动读取蒙版 URL 和文件头长度,业务无需手动设置蒙版 URL。

import { PlayOptions, VePlayer, VidSource } from '@simplayer/simkit_api'

// vid 和 playAuthToken 由应用服务端下发
const source = new VidSource(vid, playAuthToken)
const player = new VePlayer(source, PlayOptions.create())

player.setBarrageMaskInfoListener(new BusinessMaskInfoListener())
player.setBarrageMaskEnabled(true)
player.play()

说明

若 PlayAuthToken 未签入 NeedBarrageMask,或视频没有生成蒙版文件,SDK 无法获得蒙版资源,此时调用 setBarrageMaskEnabled(true) 不会产生蒙版回调。

URL 模式

在创建 VePlayer 之前,通过 PlayUrlModel.setBarrageMaskURL 设置与视频对应的蒙版文件 URL。

import {
  PlayOptions,
  PlayRequest,
  PlayUrlModel,
  VePlayer,
  getVideoModelFromPlayRequest
} from '@simplayer/simkit_api'

// videoUrl、barrageMaskUrl 和 sourceID 由业务提供
const playUrlModel = new PlayUrlModel([videoUrl])
playUrlModel.setBarrageMaskURL(barrageMaskUrl)

const playRequest = new PlayRequest(sourceID, playUrlModel)
const source = getVideoModelFromPlayRequest(playRequest)
const player = new VePlayer(source, PlayOptions.create())

player.setBarrageMaskInfoListener(new BusinessMaskInfoListener())
player.setBarrageMaskEnabled(true)
player.play()

蒙版 URL 必须与视频内容、时长和时间轴匹配。播放器创建后再补充 URL,不能为当前播放实例补建蒙版处理链路。

步骤 3:播放中动态开启或关闭

setBarrageMaskEnabled 是运行时开关,默认关闭。它只控制蒙版帧是否继续输出,不负责创建蒙版处理链路。

// 开启蒙版帧输出
player.setBarrageMaskEnabled(true)

// 关闭蒙版帧输出
player.setBarrageMaskEnabled(false)

关闭开关时,业务还需主动清空渲染层缓存的 SVG,避免继续显示最后一帧蒙版。

步骤 4:渲染 SVG 蒙版

以下代码仅示意业务渲染流程。currentSourceID 表示当前播放源,videoContentRect 表示视频内容实际显示区域,danmakuCanvas 表示独立弹幕图层的画布上下文。parseSvgMask、calculateVideoContentTransform、drawDanmakus 和 drawMaskPath 均需由业务实现,不属于播放器 SDK API。

function updateBarrageMask(
  sourceID: string | undefined,
  code: number,
  pts: number,
  svg: string
): void {
  if (sourceID !== currentSourceID || svg.length === 0) {
    return
  }

  const mask = parseSvgMask(svg)
  const transform = calculateVideoContentTransform(mask.viewBox, videoContentRect)

  danmakuCanvas.save()
  drawDanmakus(danmakuCanvas, pts)
  danmakuCanvas.globalCompositeOperation = 'destination-in'
  drawMaskPath(danmakuCanvas, mask, transform)
  danmakuCanvas.restore()
}

生命周期处理

页面退出

页面退出或不再消费蒙版信息时,关闭输出、解绑监听并释放播放器,同时由业务清理渲染层缓存的 SVG。

player.setBarrageMaskEnabled(false)
player.setBarrageMaskInfoListener(undefined)
player.release()

播放结束

播放结束后,建议停止生成新弹幕并清空当前 SVG 蒙版。已经进入屏幕的弹幕可以继续完成剩余动画。循环播放开始下一轮时,再恢复蒙版监听和运行时开关。

常见问题

开启后没有蒙版回调怎么办?

请依次检查:

  • SDK 版本为 3.8.1-tob 或更高版本,License 为有效的高级版或企业版。
  • 使用 VePlayer 自有播放器内核,而非系统 AVPlayer。
  • Vid 模式下,PlayAuthToken 包含 NeedBarrageMask: true,且视频已生成蒙版文件。
  • URL 模式下,在创建播放器前已设置有效的蒙版 URL。
  • 已注册 MaskInfoListener,并调用 setBarrageMaskEnabled(true)。

蒙版尺寸或位置不正确怎么办?

检查 SVG viewBox 与视频内容实际显示区域的映射。使用 AspectFit 等模式时,需要扣除上下或左右黑边,并统一 px 与 vp 的坐标单位。旋转屏幕、切换全屏或改变播放器尺寸后,重新计算变换矩阵。

弹幕全部消失或主体区域反向显示怎么办?

检查合成方向。HarmonyOS 蒙版中有像素的区域是弹幕允许显示区,应使用 destination-in;使用 destination-out 会得到相反结果。同时检查是否正确解析 fill-rule="evenodd"。

关闭后仍显示最后一帧蒙版怎么办?

运行时开关只停止后续输出,不会清理已绘制的画布。关闭开关或收到播放结束事件时,业务需要主动清空渲染层缓存的 SVG。

最近更新时间:2026.10.14 17:48:18
这个页面对您有帮助吗?
有用
有用
无用
无用