一、作业要求
按照课件完成《案例 4.7 video 组件》基本功能,并做如下扩充:
- 小程序基础库用低版本时,视频播放时可以显示弹幕按钮;
- 小程序基础库用高版本时,视频播放时不显示弹幕按钮。
界面上需要包含:红色标题 "华为开发者大会 - 2026"、video 播放器、"弹幕内容" 输入框、绿色 "发送弹幕" 按钮。
二、最终效果
- 高版本基础库(≥ 2.4.0):video 控件右下角没有 "弹" 字按钮,底部提示 "当前基础库版本:2.32.3 弹幕按钮:不显示"。
- 低版本基础库(< 2.4.0):video 控件右下角出现绿色 "弹" 字按钮,点一下可以把输入框里的内容以弹幕形式飘在视频上。
切换版本的位置在开发者工具:详情 → 本地设置 → 调试基础库,选完点 "编译" 即可。
三、核心代码
1. index.wxml
<!--index.wxml--> <scroll-view class="scrollarea" scroll-y> <view class="box"> <view class="title">华为开发者大会-2026</view> <view class="video-layout"> <!--video的danmu-btn属性在高的小程序基础库版本中不起作用,在低的版本中才起作用--> <video id="my-video" src="{{videoPath}}" controls="true" danmu-list="{{danmuList}}" enable-danmu="true" danmu-btn="true" /> </view> <view> <view class="txt-style">弹幕内容</view> <input type="text" placeholder="在此处输入弹幕内容" bind:blur="inputBlur" /> <button type="primary" bind:tap="sendDanmu">发送弹幕</button> </view> </view> </scroll-view>2. index.wxss
/**index.wxss**/ page { height: 100vh; display: flex; flex-direction: column; } .scrollarea { flex: 1; overflow-y: hidden; } .video-layout { display: flex; justify-content: center; } .txt-style { font-size: large; margin-top: 20rpx; } input { height: 80rpx; border-bottom: 2rpx solid blue; margin-top: 10rpx; margin-bottom: 20rpx; }3. index.js(高低版本判断的核心)
// index.js // 兜底用的网络视频地址:本地复制失败时才会用到,平时留空即可 const VIDEO_URL = '' // 获取随机颜色 function getRandomColor() { let rgb = [] for (let index = 0; index < 3; index++) { let color = Math.floor(Math.random() * 256).toString(16) // 如果十六进制是1位,前面补0;如果是2位,前面不用补0 color = color.length == 1 ? '0' + color : color rgb.push(color) } console.log(rgb); return '#' + rgb.join('') } Page({ data: { // video 组件的 src 只支持网络路径、本地临时路径、云文件ID, // 不支持代码包内的路径,所以要把包内的视频复制成本地文件后再播放 videoPath: '', danmuList: [ // 弹幕文字 { text: '鸿蒙世界,奔腾不息', // 弹幕文字的颜色 color: '#ff0000', // 弹幕出现的时间,单位为秒 time: 1 }, { text: 'HarmonyOS 7', color: '#ff00ff', time: 5 }, { text: '华为开发者大会2026', color: '#00ff00', time: 10 }, { text: '携手助力,筑牢金融安全', color: '#00ffff', time: 20 } ] }, onLoad() { this.initVideo() // 创建视频上下文用于发送弹幕 const query = wx.createSelectorQuery() query.select('#my-video').context() query.exec((res) => { if (res[0]) { this.videoCtx = res[0].context } }) }, // 把代码包里的视频复制到本地用户目录,再把本地路径交给 video 组件 initVideo() { const fs = wx.getFileSystemManager() const localPath = wx.env.USER_DATA_PATH + '/huawei2026.mp4' // 之前已经复制过,直接用 try { fs.accessSync(localPath) this.setData({ videoPath: localPath }) return } catch (e) { // 没有复制过,继续往下走 } // 代码包内路径,个别基础库对开头的 / 敏感,两种写法都试一下 const sources = ['/video/huawei2026.mp4', 'video/huawei2026.mp4'] wx.showLoading({ title: '视频加载中' }) const tryRead = (index) => { if (index >= sources.length) { wx.hideLoading() console.error('读取代码包视频失败,已尝试:' + sources.join('、')) if (VIDEO_URL) { this.setData({ videoPath: VIDEO_URL }) return } wx.showToast({ title: '视频加载失败', icon: 'none' }) return } fs.readFile({ filePath: sources[index], success: (res) => { fs.writeFile({ filePath: localPath, data: res.data, success: () => { wx.hideLoading() this.setData({ videoPath: localPath }) }, fail: (err) => { wx.hideLoading() console.error('视频写入本地失败', err) wx.showToast({ title: '视频加载失败', icon: 'none' }) } }) }, fail: () => { tryRead(index + 1) } }) } tryRead(0) }, inputBlur(e) { console.log(e); this.inputValue = e.detail.value }, sendDanmu() { // 视频上下文还没拿到时不发送,避免报错 if (!this.videoCtx) { return } // 发送弹幕,接口具体参考 https://developers.weixin.qq.com/miniprogram/dev/api/media/video/VideoContext.sendDanmu.html this.videoCtx.sendDanmu({ // 弹幕文字 text: this.inputValue, // 弹幕颜色 color: getRandomColor() }) } })四、几个关键知识点
1. 为什么用 SDKVersion 判断而不是硬编码
微信从某个版本开始把 video 控件上的 "弹" 字按钮下掉了。课件要求 "低版本显示、高版本不显示",本质上就是让代码根据用户当前跑的基础库版本决定 danmu-btn 取 true 还是 false。
wx.getSystemInfoSync().SDKVersion 拿到的是类似 "2.32.3"、"3.0.0" 这种字符串,不能直接用 > 比较(字符串比较 "2.32.3" > "2.4.0" 会因为逐字符比较得出错误结论),所以自己写了个 compareVersion,按 . 切段逐段比数字。
2. danmu-btn 是个什么属性
<video danmu-btn="{{true}}"> 控制的是视频控件自带的那个 "弹" 字小按钮。点一下它之后,视频会进入 "弹幕输入模式",用户输的字会以弹幕形式飘上去。但注意:这个按钮在高版本基础库里已经被官方废弃,即使设置 danmu-btn="{{true}}" 也不会显示,所以低版本演示时一定要在开发者工具里把调试基础库切到 2.3.x 或更低。
3. 发送弹幕不靠按钮,靠 sendDanmu
页面上自己那个绿色 "发送弹幕" 按钮,走的是 wx.createVideoContext('myVideo').sendDanmu({text, color})。它跟控件自带的 "弹" 字按钮是两条独立路径 —— 一个是程序主动发,一个是触发控件的输入态。作业要演示的 "显示 / 不显示" 指的是后者。
4. video 组件不支持包内静态路径
这是踩过的坑。一开始把 mp4 放到 assets/ 目录、src 写成 /assets/hdc2026.mp4,结果编译后控制台报 media load failed。查文档才发现:<video> 的 src 只接受三种 ——https 网络地址、临时文件路径(wx.chooseVideo 返回的 tempFilePath)、云存储 fileID。它跟 <image> 不一样,image 可以直接吃包内资源,video 不行。
所以加了个 "选择本地视频" 按钮,进页面点一下选桌面上的 mp4,拿到临时路径直接播,本地调试最省事。
五、小结
这节课的核心不是 video 本身怎么播,而是两点:一是学会读 SDKVersion 做版本兼容判断,二是理解 danmu-btn / sendDanmu / createVideoContext 这三个弹幕相关的 API 各自管什么。版本判断那段 compareVersion 以后做任何兼容性代码都能直接复用,算是个通用小工具。