byt-lingxiao-ai 0.3.27 → 0.3.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/AudioSubtitle.vue +29 -0
- package/components/ChatWindow.vue +362 -70
- package/components/config/blacklist.js +3 -0
- package/components/config/index.js +12 -3
- package/components/mixins/audioMixin.js +137 -80
- package/components/mixins/messageMixin.js +2 -2
- package/components/mixins/webSocketMixin.js +7 -10
- package/dist/index.common.js +544 -135
- package/dist/index.common.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.umd.js +544 -135
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/index.umd.min.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js
CHANGED
|
@@ -66369,7 +66369,7 @@ if (typeof window !== 'undefined') {
|
|
|
66369
66369
|
var es_iterator_constructor = __webpack_require__(8111);
|
|
66370
66370
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.for-each.js
|
|
66371
66371
|
var es_iterator_for_each = __webpack_require__(7588);
|
|
66372
|
-
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=template&id=
|
|
66372
|
+
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=template&id=959a9f66&scoped=true
|
|
66373
66373
|
var render = function render() {
|
|
66374
66374
|
var _vm = this,
|
|
66375
66375
|
_c = _vm._self._c;
|
|
@@ -66379,16 +66379,16 @@ var render = function render() {
|
|
|
66379
66379
|
}, [_c('audio', {
|
|
66380
66380
|
ref: "audioPlayer",
|
|
66381
66381
|
staticClass: "hidden-audio",
|
|
66382
|
+
attrs: {
|
|
66383
|
+
"src": _vm.audioSrc,
|
|
66384
|
+
"controls": "",
|
|
66385
|
+
"preload": "auto"
|
|
66386
|
+
},
|
|
66382
66387
|
on: {
|
|
66383
66388
|
"timeupdate": _vm.onTimeUpdate,
|
|
66384
66389
|
"ended": _vm.onAudioEnded
|
|
66385
66390
|
}
|
|
66386
|
-
},
|
|
66387
|
-
attrs: {
|
|
66388
|
-
"src": _vm.audioSrc,
|
|
66389
|
-
"type": "audio/mpeg"
|
|
66390
|
-
}
|
|
66391
|
-
}), _vm._v(" 您的浏览器不支持音频元素。 ")]), _vm.robotStatus !== 'leaving' ? _c('ChatRobot', {
|
|
66391
|
+
}), _vm.robotStatus !== 'leaving' ? _c('ChatRobot', {
|
|
66392
66392
|
attrs: {
|
|
66393
66393
|
"status": _vm.robotStatus
|
|
66394
66394
|
}
|
|
@@ -66397,7 +66397,9 @@ var render = function render() {
|
|
|
66397
66397
|
"status": _vm.avaterStatus
|
|
66398
66398
|
},
|
|
66399
66399
|
on: {
|
|
66400
|
-
"mousedown":
|
|
66400
|
+
"mousedown": function ($event) {
|
|
66401
|
+
return _vm.startDrag($event);
|
|
66402
|
+
}
|
|
66401
66403
|
}
|
|
66402
66404
|
}), _c('ChatWindowDialog', {
|
|
66403
66405
|
attrs: {
|
|
@@ -66422,6 +66424,11 @@ var render = function render() {
|
|
|
66422
66424
|
},
|
|
66423
66425
|
expression: "visible"
|
|
66424
66426
|
}
|
|
66427
|
+
}), _c('AudioSubtitle', {
|
|
66428
|
+
ref: "audioSubtitle",
|
|
66429
|
+
attrs: {
|
|
66430
|
+
"current-subtitle": _vm.currentSubtitle
|
|
66431
|
+
}
|
|
66425
66432
|
})], 1);
|
|
66426
66433
|
};
|
|
66427
66434
|
var staticRenderFns = [];
|
|
@@ -69553,6 +69560,55 @@ var ChatWindowDialog_component = normalizeComponent(
|
|
|
69553
69560
|
)
|
|
69554
69561
|
|
|
69555
69562
|
/* harmony default export */ var ChatWindowDialog = (ChatWindowDialog_component.exports);
|
|
69563
|
+
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AudioSubtitle.vue?vue&type=template&id=a3a42172&scoped=true
|
|
69564
|
+
var AudioSubtitlevue_type_template_id_a3a42172_scoped_true_render = function render() {
|
|
69565
|
+
var _vm = this,
|
|
69566
|
+
_c = _vm._self._c;
|
|
69567
|
+
return _c('div', {
|
|
69568
|
+
staticClass: "subtitle-container"
|
|
69569
|
+
}, [_c('div', {
|
|
69570
|
+
staticClass: "subtitle-text"
|
|
69571
|
+
}, [_vm._v(_vm._s(_vm.currentSubtitle))])]);
|
|
69572
|
+
};
|
|
69573
|
+
var AudioSubtitlevue_type_template_id_a3a42172_scoped_true_staticRenderFns = [];
|
|
69574
|
+
|
|
69575
|
+
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AudioSubtitle.vue?vue&type=script&lang=js
|
|
69576
|
+
/* harmony default export */ var AudioSubtitlevue_type_script_lang_js = ({
|
|
69577
|
+
props: {
|
|
69578
|
+
currentSubtitle: {
|
|
69579
|
+
type: String,
|
|
69580
|
+
default: ''
|
|
69581
|
+
}
|
|
69582
|
+
}
|
|
69583
|
+
});
|
|
69584
|
+
;// ./components/AudioSubtitle.vue?vue&type=script&lang=js
|
|
69585
|
+
/* harmony default export */ var components_AudioSubtitlevue_type_script_lang_js = (AudioSubtitlevue_type_script_lang_js);
|
|
69586
|
+
;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-54.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-54.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-54.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AudioSubtitle.vue?vue&type=style&index=0&id=a3a42172&prod&scoped=true&lang=css
|
|
69587
|
+
// extracted by mini-css-extract-plugin
|
|
69588
|
+
|
|
69589
|
+
;// ./components/AudioSubtitle.vue?vue&type=style&index=0&id=a3a42172&prod&scoped=true&lang=css
|
|
69590
|
+
|
|
69591
|
+
;// ./components/AudioSubtitle.vue
|
|
69592
|
+
|
|
69593
|
+
|
|
69594
|
+
|
|
69595
|
+
;
|
|
69596
|
+
|
|
69597
|
+
|
|
69598
|
+
/* normalize component */
|
|
69599
|
+
|
|
69600
|
+
var AudioSubtitle_component = normalizeComponent(
|
|
69601
|
+
components_AudioSubtitlevue_type_script_lang_js,
|
|
69602
|
+
AudioSubtitlevue_type_template_id_a3a42172_scoped_true_render,
|
|
69603
|
+
AudioSubtitlevue_type_template_id_a3a42172_scoped_true_staticRenderFns,
|
|
69604
|
+
false,
|
|
69605
|
+
null,
|
|
69606
|
+
"a3a42172",
|
|
69607
|
+
null
|
|
69608
|
+
|
|
69609
|
+
)
|
|
69610
|
+
|
|
69611
|
+
/* harmony default export */ var AudioSubtitle = (AudioSubtitle_component.exports);
|
|
69556
69612
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array-buffer.detached.js
|
|
69557
69613
|
var es_array_buffer_detached = __webpack_require__(6573);
|
|
69558
69614
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array-buffer.transfer.js
|
|
@@ -69566,23 +69622,92 @@ var es_typed_array_with = __webpack_require__(9577);
|
|
|
69566
69622
|
|
|
69567
69623
|
|
|
69568
69624
|
|
|
69625
|
+
|
|
69626
|
+
|
|
69627
|
+
|
|
69628
|
+
|
|
69629
|
+
|
|
69569
69630
|
/* harmony default export */ var audioMixin = ({
|
|
69570
69631
|
data() {
|
|
69571
69632
|
return {
|
|
69633
|
+
audioContext: null,
|
|
69634
|
+
workletNode: null,
|
|
69635
|
+
mediaStreamSource: null,
|
|
69572
69636
|
isRecording: false,
|
|
69573
69637
|
isMicAvailable: false,
|
|
69574
|
-
|
|
69575
|
-
microphone: null,
|
|
69576
|
-
processor: null,
|
|
69577
|
-
audioBuffer: new Float32Array(0)
|
|
69638
|
+
audioData: new Float32Array(128)
|
|
69578
69639
|
};
|
|
69579
69640
|
},
|
|
69580
69641
|
methods: {
|
|
69642
|
+
async initAudioWorklet() {
|
|
69643
|
+
if (this.audioContext) return;
|
|
69644
|
+
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
|
69645
|
+
this.audioContext = new AudioContext({
|
|
69646
|
+
sampleRate: this.SAMPLE_RATE
|
|
69647
|
+
});
|
|
69648
|
+
const processorCode = `
|
|
69649
|
+
class RecorderProcessor extends AudioWorkletProcessor {
|
|
69650
|
+
constructor() {
|
|
69651
|
+
super();
|
|
69652
|
+
this.buffer = [];
|
|
69653
|
+
this.frameSize = ${this.FRAME_SIZE};
|
|
69654
|
+
}
|
|
69655
|
+
|
|
69656
|
+
process(inputs) {
|
|
69657
|
+
const input = inputs[0];
|
|
69658
|
+
if (!input || !input[0]) return true;
|
|
69659
|
+
|
|
69660
|
+
const channel = input[0];
|
|
69661
|
+
|
|
69662
|
+
for (let i = 0; i < channel.length; i++) {
|
|
69663
|
+
this.buffer.push(channel[i]);
|
|
69664
|
+
}
|
|
69665
|
+
|
|
69666
|
+
while (this.buffer.length >= this.frameSize) {
|
|
69667
|
+
const frame = this.buffer.splice(0, this.frameSize);
|
|
69668
|
+
|
|
69669
|
+
// PCM
|
|
69670
|
+
const pcm = this.floatTo16BitPCM(frame);
|
|
69671
|
+
this.port.postMessage({
|
|
69672
|
+
type: 'audio',
|
|
69673
|
+
payload: pcm
|
|
69674
|
+
});
|
|
69675
|
+
|
|
69676
|
+
// Visual(下采样)
|
|
69677
|
+
this.port.postMessage({
|
|
69678
|
+
type: 'visual',
|
|
69679
|
+
payload: new Float32Array(frame.slice(0, 128))
|
|
69680
|
+
});
|
|
69681
|
+
}
|
|
69682
|
+
return true;
|
|
69683
|
+
}
|
|
69684
|
+
|
|
69685
|
+
floatTo16BitPCM(float32Array) {
|
|
69686
|
+
const pcm = new Int16Array(float32Array.length);
|
|
69687
|
+
for (let i = 0; i < float32Array.length; i++) {
|
|
69688
|
+
let s = Math.max(-1, Math.min(1, float32Array[i]));
|
|
69689
|
+
pcm[i] = s < 0 ? s * 0x8000 : s * 0x7fff;
|
|
69690
|
+
}
|
|
69691
|
+
return pcm.buffer;
|
|
69692
|
+
}
|
|
69693
|
+
}
|
|
69694
|
+
|
|
69695
|
+
registerProcessor('recorder-processor', RecorderProcessor);
|
|
69696
|
+
`;
|
|
69697
|
+
const blob = new Blob([processorCode], {
|
|
69698
|
+
type: 'application/javascript'
|
|
69699
|
+
});
|
|
69700
|
+
const moduleUrl = URL.createObjectURL(blob);
|
|
69701
|
+
await this.audioContext.audioWorklet.addModule(moduleUrl);
|
|
69702
|
+
this.workletNode = new AudioWorkletNode(this.audioContext, 'recorder-processor');
|
|
69703
|
+
this.workletNode.port.onmessage = this.handleWorkletMessage;
|
|
69704
|
+
},
|
|
69581
69705
|
async initAudio() {
|
|
69582
69706
|
if (this.isRecording) return;
|
|
69583
69707
|
try {
|
|
69584
69708
|
this.isMicAvailable = true;
|
|
69585
|
-
|
|
69709
|
+
await this.initAudioWorklet();
|
|
69710
|
+
this.stream = await navigator.mediaDevices.getUserMedia({
|
|
69586
69711
|
audio: {
|
|
69587
69712
|
sampleRate: this.SAMPLE_RATE,
|
|
69588
69713
|
channelCount: 1,
|
|
@@ -69591,103 +69716,95 @@ var es_typed_array_with = __webpack_require__(9577);
|
|
|
69591
69716
|
autoGainControl: false
|
|
69592
69717
|
}
|
|
69593
69718
|
});
|
|
69594
|
-
this.
|
|
69595
|
-
|
|
69596
|
-
|
|
69597
|
-
|
|
69598
|
-
|
|
69599
|
-
this.processor.onaudioprocess = this.processAudio;
|
|
69600
|
-
this.microphone.connect(this.processor);
|
|
69601
|
-
this.processor.connect(this.audioContext.destination);
|
|
69719
|
+
this.mediaStreamSource = this.audioContext.createMediaStreamSource(this.stream);
|
|
69720
|
+
this.mediaStreamSource.connect(this.workletNode);
|
|
69721
|
+
if (this.audioContext.state === 'suspended') {
|
|
69722
|
+
await this.audioContext.resume();
|
|
69723
|
+
}
|
|
69602
69724
|
this.isRecording = true;
|
|
69603
|
-
console.log(
|
|
69604
|
-
} catch (
|
|
69605
|
-
console.error(
|
|
69725
|
+
console.log(`AudioWorklet 录音中 (${this.SAMPLE_RATE}Hz)`);
|
|
69726
|
+
} catch (e) {
|
|
69727
|
+
console.error('音频初始化失败:', e);
|
|
69606
69728
|
this.isRecording = false;
|
|
69607
69729
|
this.isMicAvailable = false;
|
|
69608
69730
|
}
|
|
69609
69731
|
},
|
|
69610
|
-
|
|
69611
|
-
|
|
69612
|
-
|
|
69613
|
-
|
|
69614
|
-
|
|
69615
|
-
|
|
69616
|
-
|
|
69617
|
-
|
|
69618
|
-
const frame = this.audioBuffer.slice(0, this.FRAME_SIZE);
|
|
69619
|
-
this.audioBuffer = this.audioBuffer.slice(this.FRAME_SIZE);
|
|
69620
|
-
const pcmData = this.floatTo16BitPCM(frame);
|
|
69621
|
-
if (this.ws && this.ws.readyState === this.ws.OPEN) {
|
|
69622
|
-
this.ws.send(pcmData);
|
|
69732
|
+
handleWorkletMessage(e) {
|
|
69733
|
+
const {
|
|
69734
|
+
type,
|
|
69735
|
+
payload
|
|
69736
|
+
} = e.data;
|
|
69737
|
+
if (type === 'audio') {
|
|
69738
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
69739
|
+
this.ws.send(payload);
|
|
69623
69740
|
}
|
|
69624
69741
|
}
|
|
69625
69742
|
},
|
|
69626
|
-
floatTo16BitPCM(input) {
|
|
69627
|
-
const output = new Int16Array(input.length);
|
|
69628
|
-
for (let i = 0; i < input.length; i++) {
|
|
69629
|
-
const s = Math.max(-1, Math.min(1, input[i]));
|
|
69630
|
-
output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
|
|
69631
|
-
}
|
|
69632
|
-
return output.buffer;
|
|
69633
|
-
},
|
|
69634
69743
|
stopRecording() {
|
|
69635
69744
|
if (!this.isRecording) return;
|
|
69636
|
-
if (this.
|
|
69637
|
-
if (this.
|
|
69638
|
-
if (this.
|
|
69745
|
+
if (this.mediaStreamSource) this.mediaStreamSource.disconnect();
|
|
69746
|
+
if (this.workletNode) this.workletNode.disconnect();
|
|
69747
|
+
if (this.stream) {
|
|
69748
|
+
this.stream.getTracks().forEach(t => t.stop());
|
|
69749
|
+
}
|
|
69639
69750
|
if (this.audioContext) {
|
|
69640
|
-
this.audioContext.close()
|
|
69641
|
-
|
|
69642
|
-
});
|
|
69751
|
+
this.audioContext.close();
|
|
69752
|
+
this.audioContext = null;
|
|
69643
69753
|
}
|
|
69644
69754
|
this.isRecording = false;
|
|
69755
|
+
console.log('录音已停止');
|
|
69756
|
+
},
|
|
69757
|
+
handleWebSocketMessage(data) {
|
|
69758
|
+
if (data.type === 'detection') {
|
|
69759
|
+
if (this.robotStatus === 'speaking') {
|
|
69760
|
+
this.robotStatus = 'waiting';
|
|
69761
|
+
}
|
|
69762
|
+
this.avaterStatus = 'normal';
|
|
69763
|
+
this.startTime = Date.now();
|
|
69764
|
+
}
|
|
69765
|
+
if (data.type === 'Collecting') {
|
|
69766
|
+
this.avaterStatus = 'thinking';
|
|
69767
|
+
}
|
|
69768
|
+
if (data.type === 'command') {
|
|
69769
|
+
if (this.startTime) {
|
|
69770
|
+
console.log(`[Latency] ${Date.now() - this.startTime}ms`);
|
|
69771
|
+
this.startTime = null;
|
|
69772
|
+
}
|
|
69773
|
+
this.analyzeAudioCommand(data.category);
|
|
69774
|
+
}
|
|
69645
69775
|
},
|
|
69646
69776
|
play() {
|
|
69647
|
-
this.
|
|
69648
|
-
this.$refs.audioPlayer.play();
|
|
69777
|
+
this.$refs.audioPlayer?.play();
|
|
69649
69778
|
},
|
|
69650
69779
|
pause() {
|
|
69651
|
-
|
|
69652
|
-
this.robotStatus = 'waiting';
|
|
69653
|
-
this.$refs.audioPlayer.pause();
|
|
69780
|
+
this.$refs.audioPlayer?.pause();
|
|
69654
69781
|
},
|
|
69655
69782
|
stop() {
|
|
69656
|
-
|
|
69657
|
-
|
|
69658
|
-
|
|
69659
|
-
|
|
69660
|
-
},
|
|
69661
|
-
analyzeAudioCommand(command) {
|
|
69662
|
-
console.log('分析音频命令:', command);
|
|
69663
|
-
if (command === 'C5') {
|
|
69664
|
-
this.robotStatus = 'entering';
|
|
69665
|
-
setTimeout(() => {
|
|
69666
|
-
this.robotStatus = 'speaking';
|
|
69667
|
-
this.play();
|
|
69668
|
-
}, 3000);
|
|
69669
|
-
} else if (command === 'C8') {
|
|
69670
|
-
this.robotStatus = 'speaking';
|
|
69671
|
-
this.play();
|
|
69672
|
-
} else if (command === 'C7') {
|
|
69673
|
-
this.robotStatus = 'waiting';
|
|
69674
|
-
this.pause();
|
|
69675
|
-
} else if (command === 'C6') {
|
|
69676
|
-
this.robotStatus = 'leaving';
|
|
69677
|
-
this.avaterStatus = 'normal';
|
|
69678
|
-
this.stop();
|
|
69679
|
-
}
|
|
69783
|
+
const p = this.$refs.audioPlayer;
|
|
69784
|
+
if (!p) return;
|
|
69785
|
+
p.pause();
|
|
69786
|
+
p.currentTime = 0;
|
|
69680
69787
|
}
|
|
69681
69788
|
}
|
|
69682
69789
|
});
|
|
69683
69790
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/esnext.json.parse.js
|
|
69684
69791
|
var esnext_json_parse = __webpack_require__(8335);
|
|
69685
69792
|
;// ./components/config/index.js
|
|
69686
|
-
const baseUrl = window.location.host;
|
|
69793
|
+
// const baseUrl = window.location.host;
|
|
69794
|
+
|
|
69687
69795
|
const API_URL = `/lingxiao-byt/api/v1/mcp/ask`; // 对话
|
|
69688
|
-
const WS_URL = `ws://${baseUrl}/audio/ws/`;
|
|
69689
|
-
const
|
|
69796
|
+
// export const WS_URL = `ws://${baseUrl}/audio/ws/`; // 语音
|
|
69797
|
+
const WS_URL = `ws://220.189.237.146:8312/audio/ws/`; // 测试语音
|
|
69798
|
+
|
|
69799
|
+
const AUDIO_URL = '/minio/lingxiaoai/byt.mp3'; // 导览 铜梁
|
|
69800
|
+
|
|
69801
|
+
const COLLECTION = '/minio/lingxiaoai/collection.mp3';
|
|
69802
|
+
const AREA_BOARD = '/minio/lingxiaoai/area_board.mp3'; // 区域看板
|
|
69803
|
+
const ENTERPRISE_APPLICATION = '/minio/lingxiaoai/enterprise_application.mp3'; // 企业应用
|
|
69804
|
+
const REGIONAL_APPLICATION = '/minio/lingxiaoai/regional_application.mp3'; // 区域应用
|
|
69805
|
+
|
|
69690
69806
|
const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音url跳转节点
|
|
69807
|
+
const SUBTITLE_POINTS_URL = '/minio/lingxiaoai/subTitlePoints.json'; // 字幕跳转节点
|
|
69691
69808
|
;// ./components/mixins/webSocketMixin.js
|
|
69692
69809
|
|
|
69693
69810
|
|
|
@@ -69707,11 +69824,7 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音u
|
|
|
69707
69824
|
methods: {
|
|
69708
69825
|
initWebSocket() {
|
|
69709
69826
|
try {
|
|
69710
|
-
// this.ws = new WebSocket('ws://10.2.233.41:9999');
|
|
69711
|
-
// 测试
|
|
69712
|
-
// console.log('WS_URL:', WS_URL)
|
|
69713
69827
|
this.ws = new WebSocket(WS_URL);
|
|
69714
|
-
// this.ws = new WebSocket('ws://192.168.8.87/audio/ws/');
|
|
69715
69828
|
this.ws.binaryType = 'arraybuffer';
|
|
69716
69829
|
this.ws.onopen = async () => {
|
|
69717
69830
|
console.log('WebSocket 连接成功');
|
|
@@ -69781,12 +69894,15 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音u
|
|
|
69781
69894
|
console.log('状态: 处理中');
|
|
69782
69895
|
|
|
69783
69896
|
// 性能检测终点
|
|
69784
|
-
if (this.startTime) {
|
|
69785
|
-
|
|
69786
|
-
|
|
69787
|
-
|
|
69788
|
-
}
|
|
69897
|
+
// if (this.startTime) {
|
|
69898
|
+
// const latency = Date.now() - this.startTime;
|
|
69899
|
+
// console.log(`[Latency] 完整命令处理耗时: ${latency}ms`); // 记录端到端延迟
|
|
69900
|
+
// this.startTime = null;
|
|
69901
|
+
// }
|
|
69902
|
+
|
|
69789
69903
|
this.analyzeAudioCommand(data.category);
|
|
69904
|
+
} else if (data.type === 'voice') {
|
|
69905
|
+
this.analyzeVoiceCommand(data.category);
|
|
69790
69906
|
} else {
|
|
69791
69907
|
console.log('状态: 其他');
|
|
69792
69908
|
this.avaterStatus = 'normal';
|
|
@@ -70104,6 +70220,7 @@ function generateUuid() {
|
|
|
70104
70220
|
// 记录耗时
|
|
70105
70221
|
const duration = Date.now() - startTime;
|
|
70106
70222
|
if (this.currentMessage) {
|
|
70223
|
+
this.messageLoading = false;
|
|
70107
70224
|
this.currentMessage.time = (duration / 1000).toFixed(2);
|
|
70108
70225
|
}
|
|
70109
70226
|
console.log(`流处理完成,总耗时: ${duration}ms`);
|
|
@@ -70111,10 +70228,9 @@ function generateUuid() {
|
|
|
70111
70228
|
} catch (error) {
|
|
70112
70229
|
console.error('发送消息失败:', error);
|
|
70113
70230
|
if (this.currentMessage) {
|
|
70231
|
+
this.messageLoading = false;
|
|
70114
70232
|
this.currentMessage.content = '抱歉,发生了错误,请重试。';
|
|
70115
70233
|
}
|
|
70116
|
-
} finally {
|
|
70117
|
-
this.messageLoading = false;
|
|
70118
70234
|
}
|
|
70119
70235
|
},
|
|
70120
70236
|
/**
|
|
@@ -70180,6 +70296,9 @@ function generateUuid() {
|
|
|
70180
70296
|
},
|
|
70181
70297
|
beforeDestroy() {}
|
|
70182
70298
|
});
|
|
70299
|
+
;// ./components/config/blacklist.js
|
|
70300
|
+
const BLACKLIST = ['81010400' // 南方水泥
|
|
70301
|
+
];
|
|
70183
70302
|
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=script&lang=js
|
|
70184
70303
|
|
|
70185
70304
|
|
|
@@ -70199,15 +70318,30 @@ function generateUuid() {
|
|
|
70199
70318
|
|
|
70200
70319
|
|
|
70201
70320
|
|
|
70321
|
+
|
|
70202
70322
|
const SAMPLE_RATE = 16000;
|
|
70203
70323
|
const FRAME_SIZE = 512;
|
|
70204
|
-
const
|
|
70324
|
+
const ROBOT_STATUS = {
|
|
70325
|
+
ENTERING: 'entering',
|
|
70326
|
+
// 进入中
|
|
70327
|
+
SPEAKING: 'speaking',
|
|
70328
|
+
// 说话中
|
|
70329
|
+
WAITING: 'waiting',
|
|
70330
|
+
// 等待中
|
|
70331
|
+
LEAVING: 'leaving' // 离开中
|
|
70332
|
+
};
|
|
70333
|
+
const AVATAR_STATUS = {
|
|
70334
|
+
NORMAL: 'normal',
|
|
70335
|
+
// 正常
|
|
70336
|
+
THINKING: 'thinking' // 思考中
|
|
70337
|
+
};
|
|
70205
70338
|
/* harmony default export */ var ChatWindowvue_type_script_lang_js = ({
|
|
70206
70339
|
name: 'ChatWindow',
|
|
70207
70340
|
components: {
|
|
70208
70341
|
ChatRobot: ChatRobot,
|
|
70209
70342
|
ChatAvatar: ChatAvatar,
|
|
70210
|
-
ChatWindowDialog: ChatWindowDialog
|
|
70343
|
+
ChatWindowDialog: ChatWindowDialog,
|
|
70344
|
+
AudioSubtitle: AudioSubtitle
|
|
70211
70345
|
},
|
|
70212
70346
|
mixins: [audioMixin, webSocketMixin, messageMixin],
|
|
70213
70347
|
props: {
|
|
@@ -70218,32 +70352,67 @@ const startTime = null;
|
|
|
70218
70352
|
},
|
|
70219
70353
|
data() {
|
|
70220
70354
|
return {
|
|
70355
|
+
lastTimeUpdate: null,
|
|
70356
|
+
// 上次更新时间
|
|
70221
70357
|
chatId: generateUuid(),
|
|
70358
|
+
// 唯一标识当前聊天会话
|
|
70222
70359
|
audioSrc: AUDIO_URL,
|
|
70360
|
+
// 音频文件URL
|
|
70223
70361
|
inputMessage: '',
|
|
70362
|
+
// 当前输入的消息
|
|
70224
70363
|
visible: false,
|
|
70364
|
+
// 是否显示聊天窗口
|
|
70225
70365
|
messages: [],
|
|
70366
|
+
// 聊天消息数组
|
|
70226
70367
|
messageLoading: true,
|
|
70368
|
+
// 是否正在加载消息
|
|
70227
70369
|
robotStatus: 'leaving',
|
|
70370
|
+
// 机器人状态 entering: 进入中, waiting: 等待中, speaking: 说话中, leaving: 离开中
|
|
70228
70371
|
avaterStatus: 'normal',
|
|
70372
|
+
// 头像状态 normal: 正常, thinking: 思考中
|
|
70229
70373
|
currentMessage: null,
|
|
70374
|
+
// 当前正在处理的消息
|
|
70230
70375
|
thinkStatus: true,
|
|
70376
|
+
// 是否思考中
|
|
70231
70377
|
jumpedTimePoints: new Set(),
|
|
70378
|
+
// 已跳转的时间点集合
|
|
70232
70379
|
SAMPLE_RATE,
|
|
70380
|
+
// 采样率 16000Hz
|
|
70233
70381
|
FRAME_SIZE,
|
|
70234
|
-
|
|
70235
|
-
// 检查性能使用
|
|
70382
|
+
// 帧大小 512
|
|
70236
70383
|
dragThreshold: 5,
|
|
70237
70384
|
// 拖拽阈值
|
|
70238
70385
|
isDragging: false,
|
|
70386
|
+
// 是否正在拖拽
|
|
70239
70387
|
dragStartX: 0,
|
|
70388
|
+
// 拖拽开始时的X坐标
|
|
70240
70389
|
dragStartY: 0,
|
|
70390
|
+
// 拖拽开始时的Y坐标
|
|
70241
70391
|
currentX: 10,
|
|
70392
|
+
// 当前X坐标
|
|
70242
70393
|
currentY: 20,
|
|
70394
|
+
// 当前Y坐标
|
|
70243
70395
|
initialX: 10,
|
|
70396
|
+
// 初始X坐标
|
|
70244
70397
|
initialY: 20,
|
|
70398
|
+
// 初始Y坐标
|
|
70245
70399
|
hasMoved: false,
|
|
70246
|
-
|
|
70400
|
+
// 是否已移动
|
|
70401
|
+
timeJumpPoints: null,
|
|
70402
|
+
// 跳转
|
|
70403
|
+
subTitlePoints: null,
|
|
70404
|
+
// 字幕
|
|
70405
|
+
currentJumpPoints: [],
|
|
70406
|
+
// 当前跳转点数组
|
|
70407
|
+
currentSubtitles: [],
|
|
70408
|
+
// 当前字幕数组
|
|
70409
|
+
currentSubtitle: '',
|
|
70410
|
+
// 当前字幕,
|
|
70411
|
+
jumpIndex: 0,
|
|
70412
|
+
// 当前跳转索引
|
|
70413
|
+
subtitleIndex: 0,
|
|
70414
|
+
// 当前字幕索引
|
|
70415
|
+
isTourRunning: false // 是否正在导览
|
|
70247
70416
|
};
|
|
70248
70417
|
},
|
|
70249
70418
|
computed: {
|
|
@@ -70261,12 +70430,12 @@ const startTime = null;
|
|
|
70261
70430
|
};
|
|
70262
70431
|
}
|
|
70263
70432
|
},
|
|
70264
|
-
mounted() {
|
|
70433
|
+
async mounted() {
|
|
70265
70434
|
this.initWebSocket();
|
|
70266
70435
|
if (this.appendToBody) {
|
|
70267
70436
|
this.appendToBodyHandler();
|
|
70268
70437
|
}
|
|
70269
|
-
this.fetchTimeJumpPoints();
|
|
70438
|
+
await Promise.all([this.fetchTimeJumpPoints(), this.fetchSubTitlePoints()]);
|
|
70270
70439
|
this.$nextTick(() => {
|
|
70271
70440
|
const chatEl = this.$el;
|
|
70272
70441
|
const style = window.getComputedStyle(chatEl);
|
|
@@ -70286,16 +70455,27 @@ const startTime = null;
|
|
|
70286
70455
|
document.removeEventListener('mouseup', this.stopDrag);
|
|
70287
70456
|
},
|
|
70288
70457
|
methods: {
|
|
70458
|
+
initGuide() {
|
|
70459
|
+
this.jumpIndex = 0;
|
|
70460
|
+
this.subtitleIndex = 0;
|
|
70461
|
+
this.jumpedTimePoints.clear();
|
|
70462
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70463
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70464
|
+
},
|
|
70465
|
+
setRobotStatus(status) {
|
|
70466
|
+
this.robotStatus = status || ROBOT_STATUS.LEAVING;
|
|
70467
|
+
},
|
|
70468
|
+
setAvatarStatus(status) {
|
|
70469
|
+
this.avaterStatus = status || AVATAR_STATUS.NORMAL;
|
|
70470
|
+
},
|
|
70289
70471
|
toggleWindow() {
|
|
70290
|
-
if (this.avaterStatus === 'thinking') return;
|
|
70291
70472
|
this.visible = !this.visible;
|
|
70292
70473
|
if (this.visible) {
|
|
70293
70474
|
this.currentX = this.initialX;
|
|
70294
70475
|
this.currentY = this.initialY;
|
|
70295
70476
|
}
|
|
70296
70477
|
},
|
|
70297
|
-
startDrag() {
|
|
70298
|
-
console.log('startDrag');
|
|
70478
|
+
startDrag(event) {
|
|
70299
70479
|
if (this.robotStatus !== 'leaving' && this.visible) return;
|
|
70300
70480
|
this.isDragging = true;
|
|
70301
70481
|
this.hasMoved = false;
|
|
@@ -70347,9 +70527,18 @@ const startTime = null;
|
|
|
70347
70527
|
document.removeEventListener('mousemove', this.onDrag);
|
|
70348
70528
|
document.removeEventListener('mouseup', this.stopDrag);
|
|
70349
70529
|
if (!this.hasMoved) {
|
|
70350
|
-
this.
|
|
70530
|
+
this.handleClick();
|
|
70351
70531
|
}
|
|
70352
70532
|
},
|
|
70533
|
+
handleClick() {
|
|
70534
|
+
if (this.avaterStatus === 'thinking') return;
|
|
70535
|
+
if (this.isInBlacklist()) return;
|
|
70536
|
+
this.toggleWindow();
|
|
70537
|
+
},
|
|
70538
|
+
isInBlacklist() {
|
|
70539
|
+
const tenantId = getCookie('bonyear-tenantId');
|
|
70540
|
+
return tenantId && BLACKLIST.includes(tenantId);
|
|
70541
|
+
},
|
|
70353
70542
|
handleThinkingClick() {
|
|
70354
70543
|
this.thinkStatus = !this.thinkStatus;
|
|
70355
70544
|
},
|
|
@@ -70365,54 +70554,274 @@ const startTime = null;
|
|
|
70365
70554
|
},
|
|
70366
70555
|
async fetchTimeJumpPoints() {
|
|
70367
70556
|
try {
|
|
70368
|
-
const res = await fetch(TIME_JUMP_POINTS_URL);
|
|
70557
|
+
const res = await fetch(TIME_JUMP_POINTS_URL + '?timestamp=' + Date.now());
|
|
70369
70558
|
const data = await res.json();
|
|
70370
|
-
this.timeJumpPoints =
|
|
70371
|
-
console.log('时间跳转点加载完成:', this.timeJumpPoints);
|
|
70559
|
+
this.timeJumpPoints = data;
|
|
70372
70560
|
} catch (err) {
|
|
70373
70561
|
console.error('获取时间跳转点失败:', err);
|
|
70374
|
-
this.timeJumpPoints =
|
|
70562
|
+
this.timeJumpPoints = null;
|
|
70563
|
+
}
|
|
70564
|
+
},
|
|
70565
|
+
async fetchSubTitlePoints() {
|
|
70566
|
+
try {
|
|
70567
|
+
const res = await fetch(SUBTITLE_POINTS_URL + '?timestamp=' + Date.now());
|
|
70568
|
+
const data = await res.json();
|
|
70569
|
+
this.subTitlePoints = data;
|
|
70570
|
+
} catch (err) {
|
|
70571
|
+
console.error('获取字幕跳转点失败');
|
|
70572
|
+
this.subTitlePoints = null;
|
|
70573
|
+
}
|
|
70574
|
+
},
|
|
70575
|
+
normalizeCommand(cmd = '') {
|
|
70576
|
+
return cmd.trim() // 去掉 \n \r 空格
|
|
70577
|
+
.replace(/[\u200B-\u200D]/g, '') // 去零宽字符
|
|
70578
|
+
.replace(/[。!?,、,.!?]/g, ''); // 去标点
|
|
70579
|
+
},
|
|
70580
|
+
// 分析音频语音指令
|
|
70581
|
+
analyzeVoiceCommand(name) {
|
|
70582
|
+
console.log('===== analyzeVoiceCommand =====');
|
|
70583
|
+
console.log('typeof name:', typeof name);
|
|
70584
|
+
console.log('name === "结束导览":', name === '结束导览');
|
|
70585
|
+
console.log('Object.prototype.toString:', Object.prototype.toString.call(name));
|
|
70586
|
+
const normalized = this.normalizeCommand(name);
|
|
70587
|
+
const commandMap = {
|
|
70588
|
+
'开始导览': this.startTheTour,
|
|
70589
|
+
'开始区域看板导览': this.startAreaBoardTour,
|
|
70590
|
+
'开始企业应用导览': this.startEnterpriseApplicationTour,
|
|
70591
|
+
'开始区域应用导览': this.startRegionalApplicationTour,
|
|
70592
|
+
'暂停导览': this.pauseTheTour,
|
|
70593
|
+
'继续导览': this.resumeTheTour,
|
|
70594
|
+
'结束导览': this.offTheTour,
|
|
70595
|
+
'返回首页': this.returnToHome,
|
|
70596
|
+
'未知指令': this.offTheTour
|
|
70597
|
+
};
|
|
70598
|
+
const handler = commandMap[normalized];
|
|
70599
|
+
if (!handler) {
|
|
70600
|
+
console.warn('未定义的指令:', name);
|
|
70601
|
+
return;
|
|
70602
|
+
}
|
|
70603
|
+
handler();
|
|
70604
|
+
},
|
|
70605
|
+
// 启动导览
|
|
70606
|
+
async onTheTour() {
|
|
70607
|
+
if (this.isTourRunning) return;
|
|
70608
|
+
this.isTourRunning = true;
|
|
70609
|
+
const audio = this.$refs.audioPlayer;
|
|
70610
|
+
if (!audio) return;
|
|
70611
|
+
this.setRobotStatus(ROBOT_STATUS.ENTERING);
|
|
70612
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
70613
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70614
|
+
try {
|
|
70615
|
+
await audio.play();
|
|
70616
|
+
} catch (e) {
|
|
70617
|
+
console.error('播放音频失败:', e);
|
|
70618
|
+
} finally {
|
|
70619
|
+
this.isTourRunning = false;
|
|
70620
|
+
}
|
|
70621
|
+
},
|
|
70622
|
+
// 暂停导览
|
|
70623
|
+
pauseTheTour() {
|
|
70624
|
+
this.pause();
|
|
70625
|
+
this.setRobotStatus(ROBOT_STATUS.WAITING);
|
|
70626
|
+
},
|
|
70627
|
+
// 继续导览
|
|
70628
|
+
resumeTheTour() {
|
|
70629
|
+
this.play();
|
|
70630
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70631
|
+
},
|
|
70632
|
+
// 结束导览
|
|
70633
|
+
offTheTour() {
|
|
70634
|
+
this.stop();
|
|
70635
|
+
this.currentSubtitle = '';
|
|
70636
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70637
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70638
|
+
},
|
|
70639
|
+
// 返回首页
|
|
70640
|
+
returnToHome() {
|
|
70641
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70642
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70643
|
+
this.$appOptions.router.push({
|
|
70644
|
+
path: '/'
|
|
70645
|
+
});
|
|
70646
|
+
},
|
|
70647
|
+
initJumpPoints(name) {
|
|
70648
|
+
// 初始化跳转点
|
|
70649
|
+
if (name) {
|
|
70650
|
+
this.currentJumpPoints = this.timeJumpPoints[name] || [];
|
|
70651
|
+
console.log('currentJumpPoints:', this.currentJumpPoints);
|
|
70652
|
+
} else {
|
|
70653
|
+
this.currentJumpPoints = this.timeJumpPoints;
|
|
70654
|
+
}
|
|
70655
|
+
},
|
|
70656
|
+
initSubtitles(name) {
|
|
70657
|
+
console.log('name:', name);
|
|
70658
|
+
if (name) {
|
|
70659
|
+
this.currentSubtitles = this.subTitlePoints[name] || [];
|
|
70660
|
+
} else {
|
|
70661
|
+
this.currentSubtitles = this.subTitlePoints;
|
|
70662
|
+
}
|
|
70663
|
+
},
|
|
70664
|
+
// 开始导览
|
|
70665
|
+
async startTheTour() {
|
|
70666
|
+
await this.setAudio(COLLECTION); // 重置音频源
|
|
70667
|
+
|
|
70668
|
+
// 重置指针
|
|
70669
|
+
this.initGuide();
|
|
70670
|
+
// 重置跳转点指针
|
|
70671
|
+
this.initJumpPoints('开始导览');
|
|
70672
|
+
// 重置字幕指针
|
|
70673
|
+
this.initSubtitles('开始导览');
|
|
70674
|
+
await this.onTheTour();
|
|
70675
|
+
},
|
|
70676
|
+
// 开始区域看板导览
|
|
70677
|
+
async startAreaBoardTour() {
|
|
70678
|
+
// 重置audio
|
|
70679
|
+
await this.setAudio(AREA_BOARD);
|
|
70680
|
+
|
|
70681
|
+
// 重置指针
|
|
70682
|
+
this.initGuide();
|
|
70683
|
+
// 重置跳转点指针
|
|
70684
|
+
this.initJumpPoints('开始区域看板导览');
|
|
70685
|
+
// 重置字幕指针
|
|
70686
|
+
this.initSubtitles('开始区域看板导览');
|
|
70687
|
+
await this.onTheTour();
|
|
70688
|
+
},
|
|
70689
|
+
// 开始企业应用导览
|
|
70690
|
+
async startEnterpriseApplicationTour() {
|
|
70691
|
+
await this.setAudio(ENTERPRISE_APPLICATION);
|
|
70692
|
+
|
|
70693
|
+
// 重置指针
|
|
70694
|
+
this.initGuide();
|
|
70695
|
+
// 重置跳转点指针
|
|
70696
|
+
this.initJumpPoints('开始企业应用导览');
|
|
70697
|
+
// 重置字幕指针
|
|
70698
|
+
this.initSubtitles('开始企业应用导览');
|
|
70699
|
+
await this.onTheTour();
|
|
70700
|
+
},
|
|
70701
|
+
// 开始区域应用导览
|
|
70702
|
+
async startRegionalApplicationTour() {
|
|
70703
|
+
await this.setAudio(REGIONAL_APPLICATION);
|
|
70704
|
+
|
|
70705
|
+
// 重置指针
|
|
70706
|
+
this.initGuide();
|
|
70707
|
+
// 重置跳转点指针
|
|
70708
|
+
this.initJumpPoints('开始区域应用导览');
|
|
70709
|
+
// 重置字幕指针
|
|
70710
|
+
this.initSubtitles('开始区域应用导览');
|
|
70711
|
+
await this.onTheTour();
|
|
70712
|
+
},
|
|
70713
|
+
// 分析音频命令
|
|
70714
|
+
analyzeAudioCommand(command) {
|
|
70715
|
+
console.log('分析音频命令:', command);
|
|
70716
|
+
if (command === 'C5') {
|
|
70717
|
+
this.setRobotStatus(ROBOT_STATUS.ENTERING);
|
|
70718
|
+
setTimeout(() => {
|
|
70719
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70720
|
+
this.play();
|
|
70721
|
+
}, 3000);
|
|
70722
|
+
}
|
|
70723
|
+
if (command === 'C8') {
|
|
70724
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70725
|
+
this.play();
|
|
70726
|
+
}
|
|
70727
|
+
if (command === 'C7') {
|
|
70728
|
+
this.setRobotStatus(ROBOT_STATUS.WAITING);
|
|
70729
|
+
this.pause();
|
|
70730
|
+
}
|
|
70731
|
+
if (command === 'C6') {
|
|
70732
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70733
|
+
this.stop();
|
|
70375
70734
|
}
|
|
70376
70735
|
},
|
|
70736
|
+
// 处理点击跳转时间
|
|
70737
|
+
handleJumpPoint(currentTime) {
|
|
70738
|
+
console.log('jumpIndex:', this.jumpIndex);
|
|
70739
|
+
const point = this.currentJumpPoints[this.jumpIndex];
|
|
70740
|
+
if (!point) return;
|
|
70741
|
+
console.log('currentTime:', currentTime);
|
|
70742
|
+
console.log('point.time:', point.time);
|
|
70743
|
+
if (currentTime >= point.time && !this.jumpedTimePoints.has(point.time)) {
|
|
70744
|
+
this.jumpedTimePoints.add(point.time);
|
|
70745
|
+
this.jumpIndex++;
|
|
70746
|
+
this.$appOptions.store.dispatch('tags/addTagview', {
|
|
70747
|
+
path: point.url,
|
|
70748
|
+
fullPath: point.url,
|
|
70749
|
+
label: point.title,
|
|
70750
|
+
name: point.title,
|
|
70751
|
+
meta: {
|
|
70752
|
+
title: point.title
|
|
70753
|
+
},
|
|
70754
|
+
query: {},
|
|
70755
|
+
params: {}
|
|
70756
|
+
});
|
|
70757
|
+
this.$appOptions.router.push({
|
|
70758
|
+
path: point.url
|
|
70759
|
+
});
|
|
70760
|
+
}
|
|
70761
|
+
},
|
|
70762
|
+
// 处理播放字幕
|
|
70763
|
+
handlePlaySubtitles(currentTime) {
|
|
70764
|
+
const subtitle = this.currentSubtitles[this.subtitleIndex];
|
|
70765
|
+
if (!subtitle) return;
|
|
70766
|
+
if (currentTime < subtitle.start) return;
|
|
70767
|
+
|
|
70768
|
+
// 正在播放当前字幕
|
|
70769
|
+
if (currentTime >= subtitle.start && currentTime <= subtitle.end) {
|
|
70770
|
+
if (this.currentSubtitle !== subtitle.text) {
|
|
70771
|
+
this.currentSubtitle = subtitle.text;
|
|
70772
|
+
}
|
|
70773
|
+
return;
|
|
70774
|
+
}
|
|
70775
|
+
|
|
70776
|
+
// 超过当前字幕,推进游标
|
|
70777
|
+
if (currentTime > subtitle.end) {
|
|
70778
|
+
this.subtitleIndex++;
|
|
70779
|
+
this.currentSubtitle = '';
|
|
70780
|
+
}
|
|
70781
|
+
},
|
|
70782
|
+
async setAudio(src) {
|
|
70783
|
+
return new Promise((resolve, reject) => {
|
|
70784
|
+
const audio = this.$refs.audioPlayer;
|
|
70785
|
+
if (!audio) return reject('未找到音频元素');
|
|
70786
|
+
audio.pause();
|
|
70787
|
+
audio.currentTime = 0;
|
|
70788
|
+
|
|
70789
|
+
// ✅ 用响应式数据
|
|
70790
|
+
this.audioSrc = src;
|
|
70791
|
+
this.$nextTick(() => {
|
|
70792
|
+
audio.load();
|
|
70793
|
+
const onCanPlay = () => {
|
|
70794
|
+
audio.removeEventListener('canplay', onCanPlay);
|
|
70795
|
+
resolve();
|
|
70796
|
+
};
|
|
70797
|
+
audio.addEventListener('canplay', onCanPlay);
|
|
70798
|
+
});
|
|
70799
|
+
});
|
|
70800
|
+
},
|
|
70377
70801
|
// 音频时间更新处理
|
|
70378
70802
|
onTimeUpdate() {
|
|
70803
|
+
const now = performance.now();
|
|
70804
|
+
if (this.lastTimeUpdate && now - this.lastTimeUpdate < 200) return;
|
|
70805
|
+
this.lastTimeUpdate = now;
|
|
70379
70806
|
const audio = this.$refs.audioPlayer;
|
|
70380
70807
|
const currentTime = audio.currentTime;
|
|
70381
|
-
|
|
70382
|
-
this.
|
|
70383
|
-
if (currentTime >= point.time && currentTime < point.time + 1 && !this.jumpedTimePoints.has(point.time)) {
|
|
70384
|
-
console.log('触发跳转:', point.url);
|
|
70385
|
-
this.jumpedTimePoints.add(point.time);
|
|
70386
|
-
this.$appOptions.store.dispatch('tags/addTagview', {
|
|
70387
|
-
path: point.url,
|
|
70388
|
-
fullPath: point.url,
|
|
70389
|
-
label: point.title,
|
|
70390
|
-
name: point.title,
|
|
70391
|
-
meta: {
|
|
70392
|
-
title: point.title
|
|
70393
|
-
},
|
|
70394
|
-
query: {},
|
|
70395
|
-
params: {}
|
|
70396
|
-
});
|
|
70397
|
-
this.$appOptions.router.push({
|
|
70398
|
-
path: point.url
|
|
70399
|
-
});
|
|
70400
|
-
}
|
|
70401
|
-
});
|
|
70808
|
+
this.handleJumpPoint(currentTime);
|
|
70809
|
+
this.handlePlaySubtitles(currentTime);
|
|
70402
70810
|
},
|
|
70403
70811
|
onAudioEnded() {
|
|
70404
|
-
this.
|
|
70405
|
-
this.
|
|
70812
|
+
this.currentSubtitle = '';
|
|
70813
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70814
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70406
70815
|
this.jumpedTimePoints.clear();
|
|
70407
70816
|
}
|
|
70408
70817
|
}
|
|
70409
70818
|
});
|
|
70410
70819
|
;// ./components/ChatWindow.vue?vue&type=script&lang=js
|
|
70411
70820
|
/* harmony default export */ var components_ChatWindowvue_type_script_lang_js = (ChatWindowvue_type_script_lang_js);
|
|
70412
|
-
;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-54.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-54.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-54.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=style&index=0&id=
|
|
70821
|
+
;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-54.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-54.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-54.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=style&index=0&id=959a9f66&prod&scoped=true&lang=css
|
|
70413
70822
|
// extracted by mini-css-extract-plugin
|
|
70414
70823
|
|
|
70415
|
-
;// ./components/ChatWindow.vue?vue&type=style&index=0&id=
|
|
70824
|
+
;// ./components/ChatWindow.vue?vue&type=style&index=0&id=959a9f66&prod&scoped=true&lang=css
|
|
70416
70825
|
|
|
70417
70826
|
;// ./components/ChatWindow.vue
|
|
70418
70827
|
|
|
@@ -70429,7 +70838,7 @@ var ChatWindow_component = normalizeComponent(
|
|
|
70429
70838
|
staticRenderFns,
|
|
70430
70839
|
false,
|
|
70431
70840
|
null,
|
|
70432
|
-
"
|
|
70841
|
+
"959a9f66",
|
|
70433
70842
|
null
|
|
70434
70843
|
|
|
70435
70844
|
)
|