前言
通常情况端上做刷礼物动画时,需要播放背景透明的礼物特效动画,这种情况map4相对其他json/webgl/gif/svga等等格式的动画来说体积往往更小且像素会更清晰,更能打动大哥们得打赏~,端上一般引用QGVAPlayer插件播放,而h5需要引入video-animation-player
直接上代码
第一步:
cnpm i video-animation-player
第二步:
<template> <van-image ref="vedioRef" :src="urlImg" class="mp4-transparent-vedio" /> </template> <script lang='ts' setup> import { ref, nextTick } from 'vue' import Vap from 'video-animation-player' const show = ref<boolean>(false) const vedioRef = ref() const url = ref<string>('') const urlImg = ref<string>('') const vapPlayer = ref() const playVideo = (animation:string = '', animationUrl:string = '', json:string = '', fps:number = 30) => { url.value = animation urlImg.value = animationUrl show.value = true nextTick(() => { vapPlayer.value = new Vap({ container: vedioRef.value, // 要渲染的载体,dom元素 src: url.value, // vap动画地址 config: json, // 播放vap动画需要的 json文件。必填 width: window.innerWidth, // 容器宽度 height: window.innerHeight, // 容器高度 fps, // 帧数,json文件中有这个视频的帧数的,可以看一下, mute: true, // 静音 type: 2, // 组件基于type字段做了实例化缓存,不同的VAP实例应该使用不同的type值(如0、1、2等) loop: false, // 循环 precache: false, // 预加载视频,下载完再播。小动画建议边下边播,大动画还是先下后播吧,因为太大了或者网络不好,会一卡一卡的。 beginPoint: 0, // 起始播放时间点(单位秒),在一些浏览器中可能无效 accurate: true, // 是否启用精准模式(使用requestVideoFrameCallback提升融合效果,浏览器不兼容时自动降级) }) vapPlayer.value.play() // 开始播放 vapPlayer.value.on("ended", () => { // 监听播放完成的事件 closeVedio() }) }) } const closeVedio = () => { vapPlayer.value.destroy() vapPlayer.value = null show.value = false } defineExpose({ playVideo, closeVedio, }); </script> <style scoped lang="scss"> .mp4-transparent-vedio { width: 100vw; height: 100vh; } </style>
上面那种方式需要nodejs起本地服务,如果要本地直接利用html播放(flutter中也是将html和对应的js放入并启动即可),则需要自己解析mp4中的json并播放
// JSON配置解析器 const VapConfigParser = async (file) => { const buffer = await file.slice(0, 1024 * 1024).arrayBuffer(); const uint8 = new Uint8Array(buffer); // 查找配置起始标记 {"info": const startMark = [0x7B, 0x22, 0x69, 0x6E, 0x66, 0x6F, 0x22, 0x3A]; let startIndex = -1; for (let i = 0; i < uint8.length - startMark.length; i++) { if (startMark.every((v, j) => uint8[i + j] === v)) { startIndex = i; break; } } if (startIndex === -1) throw new Error('未找到JSON配置'); // 解析完整JSON结构 let braceCount = 0; let inString = false; let endIndex = startIndex; for (let i = startIndex; i < uint8.length; i++) { const char = String.fromCharCode(uint8[i]); if (char === '"' && (i === 0 || uint8[i - 1] !== 0x5C)) { inString = !inString; } if (!inString) { if (char === '{') braceCount++; if (char === '}') { braceCount--; if (braceCount === 0) { endIndex = i; break; } } } } const jsonStr = new TextDecoder().decode(uint8.slice(startIndex, endIndex + 1)) return JSON.parse(jsonStr) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话