题主当前项目的配置:
- uniapp:2.0.1-alpha-36920221121001
- vue: 2.6.11
- hbuidler: 3.8.4
- mp开发工具: 1.32.1
1. 设置小程序appid
hbuilder可以在配置文件中输入appid,但是实际小程序开发工具中需要反复输入appid才能进行扫码预览和真机预览。
解决: uniapp的配置文件manifest.json中手动加入 (hello uniapp的demo中没有对应的字段)
json
"mp-kuaishou" : {
"appid": "ksxxxxxxxxxxxxxxx",
"usingComponents" : true
}
2. unzip解压图片包不完整的问题(安卓)
项目中将一个zip文件使用downloadFile + unzip获取一系列图片资源,但是发现安卓设备解压出来的图片总是不完整,具体表现为:图片的底部会出现不定高度的缺失。但是ios设备表现正常。
解决: 手动下载文件并逐个存储。(存的时候需要使用await保证依次执行,否则会大大增加耗时)
javascript
//package.json -> "jszip": "^3.10.1",
uni.request({
url: 'xxxxxxxxx',
method: 'GET',
responseType: 'arraybuffer', //貌似并没有用
success: (img:any)=> {
JSZip.loadAsync(Buffer.from(img.data, 'base64')).then(async (res)=> {
for (const fileName of Object.keys(res.files)) {
let file = res.files[fileName]
await file.async('arraybuffer').then(async buffer=> {
let path = `${dir}/${fileName}`
await this.writeFileToPath(buffer, path)
})
}
});
}, fail: err=> {
console.log(`fetch zip fail`, this.remote_url, err)
}
})
3. mkdir失败
不管是安卓设备还是ios都会mkdir失败。
首先快手的默认临时目录为: kwfile://tmp 。这个可以在开发工具的项目详情-文件系统中看到。用户目录为 kwfile://usr 。但是实际项目中我们想要创建一个tmp/xxx文件夹的时候,真机预览和体验版会返回错误。
解决 通过unzip解压路径来绕过这个问题,下载一个很小的zip文件,将解压路径指定为需要创建的目录即可。
ps: 三级目录可能无法直接创建(kwfile://tmp/abc可以解压, 但kwfile://tmp/abc/dfe可能无法解压)
javascript
_mkdir2 (dir:string) {
return new Promise(async (resolve)=> {
uni.downloadFile({
url: 'xxxxx.zip',
success: (res)=> {
fs.unzip({
zipFilePath: res.tempFilePath,
targetPath: dir,
success:(res)=> {
console.log(`unzip zip success for mkdir`, dir, res)
resolve(true)
},
fail:(err)=> {
console.log(`unzip zip fail for mkdir`, dir, err)
resolve(!true)
},
})
},
fail: (err)=> {
console.log(`download zip file for mkdir fail`, err)
resolve(!true)
}
})
})
}
4. innnerAudioContext播放buffer/base64数据
在H5上我们可以给audio.src赋值base64字符串来播放音频,快手开发工具上也是可以播放的,但是当真机预览的时候,会提示播放不了。base64字符串中的斜杠会被认为是文件路径...
还有一个需要注意的问题,ios设备上会偶尔无法解析base64的音频文件,audiocontext播放这些音频的时候也不会报错,duration时长显示为0。 可以设置base64对应的临时文件后缀为mp3来解决。
解决 将base64写入文件,让audio.src指向临时文件地址
javascript
let tmpfilePath = "kwfile://tmp/" + Date.now() + '.mp3';
this.fs.writeFile({
data: data, //这个base64字符串不用带data:audio/wav;base64,标头
encoding: "base64",
filePath: tmpfilePath,
success: (res) => {
console.log(`write audio file success => ${Date.now() - st}`, res);
this.queueMapForAudio.set(keyInQueueMap, tmpfilePath);
},
});
5. requestAnimationFrame
- 小程序上没办法获得我们在H5上用来定时渲染的requestAnimationFrame方法。但是setInterval相对来说还比较靠谱。
- canvas倒是提供了一个平替的api来处理渲染前的逻辑。但是这个requestAnimationFrame不是每次都执行,而是执行一次。这里的createSelectorQuery方法可以参考快手开发平台的KSML说明
javascript
this?.createSelectorQuery().select('#canvas_shot').node((res)=> {
console.log(`Get canvas Node`, res.node)
if(res.node) {
this.canvasNode = res.node
this.canvasAnimationFrameId = this.canvasNode.requestAnimationFrame(()=> {
console.log(`FIRST requestAnimationFrame1 at => ${Date.now()}`)
})
}
}).exec()
6. canvas.drawImage 和 canvasPutImageData
- H5的putimage可以支持多种类型的参数,但是小程序只能支持文件地址,所以需要把自己获取到的base64或者buffer写成本地文件才能显示。
- canvasPutImageData这个API的执行速度非常非常慢,除非是简单的渲染,否则不太建议