123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- // components/map-sense.js
- let innerAudioContext = wx.createInnerAudioContext({
- useWebAudioImplement: true
- });
- import http from "../../utils/http";
- import { promisify, BeaconUtils } from "../../utils/util";
- let openBluetoothAdapter = promisify(wx.openBluetoothAdapter);
- let closeBluetoothAdapter = promisify(wx.closeBluetoothAdapter);
- let startBeaconDiscovery = promisify(wx.startBeaconDiscovery);
- let stopBeaconDiscovery = promisify(wx.stopBeaconDiscovery);
- import {
- CDN_URL,
- CONNECT_STATUS,
- STATUS_TEXT,
- API_BASE_URL,
- DISTRIBUTION,
- } from "../../config/index";
- const STATUS_PIC = {
- 0: "default",
- 1: "loading",
- 2: "success",
- 3: "fail",
- };
- let audioInterruptionCb = ()=>{}
- let bluetoothAdapterStateChangeCb = ()=>{}
- let isCollect = false
- let changeTO = null
- // 选择6档
- const TXPOWER = -55;
- var result = 0,
- oldResult = -1;
- // 距离经验值(调试所得)
- const N = 3.3;
- const R = 3.4; //设定感应范围半径
- const RSSIVAL = 70; //rssi信号过滤临界点
- let AveLength = 10;
- let group = [
- ["10001", "10002"],
- ["10003"],
- ["10004"],
- ["10005"],
- ["10006"],
- ["10007"],
- ["10008"],
- ["10009"],
- ["10010"],
- ["10011"],
- ["10012", "10013"],
- ["10014"],
- ["10015"],
- ["10016"],
- ["10017"],
- ["10018"],
- ["10019"],
- ["10020", "10021"],
- ["10022"],
- ["10023"],
- ["10024"],
- ];
- // 1:['10001','10002'],2:['10003'],
- // 3:['10004'],4:['10005'],5:['10006'],
- // 6:['10007'],7:['10008'],8:['10009'],
- // 9:['10010'],10:['10011'],11:['10012','10013'],
- // 12:['10014'],13:['10015'],14:['10016'],
- // 15:['10017'],16:['10018'],17:['10019'],
- // 18:['10020','10021'],19:['10022'],
- // 20:['10023'],21:['10024']
- let AudioAddress = {
- 0: "https://culture.4dage.com/demo/audio/1.2.mp3",
- 1: "https://culture.4dage.com/demo/audio/3.mp3",
- 2: "https://culture.4dage.com/demo/audio/4.mp3",
- 3: "https://culture.4dage.com/demo/audio/5.mp3",
- 4: "https://culture.4dage.com/demo/audio/6.mp3",
- 5: "https://culture.4dage.com/demo/audio/7.mp3",
- 6: "https://culture.4dage.com/demo/audio/8.mp3",
- 7: "https://culture.4dage.com/demo/audio/9.mp3",
- 8: "https://culture.4dage.com/demo/audio/10.mp3",
- 9: "https://culture.4dage.com/demo/audio/11.mp3",
- 10: "https://culture.4dage.com/demo/audio/12.13.mp3",
- 11: "https://culture.4dage.com/demo/audio/14.mp3",
- 12: "https://culture.4dage.com/demo/audio/15.mp3",
- 13: "https://culture.4dage.com/demo/audio/16.mp3",
- 14: "https://culture.4dage.com/demo/audio/17.mp3",
- 15: "https://culture.4dage.com/demo/audio/18.mp3",
- 16: "https://culture.4dage.com/demo/audio/19.mp3",
- 17: "https://culture.4dage.com/demo/audio/20.21.mp3",
- 18: "https://culture.4dage.com/demo/audio/22.mp3",
- 19: "https://culture.4dage.com/demo/audio/23.mp3",
- 20: "https://culture.4dage.com/demo/audio/24.mp3",
- };
- Component({
- /**
- * 组件的属性列表
- */
- properties: {},
- /**
- * 组件的初始数据
- */
- data: {
- status: "0",
- cdn_url: CDN_URL,
- connect_status: CONNECT_STATUS,
- status_text: STATUS_TEXT,
- status_pic: STATUS_PIC,
- targetObj: {},
- audio_address: {},
- api_base_url: API_BASE_URL,
- // 是否是扫码播放
- isScanPlay: false,
- cdn_url: CDN_URL,
- classfiy: {},
- },
- /**
- * 组件的方法列表
- */
- methods: {
- openBluetooth(cb) {
- wx.showLoading({
- title: "正在打开蓝牙…",
- mask: true,
- });
- openBluetoothAdapter().then(
- (res) => {
- wx.hideLoading({fail(){}});
- cb(res);
- },
- () => {
- wx.hideLoading({fail(){}});
- wx.showToast({
- title: "请打开蓝牙",
- icon: "error",
- duration: 2000,
- });
- }
- );
- },
- toHandle() {
- if (this.data.status == "2") {
- this.stopBeaconDiscovery();
- return;
- }
- let aveArr = [];
- this.openBluetooth(() => {
- wx.showLoading({
- title: "正在连接…",
- mask: true,
- });
- startBeaconDiscovery({
- uuids: ["FDA50693-A4E2-4FB1-AFCF-C6EB07647825"],
- })
- .then(() => {
- wx.hideLoading({fail(){}});
- this.setData({
- status: "2",
- });
- isCollect = true
- wx.onBeaconUpdate((data) => {
- if (!isCollect) {
- return
- }
- console.log('还在收集…………');
- // 需要收集十组数据,索引号最大的组是最旧的
- if (!aveArr.includes(data.beacons)) {
- if (aveArr.length >= AveLength) {
- //当超过十组时,应该将索引号大的组淘汰掉
- aveArr.pop()
- }
- aveArr.unshift(BeaconUtils.clone(data.beacons)); //在队列前面插入
- }
-
- let all = []; //获取所有data.beacons数据
- for (let i = 0; i < aveArr.length; i++) {
- let ele = aveArr[i];
- for (let j = 0; j < ele.length; j++) {
- let item = ele[j];
- //过滤信号弱的数据
- if (!(item.proximity === 0 && item.rssi === 0)) {
- if (Math.abs(item.rssi) < RSSIVAL) {
- // console.log(item.proximity,item.rssi);
- if (!all.includes(item)) {
- all.push(BeaconUtils.clone(item))
- }
- }
- }
- }
- }
- let accuracyList = {};
- // classfiy = {10003:[{},{},···],10002:[{},{},···],10001:[{},{},···]}
- let classfiy = BeaconUtils.classification(all, "major");
- // console.log(classfiy,'classfiy');
- Object.keys(classfiy).forEach((key) => {
- //每个major的AveLength个元素数组,元素为rssi
- let arr = classfiy[key].map((item) => {
- return item.rssi;
- });
- //每个major的rssi平均值
- let ave = BeaconUtils.arrayAverage(arr);
- //计算平均差
- let meanDeviation = BeaconUtils.getMeanDeviation(arr, ave);
- //计算各rssi的高斯模糊权重
- let guassionArr = []; //存放权重数组
- for (let i = 0; i < arr.length; ++i) {
- guassionArr.push(
- BeaconUtils.getOneGuassionArray(
- arr.length,
- i,
- meanDeviation
- )
- );
- }
- //计算高斯模糊后的rssi值
- let rssiArr = []; //模糊后的rssi数组
- for (let i = 0; i < arr.length; ++i) {
- let sum = 0;
- for (let j = 0; j < arr.length; ++j) {
- if (guassionArr[i].length == 0) {
- sum = arr[j];
- break;
- }
- sum += guassionArr[i][j] * arr[j];
- }
- rssiArr.push(sum);
- }
- //时间加权后求rssi平均值
- let aveOnTime = BeaconUtils.arrayAverage(
- rssiArr
- .slice(0, Math.floor(rssiArr.length / 3))
- .concat(rssiArr)
- );
- //测距,根据时间加权后的rssi计算距离
- // classfiy[key].forEach((item) => {
- let tmp = BeaconUtils.calculateAccuracy(
- TXPOWER,
- aveOnTime,
- N
- );
-
- if (!accuracyList[key]) {
- //如果还没有对应的“信标号”
- accuracyList[key] = [tmp];
- }else{
- accuracyList[key].push(tmp);
- }
- // });
- });
- // Object.keys(accuracyList).forEach(item=>{
- // console.log(accuracyList[item]+'---------'+item);
- // })
-
- // console.log('--------分隔--------');
- // 筛选器,筛选出配对的一组信标
- let signSelect = new Array(21).fill(0); //记录各组的信标出现数量,投票选择最多的,依次是prologue,annexHall,mainHall
- // const prologue = ['10001','10002'] //序厅
- // const annexHall = ['10003','10004','10005','10006','10007'] //附厅
- // const mainHall = ['10008'] //主厅
-
- Object.keys(accuracyList).forEach((key) => {
- let aveAccuracy = BeaconUtils.arrayAverage(accuracyList[key]);
- if (aveAccuracy < R) {
- for (let i = 0; i < group.length; i++) {
- if (group[i].includes(key)) {
- signSelect[i] += 1/(aveAccuracy+0.01); //取距离的反比例函数值,距离越近,值越大,+0.01是为了防止除数为0
- }
- }
- }
- });
- // console.log(signSelect);
- //对小于预设半径的信号进行数量投票
- result = BeaconUtils.maxIndex(signSelect);
- // console.log("result", result);
- if (result != null && result !== oldResult) {
- wx.hideLoading({fail(){}})
- this.playAudio(AudioAddress[result])
- oldResult = result;
- }
- if (result === null && oldResult!=-1) {
- wx.showLoading({
- title: "音频切换中…",
- mask: true,
- });
- changeTO && clearTimeout(changeTO)
- changeTO = setTimeout(() => {
- wx.hideLoading({fail(){}})
- }, 4000);
- this.stopAndDestroyAudio()
- }
- let temp = DISTRIBUTION.find((item) => {
- return item.position.some((sub) => sub == result);
- });
- this.setData({
- classfiy,
- targetObj: temp || {},
- result
- });
- });
- })
- .catch(() => {
- wx.showToast({
- title: "连接失败",
- icon: "error",
- duration: 500,
- });
- });
- });
- },
- stopAndDestroyAudio() {
- console.log(innerAudioContext,'innerAudioContext');
- if (!innerAudioContext) {
- return
- }
-
- innerAudioContext.pause()
- innerAudioContext.stop();
- innerAudioContext.src = null
- innerAudioContext.destroy();
- innerAudioContext = null
- oldResult = -1
- },
- playAudio(src) {
- if (!innerAudioContext) {
- innerAudioContext = wx.createInnerAudioContext({
- useWebAudioImplement: true
- })
- }
- innerAudioContext.src = src;
- innerAudioContext.loop = true;
- innerAudioContext.onCanplay(()=>{
- innerAudioContext.play();
- })
- // innerAudioContext.play();
- },
- stopBeaconDiscovery(notips=null) {
- console.log("这是取消连接");
- // 取消连接 停止播放音乐 目标对象置为{} 设置为第一次进入
-
- this.stopAndDestroyAudio();
- this.reset();
- isCollect = false
- stopBeaconDiscovery().then(() => {
- !notips && wx.showToast({
- title: "取消连接成功",
- icon: "error",
- duration: 1000,
- });
-
- })
- .catch((err) => {
- console.log(err);
- });
- },
- reset(){
- this.setData({
- status: "0",
- targetObj: {},
- });
- },
- // 扫一扫
- toScanCode() {
- this.setData({
- isScanPlay: true,
- });
- wx.scanCode({
- success: res=> {
- this.stopBeaconDiscovery(true)
- this.playAudio(res["result"])
- },
- fail: ()=> {
- console.log("fail innerAudioContext", innerAudioContext);
- this.setData({
- isScanPlay: false,
- });
- return;
- },
- complete() {
- this.setData({
- isScanPlay: false,
- });
- },
- });
- },
- resetPage(){
- this.stopBeaconDiscovery(true);
- },
- getAudios() {
- http.get("/api/web/getAudioIndex").then((res) => {
- let { data } = res,
- target = {};
- data.forEach((item) => {
- switch (item.type) {
- case 1:
- target["10001"] = `${this.data.api_base_url}/data/${item.audio}`;
- break;
- case 2:
- target["10002"] = `${this.data.api_base_url}/data/${item.audio}`;
- break;
- case 3:
- target["10003"] = `${this.data.api_base_url}/data/${item.audio}`;
- break;
- default:
- break;
- }
- });
- this.setData({
- audio_address: target,
- });
- });
- },
- },
- lifetimes: {
- attached: function () {
- audioInterruptionCb = ()=>{
- console.log(innerAudioContext);
- if (innerAudioContext) {
- this.resetPage()
- }
- }
- bluetoothAdapterStateChangeCb=(res)=>{
- if (!Boolean(res.available)) {
- this.resetPage()
- }
- }
- wx.onAudioInterruptionEnd(audioInterruptionCb)
- wx.onBluetoothAdapterStateChange(bluetoothAdapterStateChangeCb)
- wx.onAppShow(audioInterruptionCb)
- },
- detached: function () {
- this.resetPage()
- wx.offAudioInterruptionEnd(audioInterruptionCb)
- wx.offBluetoothAdapterStateChange(bluetoothAdapterStateChangeCb)
- wx.offAppShow(audioInterruptionCb)
- }
- },
- });
|