罗广辉
2025-10-23 6d009f08368f93713c1ebeca6acde4163042faa4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<template>
  <WebViewPlus :src="`${viewUrl}`" @webMessage="onPostMessage"/>
  <up-toast ref="uNotifyRef"></up-toast>
</template>
<script setup>
import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
import WebViewPlus from "@/components/WebViewPlus.vue";
import {getEnvObj, getWebViewUrl} from "@/utils/index.js";
import Recorder from "js-audio-recorder";
import dayjs from "dayjs";
import {useUserStore} from "@/store/index.js";
 
const wayLineJodInfoId = ref(null)
const startState = ref('0')
let recorder
const soundVideoName = ref('') // 喊话名称
soundVideoName.value = `${dayjs().format('YYYYMMDDHHmmss')}实时喊话`
const droneHornState = ref('0')
const updateKey = ref(0)
const uNotifyRef = ref(null)
 
const viewUrl = computed(() => {
  return getWebViewUrl('/DroneConsole', {
    wayLineJodInfoId: wayLineJodInfoId.value,
    startState: startState.value,
    droneHornState: droneHornState.value,
    updateKey: updateKey.value
  })
})
 
function onPostMessage(data) {
  if (data.type === 'record') {
    startState.value = '1'
    recorder = new Recorder({
      sampleBits: 16, // 采样位数,支持8或16,默认16
      sampleRate: 16000, // 采样率,支持11025、16000、22050、24000、44100、48000
      numChannels: 1, // 声道,支持1或2,默认1
    })
    nextTick(() => {
      recorder.start().then(() => {
        recorder.onprocess = duration => {
        }
      })
    })
  } else if (data.type === 'stopRecord') {
    startState.value = '2'
    recorder.stop()
  } else if (data.type === 'trialListening') {
    recorder.play()
  } else if (data.type === 'resetRecording') {
    startState.value = '0'
    droneHornState.value = '0'
    recorder?.destroy().then(() => {
      recorder = null // 释放资源
    })
  } else if (data.type === 'pushToDrone') {
    pushToDrone(data)
  } else if (data.type === 'saveSound') {
    saveSound(data)
  }
}
 
const {VITE_API_BASE_URL} = getEnvObj()
 
function uploadUtil(options) {
  const {formData, file, url} = options
  return new Promise((resolve, reject) => {
    let accessToken = useUserStore()?.$state?.userInfo?.access_token;
    const file = new File([recorder.getWAVBlob()], '.wav')
    uni.uploadFile({
      url: `${VITE_API_BASE_URL}${url}`,
      name: 'file',
      header: {'Blade-Auth': 'bearer ' + accessToken},
      file,
      formData,
      success: (res) => {
        const resData = JSON.parse(res.data)
        if (resData.code === 200 || resData.code === 0) {
          resolve(res)
        } else {
          showToast(resData.message)
          reject(res)
        }
      },
      fail: (err) => {
        reject(err)
      }
    });
  })
}
 
function showToast(message) {
  uNotifyRef.value.show({
    type: 'default',
    message,
  });
}
 
 
// 保存喊话至广播列表内
function saveSound(data) {
  const file = new File([recorder.getWAVBlob()], '.wav')
  uploadUtil({
    file,
    formData: {
      fileName: data.soundName,
      sn: data.dockSn
    },
    url: '/drone-device-core/speak/api/v1/uploadSpeak'
  }).then(res => {
    showToast('保存成功')
  })
}
 
// 无人机开始喊话
function pushToDrone(data) {
  const wavBlob = recorder.getWAVBlob()
  const file = new File([wavBlob], new Date().getTime() + '.wav')
  uploadUtil({
    file,
    formData: {
      name: data.soundName,
      sn: data.dockSn,
      psdk_index: 2,
      volumn: 100,
    },
    url: '/drone-device-core/speak/api/v1/startVoice'
  }).then(res => {
    droneHornState.value = '1'
    showToast('播放成功')
  }).catch(() => {
    droneHornState.value = '0'
  }).finally(() => {
    updateKey.value += 1
  })
}
 
onLoad((options) => {
  wayLineJodInfoId.value = options.wayLineJodInfoId
})
 
 
// onShow(() => {
//   // #ifdef APP-PLUS
//   plus.screen.lockOrientation("landscape-primary");
//   // #endif
// });
//
// onHide(() => {
//   // #ifdef APP-PLUS
//   plus.screen.lockOrientation("portrait-primary");
//   // #endif
// });
</script>
<style scoped lang="scss">
 
</style>