Skip to content
本页导航

公共视频播放器 ​

独立入口:@qxs-bns/components/video-player,标签:qxs-video-player。不从默认入口加载播放器。内部固定使用xgplayer和xgplayer-hls 3.0.26;HLS优先原生支持,否则使用HLS插件。

交互演示 ​

选择 MP4 或 HLS 点播源,体验播放、暂停、跳转、倍速、音量、全屏与切源。下方实时显示播放状态与进度,展开「接口调试」可调用控制方法、查看事件数据和来源版本。

loading

测试视频随文档提供,无需业务鉴权或外部视频服务。默认素材为原创医学主题矢量示意画面,带有轻微镜头运动;另保留彩条源用于切源测试。封面、MP4 与 HLS 均由脚本生成,并附低音量测试音,可通过 node scripts/generate-video-demo-media.mjs 重新生成(需要 ffmpeg,无外部素材或额外图像依赖)。这里的 HLS 是有限时长的点播样例,不代表真实直播链路已验收。

外观定制 ​

默认使用深色半透明控制栏、细进度条与深色倍速菜单。通过组件上的 CSS 变量调整强调色和圆角:

css
qxs-video-player {
  --qxs-player-accent: #e60000;
  --qxs-player-radius: 12px;
}

封面通过 player.options.poster 设置,和其他初始化选项一样,应在 setSource() 前赋值。

最小接入 ​

ts
import '@qxs-bns/components/video-player'
import type { QxsVideoPlayer } from '@qxs-bns/components/video-player'

const player = document.querySelector<QxsVideoPlayer>('qxs-video-player')!
player.options = { autoplay: true, muted: true, controls: true }
await player.setSource({ url: authorizedUrl, format: 'hls', mode: 'live', revision: 1 })
const unsubscribe = player.on('playing', snapshot => {
  // snapshot positions are milliseconds; live positions are null.
})
// On unmount:
unsubscribe()
player.dispose()

Vue仅将qxs-video-player注册为自定义元素,通过property或ref传参,不拼接HTML属性。不传用户Token、fileId、psign或业务场次。

SSR / VitePress 中应在 onMounted 内动态导入独立入口;<ClientOnly> 本身不能防止顶层静态 import 在服务端执行。options 应在 setSource 前设置,播放期间通过控制方法修改静音、音量与倍速。setSource 完成只代表初始化已提交,媒体可用以 ready 为准,真实播放以 playing 为准。

能力与边界 ​

  • format为hls/mp4,与live/vod模式独立;直播无拖动或倍速。
  • play/pause/seek/setRate/setMuted/setVolume/requestFullscreen/exitFullscreen为控制接口。
  • on返回取消订阅函数;同名DOM事件为qxs-player-*,detail类型从独立入口导入。
  • 自动播放无法绕过浏览器策略:默认静音,被拒时显示可点击播放按钮。不以调用play成功代替playing事件。
  • 组件不自动重新签名或无限重试;H5业务层统一管理1/2/4/8/15秒重试、状态检查和主动暂停。内核HLS网络重试关闭,避免叠加。
  • SDK快捷键仅在播放器内部获焦时处理,不监听宿主页面的全局快捷键;焦点在后台预览层时Escape由模态层处理,播放器内部的退出全屏快捷键仍归SDK。
  • 倍速菜单在点击菜单外部、焦点移出、窗口失焦或按 Escape 时关闭;菜单内部的按钮切换和倍速选择仍由 SDK 处理。
  • 切源用新的revision,旧实例事件被丢弃;连续setSource复用原生video元素、重新创建SDK,保留按元素授予的播放许可。显式dispose或组件移除仍销毁媒体,不保留旧地址;dispose可重复调用。业务层负责恢复声音/倍速及当前来源的位置。
  • 同一个 DOM 元素移除后重新挂载,或调用 dispose() 后继续使用,需要重新调用 setSource() 初始化。

组件负责媒体播放与事件通知。播放地址鉴权、续签、业务状态轮询、断流重试、学习进度上报由宿主业务负责。画中画、下载、截图和小窗入口当前关闭;字幕、清晰度选择和 DRM 没有公共接口。移动浏览器的自动播放、音量和全屏能力仍需在目标设备上验收。

观看时长应由独立业务模块结合 playing/pause/waiting/ended、timeupdate/seeking/seeked/ratechange 和页面可见性计算;倍速折算、跳转排除及服务端校验属于业务规则。切源、销毁与卸载前,宿主应主动结束当前计时区间:组件会丢弃旧实例事件,不保证销毁时再发送 pause。播放器事件只能证明播放状态,不能证明用户实际注意力。

全屏按钮在支持标准 Fullscreen API 的浏览器中使用组件宿主,在其他浏览器中保留 SDK 的原生视频或前缀 API 回退。公开的 requestFullscreen/exitFullscreen 方法使用标准 Fullscreen API;不支持时报告 FULLSCREEN_UNSUPPORTED。

构建与验证 ​

本地构建:pnpm run build:components。产物位于dist/components。后台与H5使用各自vendor目录中同一份完整组件tgz快照,锁文件固定完整性,不依赖本机兄弟目录或必须先发布npm。包来源、SHA-256、更新和独立消费者构建步骤以两端vendor/README.md为准。

分发验证:构建后运行pnpm test:video-package。脚本在临时目录打包并安装真实tgz(不执行安装脚本、不自动安装无关编辑器peer依赖),检查ESM/CJS/类型入口、固定HLS依赖和可移植依赖声明,再编译独立TypeScript消费者并完成Vite构建;断言播放器入口不加载Tiptap或ECharts。正常访问依赖仓库,测试结束自动清理临时目录,不发布npm版本。快照不代表远程npm版本已包含这些改动;将来发布npm时需要分配新版本并同步两端锁文件。

测试:pnpm --filter @qxs-bns/components test __tests__/video-player/video-player.test.ts;浏览器测试见tests/video-player/,需H5开发服务器、Chrome/WebKit和ffmpeg可用。QXS_MEDIA_BASE_URL=http://127.0.0.1:9021 pnpm exec playwright test --config playwright.video.config.ts会在临时目录生成无业务数据的测试视频,不使用线上直播或产生云费用;WebKit换用playwright.video.webkit.config.ts。端口按当前H5服务调整,两套浏览器测试顺序执行,避免互相覆盖临时媒体。

公共视频播放器 has loaded