在开发小程序冥想功能时,我们遇到了几个棘手的问题:用户反馈手机熄屏后音频停止、iOS设备播放没声音、冥想音频没有访问计数和CDN缓存优化等。本文将分享这些问题的解决过程和实践经验。
微信小程序简称:Moodo
微信小程序全程:AIMoodo心情日记系统
简介:一款在线的心情记录小程序,同时开通了心情鼓励师、冥想和助眠、心情社区(在建)模块,欢迎大家体验和交流。
问题分析
1. 熄屏停止播放
这是最常见的反馈。用户打开冥想音频,锁屏后发现音频停止了。这是因为小程序默认在进入后台时会暂停音频播放,需要特殊处理。
2. iOS设备播放无声
iOS用户反馈点击播放按钮后,进度条在走但就是听不到声音。这涉及到iOS对音频播放的特殊限制。
3. 实现访问统计
多用户同时打开冥想详情页时,访问计数有时会出现偏差。这是并发访问导致的问题。
4. CDN缓存优化
音频逻辑优化后发现云开发后台CDN流量走的快了。
解决方案
1. 后台播放支持
首先在 app.json 中添加后台播放模式:
json
{
"requiredBackgroundModes": ["audio"]
}
然后使用 BackgroundAudioManager 替代普通的音频播放:
javascript
// 获取后台播放管理器
this.backgroundAudioManager = wx.getBackgroundAudioManager();
// 必要的配置
this.backgroundAudioManager.title = this.data.meditation?.title || '冥想音频';
this.backgroundAudioManager.epname = '冥想';
this.backgroundAudioManager.singer = '冥想助手';
this.backgroundAudioManager.coverImgUrl = this.data.backgroundUrl;
this.backgroundAudioManager.src = this.data.mediaUrl;
// 监听播放事件
this.backgroundAudioManager.onPlay(() => {
this.setData({ isPlaying: true });
});
this.backgroundAudioManager.onPause(() => {
this.setData({ isPlaying: false });
});
2. iOS播放适配
移除了之前的特殊处理代码,直接使用 BackgroundAudioManager 就能解决 iOS 的播放问题。它会自动处理用户授权和播放状态。
3. 访问计数优化
原本使用事务来处理并发访问:
javascript
// 旧代码
const transaction = await db.startTransaction()
const record = await transaction.collection('meditation_resources')
.doc(event.id)
.get()
改用原子操作,既简单又高效:
javascript
// 新代码
const result = await db.collection('meditation_resources')
.doc(event.id)
.update({
data: {
visitCount: _.inc(1)
}
})
4. 资源缓存优化
实现了智能的缓存管理策略:
javascript
async getFileUrl(fileID) {
// 先从缓存获取
const cachedUrl = await cacheManager.getFromCache(fileID);
if (cachedUrl) {
try {
await this.checkUrlValidity(cachedUrl);
return cachedUrl;
} catch (error) {
console.log('缓存已失效');
}
}
// 获取新链接并缓存
const url = await this.getNewUrl(fileID);
await this.preloadAndCacheResource(fileID, url);
return url;
}
对不同类型的资源采用不同的缓存策略:
javascript
async preloadAndCacheResource(fileID, url) {
const isMedia = url.match(/\.(mp3|wav|aac|mp4|m4a)$/i);
if (isMedia) {
// 媒体文件下载到本地
const localPath = await this.downloadToLocal(url);
await cacheManager.saveToCache(fileID, localPath);
} else {
// 其他资源只缓存URL
await cacheManager.saveToCache(fileID, url);
}
}
实践总结
1. 音频播放要点:
- 使用 BackgroundAudioManager 支持后台播放
- 需要在 app.json 中配置权限
- 播放器状态同步很重要
2. 缓存策略:
- 区分资源类型采用不同策略
- 定期清理过期缓存
- 验证缓存有效性
3. 性能优化:
- 使用原子操作处理并发
- 资源预加载
- 并行加载提升体验
注意事项
1. 后台播放限制:
- 留意系统限制
- 考虑耗电问题
2. 存储管理:
- 合理设置缓存期限
- 及时清理无效缓存
- 控制存储空间使用
3. 用户体验:
- 添加加载提示
- 优化播放控制
- 保持状态同步
后续优化
1. 可以考虑添加:
- 播放历史记录
- 离线播放支持
- 自动续播功能
2. 进一步优化:
- 网络适应策略
- 预加载机制
- 错误重试机制
希望这些经验能帮助大家在开发类似功能时少走弯路。如果你有更好的解决方案,欢迎在评论区交流讨论。