感谢博主分享 。 改进了一个demo 临时文件 + uniapp + vue3 ts 实现的demo。 多段base64音频合并播放。 最终语音为 深圳。(最后的语音有点断,因为太长了评论超长了) // AudioPlayer.vue import { ref } from "vue"; import { testData } from './videoAudioChunks' interface AudioMessage { header: { code: number; message: string; sid: string; status: number; }; payload?: { audio?: { audio: string; bit_depth: number; ced: string; channels: number; encoding: string; frame_size: number; id: string; sample_rate: number; seq: number; status: number; type: string; }; }; } interface AudioChunk { array: Uint8Array; seq: number; id: string; } const playing = ref(false); const currentAudioPath = ref(''); // 生成临时文件路径 const generateTempFilePath = () => { const timestamp = new Date().getTime(); return `${uni.env.USER_DATA_PATH}/temp_audio_${timestamp}.mp3`; }; // 清理临时文件 const cleanupTempFile = (filePath: string) => { const fs = uni.getFileSystemManager(); fs.access({ path: filePath, success: () => { fs.unlink({ filePath, success: () => { console.log('临时文件清理成功'); }, fail: (err) => { console.error('清理临时文件失败:', err); } }); } }); }; // 处理并播放音频 const processAndPlay = () => { const uniqueChunks = new Map<string, AudioChunk>(); const audioJson = testData // 处理每个音频消息 audioJson.forEach((message) => { if (message.header.code === 0 && message.payload?.audio) { const audio = message.payload.audio; const key = `${audio.id}_${audio.seq}`; // 仅处理未见过的块 if (!uniqueChunks.has(key)) { const audioData = audio.audio; uniqueChunks.set(key, { array: new Uint8Array( atob(audioData) .split("") .map((char) => char.charCodeAt(0)) ), seq: audio.seq, id: audio.id, }); } } }); // 按id和seq排序块 const sortedChunks = Array.from(uniqueChunks.values()).sort((a, b) => { if (a.id === b.id) { return a.seq - b.seq; } return parseInt(a.id) - parseInt(b.id); }); // 合并所有音频块 const totalLength = sortedChunks.reduce( (acc, chunk) => acc + chunk.array.length, 0 ); const combinedArray = new Uint8Array(totalLength); let offset = 0; sortedChunks.forEach((chunk) => { combinedArray.set(chunk.array, offset); offset += chunk.array.length; }); // 生成新的临时文件路径 const tempAudioPath = generateTempFilePath(); const fs = uni.getFileSystemManager(); // 清理之前的临时文件 if (currentAudioPath.value) { cleanupTempFile(currentAudioPath.value); } // 将合并后的数据转换为base64 const base64Data = uni.arrayBufferToBase64(combinedArray); // 写入文件并播放 fs.writeFile({ filePath: tempAudioPath, data: base64Data, encoding: "base64", success() { currentAudioPath.value = tempAudioPath; const backgroundAudioManager = uni.getBackgroundAudioManager(); backgroundAudioManager.title = "音频播放"; backgroundAudioManager.src = tempAudioPath; playing.value = true; backgroundAudioManager.onEnded(() => { playing.value = false; // 播放结束后清理临时文件 cleanupTempFile(tempAudioPath); currentAudioPath.value = ''; }); }, fail(err) { console.error("写入音频文件失败:", err); }, }); };
小程序能不能直接使用base64音频文件播放?使用createInnerAudioContext方法来,存文件到云服务器太费流量了
1天前考虑用点聚合
[需求反馈]地图组件标记点能否设置优先级?业务需求在地图上分布5种资源共约几百个点,当比例尺稍大时,不同类比的标记点与标记点之间、相同类别的标记点与标记点之间都出现了重叠堆砌的情况,视觉效果较差。是否有开放定义标志物地图层级或优先级的计划,改善此类状况? [图片]
2023-06-21同问,体验版出现这个情况,正式版的不会
wx.getLocation 一直fail?,频繁调用会增加电量损耗...errMsg: "getLocation:fail 频繁调用会增加电量损耗,可考虑使用 wx.onLocationChange 监听地理位置变化", 今日开始一直报这个问题正式环境没有,只有测试环境有这样的问题。有人遇到这样的问题吗?怎样解决? [图片]
2021-04-29可以的,这个就是答案,本人已实现https://mp.weixin.qq.com/s/NHvntMN07ehuQl0jeJ5Tqg[图片]
小程序 webview可以长按识别普通二维码吗?(非小程序码)目前有个需求是小程序跳转webview,通过长按识别二维码的形式去导流;但是写了demo试了下,目前是只能识别小程序码,但是看到了一个小程序是可以长按识别出来添加微信的二维码的,跪求各位大大个思路
2020-11-03楼主有解决方案吗
报错:AppServiceSdkKnownError,是什么原因导致的?引用了第三方js,修改成微信识别的js格式,用开发者工具打开 是可以正常调用此js,发布过后,在微信里打开报错:AppServiceSdkKnownError。
2020-05-28同问
小程序调用wx.addCard,显示已成功领取会员卡,但没成功数据返回- 当前 Bug 的表现(可附上截图) 点击领取后,成功领取,在微信卡包可以看到已领取的卡券,但是没有输出成功返回的数据。 当点击返回上一层按钮时候,报一下错误。 [图片] - 预期表现 - 复现路径 - 提供一个最简复现 Demo [图片]
2019-10-25plan B:把微信返回的加密后的code,传给后端,后端去找微信接口换回原来的code。 plan C: addCard success返回的cardList 中的cardExt跟我前端post给微信后台的cardExt的顺序是一致的, 不太严谨的话,依次按顺序把加密前的code拿出来也是可以的。
wx.addCard() 成功回调res.cardList.cardExt为空?问题:在开发者工具上,sucess回调cardExt是正常,但是在真机预览上就都是空的。如果只领取一张,回调是正常的,多张就不可以,但是返回的isSuccess都是true。微信卡包中也能看到刚领取的卡券。再次打开addCard显示的都是已领取。异常都在这个真机cardExt返回为空。 真机:iphone 8, iphone 7p, 小米(型号不详) 需求:后端需要用cardExt里面的code 去做后台确认卡券已被领取。现在想到的就是拿返回的加密code去解密出原来的code,终究不是上策。有其他发方案吗。 返回的数据截图: [图片] 前端代码: [代码]// 一键领取全部优惠券[代码][代码]collectAllCoupons(){[代码][代码] [代码][代码]let wxCardList = [];[代码][代码] [代码][代码]let idList = [];[代码][代码] [代码][代码] [代码][代码]this[代码][代码].canCollectCouponList.forEach(item => {[代码][代码] [代码][代码]let { timestamp, nonce_str, card_id, code, openid, signature } = item.wx_info;[代码][代码] [代码][代码] [代码][代码]wxCardList.push({[代码][代码] [代码][代码]cardId: card_id,[代码][代码] [代码][代码]cardExt: JSON.stringify({[代码][代码] [代码][代码]timestamp,[代码][代码] [代码][代码]nonce_str,[代码][代码] [代码][代码]card_id,[代码][代码] [代码][代码]code,[代码][代码] [代码][代码]openid,[代码][代码] [代码][代码]signature,[代码][代码] [代码][代码]}),[代码][代码] [代码][代码]});[代码][代码] [代码][代码] [代码][代码]idList.push({id: item.id});[代码][代码] [代码][代码] [代码][代码]});[代码] [代码] [代码][代码]console.log([代码][代码]'wxCardList'[代码][代码]);[代码][代码] [代码][代码]console.log(wxCardList);[代码] [代码] [代码][代码]this[代码][代码].addWxCard(wxCardList, idList);[代码][代码]},[代码] [代码][代码] // 添加到微信卡包 addWxCard(wxCardList, idList){ wx.addCard({ cardList: wxCardList, success: (res) => { console.log('res'); console.log(res); let cardList = res.cardList; let toUpdateCouponsList = []; cardList.forEach((item, index)=>{ let cardExt = JSON.parse(item.cardExt); wxCardList.forEach(item2 =>{ if(cardExt.code == JSON.parse(item2.cardExt).code && item.isSuccess){ toUpdateCouponsList.push({ code: cardExt.code, id: idList[index].id, }); } }) }); console.log('toUpdateCouponsList'); console.log(toUpdateCouponsList); if(toUpdateCouponsList.length > 0){ console.log('核销'); this.$api.coupon_sureGot(toUpdateCouponsList).then(res => { this.getCoupon(); //刷新卡券 //正式 wx.showToast({ title: res.data.msg, icon: 'none', duration: 1500, }); }); } }, fail: (err) => { console.log(err) }, }); }, [代码] [代码]
2019-10-24已解决:返回的站点在address地址里面,全部是数字
查询公交站信息需求一: 需要做个一个点击地图上的公交点,弹出该点的公交线路信息。 查来查去,似乎只有腾讯地图里面---web开发---- JavaScript API --StationService 这个东西能返回公交站点信息。请问有啥好的方案吗,我现在能想到只有<web-view>引入腾讯地图web----<script>。再去把信息调出来。 请问有更好的方案吗?
2019-10-24