2026/4/18 8:03:44
网站建设
项目流程
群辉做网站服务器配置,哪个网站可以做司考题,天津建设工程信息网中标公告,长沙网站关键词排名推广公司查看微信的官方文档
DownloadTask wx.downloadFile(Object object) 以 Promise 风格 调用#xff1a;不支持 小程序插件#xff1a;支持#xff0c;需要小程序基础库版本不低于 1.9.6 微信 Windows 版#xff1a;支持 微信 Mac 版#xff1a;支持 微信 鸿蒙 OS 版#x…查看微信的官方文档DownloadTask wx.downloadFile(Object object)以 Promise 风格 调用不支持小程序插件支持需要小程序基础库版本不低于 1.9.6微信 Windows 版支持微信 Mac 版支持微信 鸿蒙 OS 版支持相关文档: 网络使用说明、局域网通信功能描述下载文件资源到本地。客户端直接发起一个 HTTPS GET 请求返回文件的本地临时路径 (本地路径)单次下载允许的最大文件为 200MB。使用前请注意阅读相关说明。注意请在服务端响应的 header 中指定合理的Content-Type字段以保证客户端正确处理文件类型。参数Object object属性类型默认值必填说明最低版本urlstring是下载资源的 urlheaderObject否HTTP 请求的 HeaderHeader 中不能设置 Referertimeoutnumber60000否超时时间单位为毫秒默认值为 60000 即一分钟。2.10.0filePathstring否指定文件下载后存储的路径 (本地路径)1.8.0文档标识只支持200MB的文件那么我们如何下载超过200MB的文件呢我尝试通过分块下载来实现这个逻辑先把文件拆分成多个子文件下载下来然后再一起合并成最终的视频。import {authorize} from ./download; const fs wx.getFileSystemManager(); const fileName video.mp4 // 下载的文件名 const tempFilePath wx.env.USER_DATA_PATH /downloads4_ // 临时文件存储路径 // const FILE_PATH ${wx.env.USER_DATA_PATH}/downloaded_video.mp4; // 最终合并输出路径 const BLOCK_SIZE 1024 * 1024 * 300; // 每块大小5MB /** * 获取远程视频文件大小 */ function getFileSize(url) { return new Promise((resolve, reject) { uni.request({ url, method: HEAD, success: (res) { const size parseInt(res.header[Content-Length] || res.header[content-length]); resolve(size); }, fail: reject, }); }); } /** * 下载单个分块并写入临时 chunk 文件 */ function downloadChunk(url, start, end, index,callback) { return new Promise((resolve, reject) { // uni.request({ // url, // header: { // Range: bytes${start}-${end}, // }, // responseType: arraybuffer, // success: (res) { // const chunkPath ${wx.env.USER_DATA_PATH}/chunk_${index}; // fs.writeFile({ // filePath: chunkPath, // data: res.data, // encoding: binary, // success: resolve, // fail: reject, // }); // }, // fail: reject, // }); authorize().then(() { console.log(${tempFilePath}${index}) const tmpFile wx.env.USER_DATA_PATH /downloads4_index.mp4 const task wx.downloadFile({ url: ${url}?t${new Date().getTime()}, //仅为示例并非真实的资源 // header: { // Range: bytes${start}-${end}, // }, // filePath:tmpFile, // filepath: tmpFile, success: (res) { console.log(res); if (res.statusCode 200 res.statusCode 300) { wx.saveVideoToPhotosAlbum({ filePath: res.tempFilePath, success:function(res) { console.log(res) resolve(); // wx.hideLoading(); }, fail: (err) { console.log(err) reject(new Error(Download chunk fail.)) } }) } else { reject(new Error(Download chunk error.)) } }, fail: (err) { console.log(err) reject(new Error(Download chunk fail.)) } }) task?.onProgressUpdate((res) { const { progress, totalBytesWritten, totalBytesExpectedToWrite } res console.log(下载进度 progress); console.log(已经下载的数据长度 totalBytesWritten); console.log(预期需要下载的数据总长度 totalBytesExpectedToWrite); if (callback) { callback(res); }else{ uni.showToast({ icon: none, title: 下载进度 ${progress}%, }); } if (totalBytesExpectedToWrite MaxTotalSize) { const CurTotalSizeMB (totalBytesExpectedToWrite / 1024 / 1024).toFixed(2); // FailReason.errMsg 当前文件${CurTotalSizeMB}MB小程序单次下载允许的最大文件仅为${MaxTotalSizeMB}MB。您可复制下载链接切换到本地浏览器自行下载; task.abort(); return; } }) }) }); } /** * 合并所有 chunk 成一个完整文件 */ function mergeChunks(chunkCount, targetFilePath) { return new Promise((resolve, reject) { try { // 清空或创建目标文件 fs.writeFileSync(targetFilePath,, binary ); for (let i 0; i chunkCount; i) { // const chunkPath ${wx.env.USER_DATA_PATH}/chunk_${i}; const chunkPath wx.env.USER_DATA_PATH /downloads4_i.mp4; console.log(chunkPath:chunkPath); const chunkData fs.readFileSync(chunkPath, binary); fs.appendFileSync( targetFilePath, chunkData, binary, ); // 删除临时 chunk fs.unlinkSync(chunkPath); } resolve(); } catch (err) { console.log(err) reject(err); } }); } // 合并已下载的分片文件 function mergeFiles(chunkCount) { const fs wx.getFileSystemManager() const stream fs.createWriteStream(${wx.env.USER_DATA_PATH}/downloads4_${fileName}) const write (index) { console.log(开始合并index); const path wx.env.USER_DATA_PATH /downloads4_index.mp4; // const path ${wx.env.USER_DATA_PATH}/chunk_${index}; // const chunk chunks[index] // if (!chunk.downloaded) { // console.log(Chunk ${chunk.index} not downloaded.) // return // } fs.readFile(path, binary, (err, data) { if (err) { console.log(err) return } stream.write(data, binary) if (index chunkCount - 1) { write(index 1) } else { // 文件合并完成 stream.end() // this.resetState() } }) } write(0) } /** * 下载完整视频带进度回调 */ async function downloadVideoWithChunks(url, callback) { const totalSize await getFileSize(url); console.log(totalSize:totalSize); const chunkCount Math.ceil(totalSize / BLOCK_SIZE); for (let i 0; i chunkCount; i) { const start i * BLOCK_SIZE; const end Math.min(start BLOCK_SIZE - 1, totalSize - 1); await downloadChunk(url, start, end, i,callback); // if (onProgress) { // onProgress(i 1, chunkCount); // } } const fullPath ${wx.env.USER_DATA_PATH}/downloads4_${fileName} console.log(fullPath, fullPath) // await mergeChunks(chunkCount,fullPath); // await mergeFiles(chunkCount); return fullPath; } /** * 保存文件到相册带权限检查 */ function requestPermissionAndSave(filePath) { return new Promise((resolve, reject) { uni.getSetting({ success(settingRes) { if (!settingRes.authSetting[scope.writePhotosAlbum]) { uni.authorize({ scope: scope.writePhotosAlbum, success: () { uni.saveVideoToPhotosAlbum({ filePath, success: resolve, fail: reject, }); }, fail: () { uni.showModal({ title: 提示, content: 请授权保存到相册, success(res) { if (res.confirm) wx.openSetting(); }, }); reject(new Error(未授权)); }, }); } else { uni.saveVideoToPhotosAlbum({ filePath, success: resolve, fail: reject, }); } }, fail: reject, }); }); } /** * 主函数分块下载 合并 保存 */ export async function downloadAndSaveVideo(url, onProgress) { try { const path await downloadVideoWithChunks(url, onProgress); // await requestPermissionAndSave(path); uni.showToast({ title: 保存成功, icon: success }); } catch (err) { console.error(下载或保存失败:, err); uni.showToast({ title: 失败, icon: none }); } }但在分块的逻辑下虽然下载子文件是没有问题但是在最终合成大视频的环节中还是会报200mb限制大小的错误所以这个方案还是不可行的。最后的最后我神奇的发现其实wx.downloadFile 是支持超过200MB的文件你不要自己定义filePath你用它自己返回的文件路径就好const Task uni.downloadFile({// url: url, //仅为示例并非真实的资源url: ${url}?t${new Date().getTime()}, //仅为示例并非真实的资源// filepath: filePath, // 之前我这里自定义了路径这里需要注释掉timeout: 300 * 1000, // 设置特定超时时间5分钟success: (res) {你用它返回的res.tempFilePath 去保存 要用真机调试开发者工具做了200MB的拦截wx.saveVideoToPhotosAlbum({filePath: res.tempFilePath,success:function(res) {resolve();// wx.hideLoading();},