2024年夏季《移动软件开发》实验报告
一、实验目标
1、掌握视频API的操作方法;
2、掌握如何发送随机颜色的弹幕;
3、学习如何调整视频倍速播放。
二、实验步骤
1. 项目初始化与基础配置
1.1 创建小程序项目:
- 打开微信开发者工具,创建一个新的小程序项目,命名为“口述校史视频播放”。
- 确认项目目录结构中包含
pages/index
文件夹,作为首页。
1.2 删除不必要的默认文件:
-
在项目中,删除不需要的默认生成文件,例如
logs
目录及其内容。 -
确保项目只保留首页
index
,并在app.json
中配置页面路径和窗口属性:{ "pages": [ "pages/index/index" ], "window": { "navigationBarBackgroundColor": "#987938", "navigationBarTitleText": "口述校史" } }
1.3 创建并配置资源文件:
- 在项目根目录下创建
images
文件夹,用于存放播放图标(play.png
)。 - 确保所有需要的资源文件都放置到合适的目录中,便于页面引用。
2. 页面布局与样式设计
2.1 视频播放器区域设计:
-
在
index.wxml
中,使用<video>
组件创建视频播放器,并设置必要的属性:<video id="myVideo" controls enable-danmu danmu-btn src="{{src}}" playback-rate="{{playbackRate}}"></video>
组件配置说明:
controls
属性:显示播放、暂停、音量控制等常规操作按钮。enable-danmu
和danmu-btn
属性:开启弹幕功能并显示发送弹幕的按钮。
2.2 弹幕输入与发送区域设计:
-
在视频播放器下方添加一个输入框和按钮区域,用户可以输入弹幕内容并点击按钮发送弹幕:
<view class="danmuArea"> <input type="text" placeholder="请输入弹幕内容" bindinput="getDanmu"></input> <button bindtap="sendDanmu">发送弹幕</button> </view>
布局说明:
- 使用
flex
布局,使输入框和按钮水平排列,并通过flex-grow
让输入框根据屏幕宽度自适应扩展。
- 使用
2.3 视频列表设计:
-
通过
wx:for
循环动态生成多个视频列表项,每个项包含播放图标和视频标题。点击标题可切换播放内容:<view class="videoList"> <view class="videoBar" wx:for="{{list}}" wx:key="video{{index}}" data-url="{{item.videoUrl}}" bindtap="playVideo"> <image src="/images/play.png"></image> <text>{{item.title}}</text> </view> </view>
2.4 页面样式设计:
-
在
index.wxss
中编写页面样式,确保不同设备下的布局效果良好。以下是视频列表和弹幕区域的样式代码示例:.danmuArea { display: flex; flex-direction: row; margin-bottom: 20rpx; } input { flex-grow: 1; border: 1rpx solid #987938; height: 100rpx; padding: 10rpx; } button { color: white; background-color: #987938; padding: 10rpx 20rpx; } .videoList { width: 100%; min-height: 400rpx; } .videoBar { display: flex; flex-direction: row; align-items: center; border-bottom: 1rpx solid #987938; padding: 10rpx 0; margin: 10rpx 0; }
3. 页面逻辑实现与功能调试
3.1 视频播放与切换功能实现:
-
在
index.js
中,使用onLoad
生命周期函数创建视频上下文:onLoad: function () { this.videoCtx = wx.createVideoContext('myVideo'); }
-
点击视频列表中的任意标题时,使用
playVideo
函数切换视频播放地址并播放新的视频:playVideo: function (e) { this.videoCtx.stop(); // 停止当前视频 this.setData({ src: e.currentTarget.dataset.url }); this.videoCtx.play(); // 播放新的视频 }
3.2 弹幕发送功能实现:
-
使用
getDanmu
函数获取用户输入的弹幕内容,并使用sendDanmu
函数将弹幕内容和颜色发送到视频中:getDanmu: function (e) { this.setData({ danmuTxt: e.detail.value }); }, sendDanmu: function () { const text = this.data.danmuTxt; this.videoCtx.sendDanmu({ text: text, color: this.getRandomColor() }); }, getRandomColor: function () { const rgb = []; for (let i = 0; i < 3; ++i) { let color = Math.floor(Math.random() * 256).toString(16); color = color.length === 1 ? '0' + color : color; rgb.push(color); } return '#' + rgb.join(''); }
3.3 倍速播放功能实现:
-
在页面中设计一个倍速选择区域,提供不同倍速选项,如 0.5x、1x、1.5x 和 2x。用户点击对应按钮即可设置播放速率:
<view class="speedControl"> <button bindtap="setSpeed" data-rate="0.5">0.5x</button> <button bindtap="setSpeed" data-rate="1.0">1x</button> <button bindtap="setSpeed" data-rate="1.5">1.5x</button> <button bindtap="setSpeed" data-rate="2.0">2x</button> </view>
-
在
index.js
中实现setSpeed
函数,根据用户选择的倍速设置播放速率:setSpeed: function (e) { const rate = parseFloat(e.currentTarget.dataset.rate); this.setData({ playbackRate: rate }); this.videoCtx.playbackRate(rate); // 设置播放速度 }
-
在布局上,通过使用
flex
布局,保证倍速按钮与其他功能区域之间的合理间距,避免按钮重叠或操作冲突。
4. 最终调试与功能验证
- 完成上述代码后,进行多次调试,验证视频播放器、弹幕发送和倍速选择功能是否正常工作。
- 修复页面显示不佳、按钮布局重叠、CSS 语法错误等问题,确保所有功能在不同设备上表现一致。
三、程序运行结果
1. 关键代码展示:
Page({
data: {
src: '',
danmuTxt: '',
playbackRate: 1.0, // 默认播放速度
list: [
{
id: '1001',
title: '杨国宜先生口述校史实录',
videoUrl: 'http://arch.ahnu.edu.cn/__local/6/CB/D1/C2DF3FC847F4CE2ABB67034C595_025F0082_ABD7AE2.mp4?e=.mp4'
},
{
id: '1002',
title: '唐成伦先生口述校史实录',
videoUrl: 'http://arch.ahnu.edu.cn/__local/E/31/EB/2F368A265E6C842BB6A63EE5F97_425ABEDD_7167F22.mp4?e=.mp4'
},
{
id: '1003',
title: '倪光明先生口述校史实录',
videoUrl: 'http://arch.ahnu.edu.cn/__local/9/DC/3B/35687573BA2145023FDAEBAFE67_AAD8D222_925F3FF.mp4?e=.mp4'
},
{
id: '1004',
title: '吴仪兴先生口述校史实录',
videoUrl: 'http://arch.ahnu.edu.cn/__local/5/DA/BD/7A27865731CF2B096E90B522005_A29CB142_6525BCF.mp4?e=.mp4'
}
]
},
onLoad: function () {
this.videoCtx = wx.createVideoContext('myVideo');
},
// 获取弹幕内容
getDanmu: function (e) {
this.setData({
danmuTxt: e.detail.value
});
},
// 播放视频
playVideo: function (e) {
this.videoCtx.stop();
this.setData({
src: e.currentTarget.dataset.url
});
this.videoCtx.play();
},
// 发送弹幕
sendDanmu: function () {
const text = this.data.danmuTxt;
this.videoCtx.sendDanmu({
text: text,
color: this.getRandomColor()
});
},
// 生成随机颜色
getRandomColor: function () {
const rgb = [];
for (let i = 0; i < 3; ++i) {
let color = Math.floor(Math.random() * 256).toString(16);
color = color.length === 1 ? '0' + color : color;
rgb.push(color);
}
return '#' + rgb.join('');
},
// 设置播放速度
setSpeed: function (e) {
const rate = parseFloat(e.currentTarget.dataset.rate);
this.setData({
playbackRate: rate
});
this.videoCtx.playbackRate(rate); // 设置播放速度
}
});
/* 全局样式 */
.container {
padding: 20rpx;
}
/* 视频播放器样式 */
video {
width: 100%;
margin-bottom: 20rpx;
}
/* 弹幕区域样式 */
.danmuArea {
display: flex;
flex-direction: row;
margin-bottom: 20rpx;
}
input {
flex-grow: 1;
border: 1rpx solid #987938;
height: 100rpx;
padding: 10rpx;
}
button {
color: white;
background-color: #987938;
padding: 10rpx 20rpx;
}
/* 倍速选择器样式 */
.speedControl {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
}
.speedControl button {
background-color: #987938;
color: white;
padding: 10rpx 20rpx;
border-radius: 10rpx;
}
/* 视频列表样式 */
.videoList {
width: 100%;
min-height: 400rpx;
}
.videoBar {
display: flex;
flex-direction: row;
align-items: center;
border-bottom: 1rpx solid #987938;
padding: 10rpx 0;
margin: 10rpx 0;
}
image {
width: 70rpx;
height: 70rpx;
margin-right: 20rpx;
}
text {
font-size: 45rpx;
color: #987938;
flex-grow: 1;
}
<view class="container">
<!-- 区域 1: 视频播放器 -->
<video id="myVideo" controls enable-danmu danmu-btn src="{{src}}" playback-rate="{{playbackRate}}"></video>
<!-- 区域 2: 弹幕控制 -->
<view class="danmuArea">
<input type="text" placeholder="请输入弹幕内容" bindinput="getDanmu"></input>
<button bindtap="sendDanmu">发送弹幕</button>
</view>
<!-- 区域 3: 倍速选择器 -->
<view class="speedControl">
<button bindtap="setSpeed" data-rate="0.5">0.5x</button>
<button bindtap="setSpeed" data-rate="1.0">1x</button>
<button bindtap="setSpeed" data-rate="1.5">1.5x</button>
<button bindtap="setSpeed" data-rate="2.0">2x</button>
</view>
<!-- 区域 4: 视频列表 -->
<view class="videoList">
<view class="videoBar" wx:for="{{list}}" wx:key="video{{index}}" data-url="{{item.videoUrl}}" bindtap="playVideo">
<image src="/images/play.png"></image>
<text>{{item.title}}</text>
</view>
</view>
</view>
2. 运行结果截图:
四、问题总结与体会
问题总结:
1. 视频播放与弹幕功能的实现难点
在本次实验中,微信小程序的 <video>
组件是核心部分,如何高效地控制视频播放、暂停、切换以及弹幕功能是实验的重点。在实现过程中,我主要遇到了以下几个问题:
- 在实现视频切换功能时,必须确保当前视频停止后再加载新的视频。通过
wx.createVideoContext
管理视频上下文,以及使用videoCtx.stop()
和videoCtx.play()
控制播放流程,有效解决了这个问题。 - 为了增强用户体验,实现了弹幕颜色随机生成的功能。在最终代码中,通过三次随机生成 0-255 之间的值并转化为十六进制颜色代码,成功实现了该功能。
2. 倍速播放功能的实现
在视频 API 中,playbackRate
是控制播放速度的关键参数。虽然 API 本身支持设置不同速率,但如何将这一功能集成到良好的用户体验中需要注意以下几点:
- 在设计倍速选择器时,考虑了用户操作的直观性和便捷性。通过为每个倍速按钮设置明确的标签(如 0.5x、1x、1.5x、2x),用户可以轻松选择合适的播放速度。
- 在实际调试过程中,针对不同网络环境和视频资源类型,进行了多次测试,确保在切换倍速时视频播放流畅且无明显卡顿。
心得体会:
在本次实验中,我深入学习了微信小程序的视频 API,并在实验过程中实践了视频播放控制、弹幕发送以及视频倍速播放等功能的实现。整个实验过程让我对小程序开发有了更加系统的理解,也让我认识到在实际项目中解决问题的重要性。
首先,在开发中,视频播放和弹幕功能是小程序中常见的交互形式,如何通过简洁的代码实现复杂的功能是我在这次实验中着重思考的内容。微信小程序提供了丰富的 API 支持,但这些功能的实现往往需要我们对其背后的原理和最佳实践有更深入的理解。
对于倍速播放功能的实现,在实际操作中,虽然微信小程序的 API 已经提供了播放速率控制的接口,但在实际使用中,需要反复调试确保功能的稳定性和流畅性。这一部分让我意识到,技术的创新不仅在于功能实现本身,还在于如何通过良好的交互设计将技术更好地应用到实际项目中。
通过本次实验,我对小程序开发的整体流程有了更加全面的认识,从项目初始化、页面布局到功能实现、问题调试,每一步都让我在开发实践中积累了宝贵的经验。在未来的学习和项目开发中,我将更加注重代码的规范性、功能的实用性和用户体验的提升,同时继续探索更多具有创新性的开发方式。