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.common.js
CHANGED
|
@@ -66359,7 +66359,7 @@ if (typeof window !== 'undefined') {
|
|
|
66359
66359
|
var es_iterator_constructor = __webpack_require__(8111);
|
|
66360
66360
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.for-each.js
|
|
66361
66361
|
var es_iterator_for_each = __webpack_require__(7588);
|
|
66362
|
-
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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=
|
|
66362
|
+
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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
|
|
66363
66363
|
var render = function render() {
|
|
66364
66364
|
var _vm = this,
|
|
66365
66365
|
_c = _vm._self._c;
|
|
@@ -66369,16 +66369,16 @@ var render = function render() {
|
|
|
66369
66369
|
}, [_c('audio', {
|
|
66370
66370
|
ref: "audioPlayer",
|
|
66371
66371
|
staticClass: "hidden-audio",
|
|
66372
|
+
attrs: {
|
|
66373
|
+
"src": _vm.audioSrc,
|
|
66374
|
+
"controls": "",
|
|
66375
|
+
"preload": "auto"
|
|
66376
|
+
},
|
|
66372
66377
|
on: {
|
|
66373
66378
|
"timeupdate": _vm.onTimeUpdate,
|
|
66374
66379
|
"ended": _vm.onAudioEnded
|
|
66375
66380
|
}
|
|
66376
|
-
},
|
|
66377
|
-
attrs: {
|
|
66378
|
-
"src": _vm.audioSrc,
|
|
66379
|
-
"type": "audio/mpeg"
|
|
66380
|
-
}
|
|
66381
|
-
}), _vm._v(" 您的浏览器不支持音频元素。 ")]), _vm.robotStatus !== 'leaving' ? _c('ChatRobot', {
|
|
66381
|
+
}), _vm.robotStatus !== 'leaving' ? _c('ChatRobot', {
|
|
66382
66382
|
attrs: {
|
|
66383
66383
|
"status": _vm.robotStatus
|
|
66384
66384
|
}
|
|
@@ -66387,7 +66387,9 @@ var render = function render() {
|
|
|
66387
66387
|
"status": _vm.avaterStatus
|
|
66388
66388
|
},
|
|
66389
66389
|
on: {
|
|
66390
|
-
"mousedown":
|
|
66390
|
+
"mousedown": function ($event) {
|
|
66391
|
+
return _vm.startDrag($event);
|
|
66392
|
+
}
|
|
66391
66393
|
}
|
|
66392
66394
|
}), _c('ChatWindowDialog', {
|
|
66393
66395
|
attrs: {
|
|
@@ -66412,6 +66414,11 @@ var render = function render() {
|
|
|
66412
66414
|
},
|
|
66413
66415
|
expression: "visible"
|
|
66414
66416
|
}
|
|
66417
|
+
}), _c('AudioSubtitle', {
|
|
66418
|
+
ref: "audioSubtitle",
|
|
66419
|
+
attrs: {
|
|
66420
|
+
"current-subtitle": _vm.currentSubtitle
|
|
66421
|
+
}
|
|
66415
66422
|
})], 1);
|
|
66416
66423
|
};
|
|
66417
66424
|
var staticRenderFns = [];
|
|
@@ -69543,6 +69550,55 @@ var ChatWindowDialog_component = normalizeComponent(
|
|
|
69543
69550
|
)
|
|
69544
69551
|
|
|
69545
69552
|
/* harmony default export */ var ChatWindowDialog = (ChatWindowDialog_component.exports);
|
|
69553
|
+
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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
|
|
69554
|
+
var AudioSubtitlevue_type_template_id_a3a42172_scoped_true_render = function render() {
|
|
69555
|
+
var _vm = this,
|
|
69556
|
+
_c = _vm._self._c;
|
|
69557
|
+
return _c('div', {
|
|
69558
|
+
staticClass: "subtitle-container"
|
|
69559
|
+
}, [_c('div', {
|
|
69560
|
+
staticClass: "subtitle-text"
|
|
69561
|
+
}, [_vm._v(_vm._s(_vm.currentSubtitle))])]);
|
|
69562
|
+
};
|
|
69563
|
+
var AudioSubtitlevue_type_template_id_a3a42172_scoped_true_staticRenderFns = [];
|
|
69564
|
+
|
|
69565
|
+
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AudioSubtitle.vue?vue&type=script&lang=js
|
|
69566
|
+
/* harmony default export */ var AudioSubtitlevue_type_script_lang_js = ({
|
|
69567
|
+
props: {
|
|
69568
|
+
currentSubtitle: {
|
|
69569
|
+
type: String,
|
|
69570
|
+
default: ''
|
|
69571
|
+
}
|
|
69572
|
+
}
|
|
69573
|
+
});
|
|
69574
|
+
;// ./components/AudioSubtitle.vue?vue&type=script&lang=js
|
|
69575
|
+
/* harmony default export */ var components_AudioSubtitlevue_type_script_lang_js = (AudioSubtitlevue_type_script_lang_js);
|
|
69576
|
+
;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.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
|
|
69577
|
+
// extracted by mini-css-extract-plugin
|
|
69578
|
+
|
|
69579
|
+
;// ./components/AudioSubtitle.vue?vue&type=style&index=0&id=a3a42172&prod&scoped=true&lang=css
|
|
69580
|
+
|
|
69581
|
+
;// ./components/AudioSubtitle.vue
|
|
69582
|
+
|
|
69583
|
+
|
|
69584
|
+
|
|
69585
|
+
;
|
|
69586
|
+
|
|
69587
|
+
|
|
69588
|
+
/* normalize component */
|
|
69589
|
+
|
|
69590
|
+
var AudioSubtitle_component = normalizeComponent(
|
|
69591
|
+
components_AudioSubtitlevue_type_script_lang_js,
|
|
69592
|
+
AudioSubtitlevue_type_template_id_a3a42172_scoped_true_render,
|
|
69593
|
+
AudioSubtitlevue_type_template_id_a3a42172_scoped_true_staticRenderFns,
|
|
69594
|
+
false,
|
|
69595
|
+
null,
|
|
69596
|
+
"a3a42172",
|
|
69597
|
+
null
|
|
69598
|
+
|
|
69599
|
+
)
|
|
69600
|
+
|
|
69601
|
+
/* harmony default export */ var AudioSubtitle = (AudioSubtitle_component.exports);
|
|
69546
69602
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array-buffer.detached.js
|
|
69547
69603
|
var es_array_buffer_detached = __webpack_require__(6573);
|
|
69548
69604
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array-buffer.transfer.js
|
|
@@ -69556,23 +69612,92 @@ var es_typed_array_with = __webpack_require__(9577);
|
|
|
69556
69612
|
|
|
69557
69613
|
|
|
69558
69614
|
|
|
69615
|
+
|
|
69616
|
+
|
|
69617
|
+
|
|
69618
|
+
|
|
69619
|
+
|
|
69559
69620
|
/* harmony default export */ var audioMixin = ({
|
|
69560
69621
|
data() {
|
|
69561
69622
|
return {
|
|
69623
|
+
audioContext: null,
|
|
69624
|
+
workletNode: null,
|
|
69625
|
+
mediaStreamSource: null,
|
|
69562
69626
|
isRecording: false,
|
|
69563
69627
|
isMicAvailable: false,
|
|
69564
|
-
|
|
69565
|
-
microphone: null,
|
|
69566
|
-
processor: null,
|
|
69567
|
-
audioBuffer: new Float32Array(0)
|
|
69628
|
+
audioData: new Float32Array(128)
|
|
69568
69629
|
};
|
|
69569
69630
|
},
|
|
69570
69631
|
methods: {
|
|
69632
|
+
async initAudioWorklet() {
|
|
69633
|
+
if (this.audioContext) return;
|
|
69634
|
+
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
|
69635
|
+
this.audioContext = new AudioContext({
|
|
69636
|
+
sampleRate: this.SAMPLE_RATE
|
|
69637
|
+
});
|
|
69638
|
+
const processorCode = `
|
|
69639
|
+
class RecorderProcessor extends AudioWorkletProcessor {
|
|
69640
|
+
constructor() {
|
|
69641
|
+
super();
|
|
69642
|
+
this.buffer = [];
|
|
69643
|
+
this.frameSize = ${this.FRAME_SIZE};
|
|
69644
|
+
}
|
|
69645
|
+
|
|
69646
|
+
process(inputs) {
|
|
69647
|
+
const input = inputs[0];
|
|
69648
|
+
if (!input || !input[0]) return true;
|
|
69649
|
+
|
|
69650
|
+
const channel = input[0];
|
|
69651
|
+
|
|
69652
|
+
for (let i = 0; i < channel.length; i++) {
|
|
69653
|
+
this.buffer.push(channel[i]);
|
|
69654
|
+
}
|
|
69655
|
+
|
|
69656
|
+
while (this.buffer.length >= this.frameSize) {
|
|
69657
|
+
const frame = this.buffer.splice(0, this.frameSize);
|
|
69658
|
+
|
|
69659
|
+
// PCM
|
|
69660
|
+
const pcm = this.floatTo16BitPCM(frame);
|
|
69661
|
+
this.port.postMessage({
|
|
69662
|
+
type: 'audio',
|
|
69663
|
+
payload: pcm
|
|
69664
|
+
});
|
|
69665
|
+
|
|
69666
|
+
// Visual(下采样)
|
|
69667
|
+
this.port.postMessage({
|
|
69668
|
+
type: 'visual',
|
|
69669
|
+
payload: new Float32Array(frame.slice(0, 128))
|
|
69670
|
+
});
|
|
69671
|
+
}
|
|
69672
|
+
return true;
|
|
69673
|
+
}
|
|
69674
|
+
|
|
69675
|
+
floatTo16BitPCM(float32Array) {
|
|
69676
|
+
const pcm = new Int16Array(float32Array.length);
|
|
69677
|
+
for (let i = 0; i < float32Array.length; i++) {
|
|
69678
|
+
let s = Math.max(-1, Math.min(1, float32Array[i]));
|
|
69679
|
+
pcm[i] = s < 0 ? s * 0x8000 : s * 0x7fff;
|
|
69680
|
+
}
|
|
69681
|
+
return pcm.buffer;
|
|
69682
|
+
}
|
|
69683
|
+
}
|
|
69684
|
+
|
|
69685
|
+
registerProcessor('recorder-processor', RecorderProcessor);
|
|
69686
|
+
`;
|
|
69687
|
+
const blob = new Blob([processorCode], {
|
|
69688
|
+
type: 'application/javascript'
|
|
69689
|
+
});
|
|
69690
|
+
const moduleUrl = URL.createObjectURL(blob);
|
|
69691
|
+
await this.audioContext.audioWorklet.addModule(moduleUrl);
|
|
69692
|
+
this.workletNode = new AudioWorkletNode(this.audioContext, 'recorder-processor');
|
|
69693
|
+
this.workletNode.port.onmessage = this.handleWorkletMessage;
|
|
69694
|
+
},
|
|
69571
69695
|
async initAudio() {
|
|
69572
69696
|
if (this.isRecording) return;
|
|
69573
69697
|
try {
|
|
69574
69698
|
this.isMicAvailable = true;
|
|
69575
|
-
|
|
69699
|
+
await this.initAudioWorklet();
|
|
69700
|
+
this.stream = await navigator.mediaDevices.getUserMedia({
|
|
69576
69701
|
audio: {
|
|
69577
69702
|
sampleRate: this.SAMPLE_RATE,
|
|
69578
69703
|
channelCount: 1,
|
|
@@ -69581,103 +69706,95 @@ var es_typed_array_with = __webpack_require__(9577);
|
|
|
69581
69706
|
autoGainControl: false
|
|
69582
69707
|
}
|
|
69583
69708
|
});
|
|
69584
|
-
this.
|
|
69585
|
-
|
|
69586
|
-
|
|
69587
|
-
|
|
69588
|
-
|
|
69589
|
-
this.processor.onaudioprocess = this.processAudio;
|
|
69590
|
-
this.microphone.connect(this.processor);
|
|
69591
|
-
this.processor.connect(this.audioContext.destination);
|
|
69709
|
+
this.mediaStreamSource = this.audioContext.createMediaStreamSource(this.stream);
|
|
69710
|
+
this.mediaStreamSource.connect(this.workletNode);
|
|
69711
|
+
if (this.audioContext.state === 'suspended') {
|
|
69712
|
+
await this.audioContext.resume();
|
|
69713
|
+
}
|
|
69592
69714
|
this.isRecording = true;
|
|
69593
|
-
console.log(
|
|
69594
|
-
} catch (
|
|
69595
|
-
console.error(
|
|
69715
|
+
console.log(`AudioWorklet 录音中 (${this.SAMPLE_RATE}Hz)`);
|
|
69716
|
+
} catch (e) {
|
|
69717
|
+
console.error('音频初始化失败:', e);
|
|
69596
69718
|
this.isRecording = false;
|
|
69597
69719
|
this.isMicAvailable = false;
|
|
69598
69720
|
}
|
|
69599
69721
|
},
|
|
69600
|
-
|
|
69601
|
-
|
|
69602
|
-
|
|
69603
|
-
|
|
69604
|
-
|
|
69605
|
-
|
|
69606
|
-
|
|
69607
|
-
|
|
69608
|
-
const frame = this.audioBuffer.slice(0, this.FRAME_SIZE);
|
|
69609
|
-
this.audioBuffer = this.audioBuffer.slice(this.FRAME_SIZE);
|
|
69610
|
-
const pcmData = this.floatTo16BitPCM(frame);
|
|
69611
|
-
if (this.ws && this.ws.readyState === this.ws.OPEN) {
|
|
69612
|
-
this.ws.send(pcmData);
|
|
69722
|
+
handleWorkletMessage(e) {
|
|
69723
|
+
const {
|
|
69724
|
+
type,
|
|
69725
|
+
payload
|
|
69726
|
+
} = e.data;
|
|
69727
|
+
if (type === 'audio') {
|
|
69728
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
69729
|
+
this.ws.send(payload);
|
|
69613
69730
|
}
|
|
69614
69731
|
}
|
|
69615
69732
|
},
|
|
69616
|
-
floatTo16BitPCM(input) {
|
|
69617
|
-
const output = new Int16Array(input.length);
|
|
69618
|
-
for (let i = 0; i < input.length; i++) {
|
|
69619
|
-
const s = Math.max(-1, Math.min(1, input[i]));
|
|
69620
|
-
output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
|
|
69621
|
-
}
|
|
69622
|
-
return output.buffer;
|
|
69623
|
-
},
|
|
69624
69733
|
stopRecording() {
|
|
69625
69734
|
if (!this.isRecording) return;
|
|
69626
|
-
if (this.
|
|
69627
|
-
if (this.
|
|
69628
|
-
if (this.
|
|
69735
|
+
if (this.mediaStreamSource) this.mediaStreamSource.disconnect();
|
|
69736
|
+
if (this.workletNode) this.workletNode.disconnect();
|
|
69737
|
+
if (this.stream) {
|
|
69738
|
+
this.stream.getTracks().forEach(t => t.stop());
|
|
69739
|
+
}
|
|
69629
69740
|
if (this.audioContext) {
|
|
69630
|
-
this.audioContext.close()
|
|
69631
|
-
|
|
69632
|
-
});
|
|
69741
|
+
this.audioContext.close();
|
|
69742
|
+
this.audioContext = null;
|
|
69633
69743
|
}
|
|
69634
69744
|
this.isRecording = false;
|
|
69745
|
+
console.log('录音已停止');
|
|
69746
|
+
},
|
|
69747
|
+
handleWebSocketMessage(data) {
|
|
69748
|
+
if (data.type === 'detection') {
|
|
69749
|
+
if (this.robotStatus === 'speaking') {
|
|
69750
|
+
this.robotStatus = 'waiting';
|
|
69751
|
+
}
|
|
69752
|
+
this.avaterStatus = 'normal';
|
|
69753
|
+
this.startTime = Date.now();
|
|
69754
|
+
}
|
|
69755
|
+
if (data.type === 'Collecting') {
|
|
69756
|
+
this.avaterStatus = 'thinking';
|
|
69757
|
+
}
|
|
69758
|
+
if (data.type === 'command') {
|
|
69759
|
+
if (this.startTime) {
|
|
69760
|
+
console.log(`[Latency] ${Date.now() - this.startTime}ms`);
|
|
69761
|
+
this.startTime = null;
|
|
69762
|
+
}
|
|
69763
|
+
this.analyzeAudioCommand(data.category);
|
|
69764
|
+
}
|
|
69635
69765
|
},
|
|
69636
69766
|
play() {
|
|
69637
|
-
this.
|
|
69638
|
-
this.$refs.audioPlayer.play();
|
|
69767
|
+
this.$refs.audioPlayer?.play();
|
|
69639
69768
|
},
|
|
69640
69769
|
pause() {
|
|
69641
|
-
|
|
69642
|
-
this.robotStatus = 'waiting';
|
|
69643
|
-
this.$refs.audioPlayer.pause();
|
|
69770
|
+
this.$refs.audioPlayer?.pause();
|
|
69644
69771
|
},
|
|
69645
69772
|
stop() {
|
|
69646
|
-
|
|
69647
|
-
|
|
69648
|
-
|
|
69649
|
-
|
|
69650
|
-
},
|
|
69651
|
-
analyzeAudioCommand(command) {
|
|
69652
|
-
console.log('分析音频命令:', command);
|
|
69653
|
-
if (command === 'C5') {
|
|
69654
|
-
this.robotStatus = 'entering';
|
|
69655
|
-
setTimeout(() => {
|
|
69656
|
-
this.robotStatus = 'speaking';
|
|
69657
|
-
this.play();
|
|
69658
|
-
}, 3000);
|
|
69659
|
-
} else if (command === 'C8') {
|
|
69660
|
-
this.robotStatus = 'speaking';
|
|
69661
|
-
this.play();
|
|
69662
|
-
} else if (command === 'C7') {
|
|
69663
|
-
this.robotStatus = 'waiting';
|
|
69664
|
-
this.pause();
|
|
69665
|
-
} else if (command === 'C6') {
|
|
69666
|
-
this.robotStatus = 'leaving';
|
|
69667
|
-
this.avaterStatus = 'normal';
|
|
69668
|
-
this.stop();
|
|
69669
|
-
}
|
|
69773
|
+
const p = this.$refs.audioPlayer;
|
|
69774
|
+
if (!p) return;
|
|
69775
|
+
p.pause();
|
|
69776
|
+
p.currentTime = 0;
|
|
69670
69777
|
}
|
|
69671
69778
|
}
|
|
69672
69779
|
});
|
|
69673
69780
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/esnext.json.parse.js
|
|
69674
69781
|
var esnext_json_parse = __webpack_require__(8335);
|
|
69675
69782
|
;// ./components/config/index.js
|
|
69676
|
-
const baseUrl = window.location.host;
|
|
69783
|
+
// const baseUrl = window.location.host;
|
|
69784
|
+
|
|
69677
69785
|
const API_URL = `/lingxiao-byt/api/v1/mcp/ask`; // 对话
|
|
69678
|
-
const WS_URL = `ws://${baseUrl}/audio/ws/`;
|
|
69679
|
-
const
|
|
69786
|
+
// export const WS_URL = `ws://${baseUrl}/audio/ws/`; // 语音
|
|
69787
|
+
const WS_URL = `ws://220.189.237.146:8312/audio/ws/`; // 测试语音
|
|
69788
|
+
|
|
69789
|
+
const AUDIO_URL = '/minio/lingxiaoai/byt.mp3'; // 导览 铜梁
|
|
69790
|
+
|
|
69791
|
+
const COLLECTION = '/minio/lingxiaoai/collection.mp3';
|
|
69792
|
+
const AREA_BOARD = '/minio/lingxiaoai/area_board.mp3'; // 区域看板
|
|
69793
|
+
const ENTERPRISE_APPLICATION = '/minio/lingxiaoai/enterprise_application.mp3'; // 企业应用
|
|
69794
|
+
const REGIONAL_APPLICATION = '/minio/lingxiaoai/regional_application.mp3'; // 区域应用
|
|
69795
|
+
|
|
69680
69796
|
const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音url跳转节点
|
|
69797
|
+
const SUBTITLE_POINTS_URL = '/minio/lingxiaoai/subTitlePoints.json'; // 字幕跳转节点
|
|
69681
69798
|
;// ./components/mixins/webSocketMixin.js
|
|
69682
69799
|
|
|
69683
69800
|
|
|
@@ -69697,11 +69814,7 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音u
|
|
|
69697
69814
|
methods: {
|
|
69698
69815
|
initWebSocket() {
|
|
69699
69816
|
try {
|
|
69700
|
-
// this.ws = new WebSocket('ws://10.2.233.41:9999');
|
|
69701
|
-
// 测试
|
|
69702
|
-
// console.log('WS_URL:', WS_URL)
|
|
69703
69817
|
this.ws = new WebSocket(WS_URL);
|
|
69704
|
-
// this.ws = new WebSocket('ws://192.168.8.87/audio/ws/');
|
|
69705
69818
|
this.ws.binaryType = 'arraybuffer';
|
|
69706
69819
|
this.ws.onopen = async () => {
|
|
69707
69820
|
console.log('WebSocket 连接成功');
|
|
@@ -69771,12 +69884,15 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音u
|
|
|
69771
69884
|
console.log('状态: 处理中');
|
|
69772
69885
|
|
|
69773
69886
|
// 性能检测终点
|
|
69774
|
-
if (this.startTime) {
|
|
69775
|
-
|
|
69776
|
-
|
|
69777
|
-
|
|
69778
|
-
}
|
|
69887
|
+
// if (this.startTime) {
|
|
69888
|
+
// const latency = Date.now() - this.startTime;
|
|
69889
|
+
// console.log(`[Latency] 完整命令处理耗时: ${latency}ms`); // 记录端到端延迟
|
|
69890
|
+
// this.startTime = null;
|
|
69891
|
+
// }
|
|
69892
|
+
|
|
69779
69893
|
this.analyzeAudioCommand(data.category);
|
|
69894
|
+
} else if (data.type === 'voice') {
|
|
69895
|
+
this.analyzeVoiceCommand(data.category);
|
|
69780
69896
|
} else {
|
|
69781
69897
|
console.log('状态: 其他');
|
|
69782
69898
|
this.avaterStatus = 'normal';
|
|
@@ -70094,6 +70210,7 @@ function generateUuid() {
|
|
|
70094
70210
|
// 记录耗时
|
|
70095
70211
|
const duration = Date.now() - startTime;
|
|
70096
70212
|
if (this.currentMessage) {
|
|
70213
|
+
this.messageLoading = false;
|
|
70097
70214
|
this.currentMessage.time = (duration / 1000).toFixed(2);
|
|
70098
70215
|
}
|
|
70099
70216
|
console.log(`流处理完成,总耗时: ${duration}ms`);
|
|
@@ -70101,10 +70218,9 @@ function generateUuid() {
|
|
|
70101
70218
|
} catch (error) {
|
|
70102
70219
|
console.error('发送消息失败:', error);
|
|
70103
70220
|
if (this.currentMessage) {
|
|
70221
|
+
this.messageLoading = false;
|
|
70104
70222
|
this.currentMessage.content = '抱歉,发生了错误,请重试。';
|
|
70105
70223
|
}
|
|
70106
|
-
} finally {
|
|
70107
|
-
this.messageLoading = false;
|
|
70108
70224
|
}
|
|
70109
70225
|
},
|
|
70110
70226
|
/**
|
|
@@ -70170,6 +70286,9 @@ function generateUuid() {
|
|
|
70170
70286
|
},
|
|
70171
70287
|
beforeDestroy() {}
|
|
70172
70288
|
});
|
|
70289
|
+
;// ./components/config/blacklist.js
|
|
70290
|
+
const BLACKLIST = ['81010400' // 南方水泥
|
|
70291
|
+
];
|
|
70173
70292
|
;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=script&lang=js
|
|
70174
70293
|
|
|
70175
70294
|
|
|
@@ -70189,15 +70308,30 @@ function generateUuid() {
|
|
|
70189
70308
|
|
|
70190
70309
|
|
|
70191
70310
|
|
|
70311
|
+
|
|
70192
70312
|
const SAMPLE_RATE = 16000;
|
|
70193
70313
|
const FRAME_SIZE = 512;
|
|
70194
|
-
const
|
|
70314
|
+
const ROBOT_STATUS = {
|
|
70315
|
+
ENTERING: 'entering',
|
|
70316
|
+
// 进入中
|
|
70317
|
+
SPEAKING: 'speaking',
|
|
70318
|
+
// 说话中
|
|
70319
|
+
WAITING: 'waiting',
|
|
70320
|
+
// 等待中
|
|
70321
|
+
LEAVING: 'leaving' // 离开中
|
|
70322
|
+
};
|
|
70323
|
+
const AVATAR_STATUS = {
|
|
70324
|
+
NORMAL: 'normal',
|
|
70325
|
+
// 正常
|
|
70326
|
+
THINKING: 'thinking' // 思考中
|
|
70327
|
+
};
|
|
70195
70328
|
/* harmony default export */ var ChatWindowvue_type_script_lang_js = ({
|
|
70196
70329
|
name: 'ChatWindow',
|
|
70197
70330
|
components: {
|
|
70198
70331
|
ChatRobot: ChatRobot,
|
|
70199
70332
|
ChatAvatar: ChatAvatar,
|
|
70200
|
-
ChatWindowDialog: ChatWindowDialog
|
|
70333
|
+
ChatWindowDialog: ChatWindowDialog,
|
|
70334
|
+
AudioSubtitle: AudioSubtitle
|
|
70201
70335
|
},
|
|
70202
70336
|
mixins: [audioMixin, webSocketMixin, messageMixin],
|
|
70203
70337
|
props: {
|
|
@@ -70208,32 +70342,67 @@ const startTime = null;
|
|
|
70208
70342
|
},
|
|
70209
70343
|
data() {
|
|
70210
70344
|
return {
|
|
70345
|
+
lastTimeUpdate: null,
|
|
70346
|
+
// 上次更新时间
|
|
70211
70347
|
chatId: generateUuid(),
|
|
70348
|
+
// 唯一标识当前聊天会话
|
|
70212
70349
|
audioSrc: AUDIO_URL,
|
|
70350
|
+
// 音频文件URL
|
|
70213
70351
|
inputMessage: '',
|
|
70352
|
+
// 当前输入的消息
|
|
70214
70353
|
visible: false,
|
|
70354
|
+
// 是否显示聊天窗口
|
|
70215
70355
|
messages: [],
|
|
70356
|
+
// 聊天消息数组
|
|
70216
70357
|
messageLoading: true,
|
|
70358
|
+
// 是否正在加载消息
|
|
70217
70359
|
robotStatus: 'leaving',
|
|
70360
|
+
// 机器人状态 entering: 进入中, waiting: 等待中, speaking: 说话中, leaving: 离开中
|
|
70218
70361
|
avaterStatus: 'normal',
|
|
70362
|
+
// 头像状态 normal: 正常, thinking: 思考中
|
|
70219
70363
|
currentMessage: null,
|
|
70364
|
+
// 当前正在处理的消息
|
|
70220
70365
|
thinkStatus: true,
|
|
70366
|
+
// 是否思考中
|
|
70221
70367
|
jumpedTimePoints: new Set(),
|
|
70368
|
+
// 已跳转的时间点集合
|
|
70222
70369
|
SAMPLE_RATE,
|
|
70370
|
+
// 采样率 16000Hz
|
|
70223
70371
|
FRAME_SIZE,
|
|
70224
|
-
|
|
70225
|
-
// 检查性能使用
|
|
70372
|
+
// 帧大小 512
|
|
70226
70373
|
dragThreshold: 5,
|
|
70227
70374
|
// 拖拽阈值
|
|
70228
70375
|
isDragging: false,
|
|
70376
|
+
// 是否正在拖拽
|
|
70229
70377
|
dragStartX: 0,
|
|
70378
|
+
// 拖拽开始时的X坐标
|
|
70230
70379
|
dragStartY: 0,
|
|
70380
|
+
// 拖拽开始时的Y坐标
|
|
70231
70381
|
currentX: 10,
|
|
70382
|
+
// 当前X坐标
|
|
70232
70383
|
currentY: 20,
|
|
70384
|
+
// 当前Y坐标
|
|
70233
70385
|
initialX: 10,
|
|
70386
|
+
// 初始X坐标
|
|
70234
70387
|
initialY: 20,
|
|
70388
|
+
// 初始Y坐标
|
|
70235
70389
|
hasMoved: false,
|
|
70236
|
-
|
|
70390
|
+
// 是否已移动
|
|
70391
|
+
timeJumpPoints: null,
|
|
70392
|
+
// 跳转
|
|
70393
|
+
subTitlePoints: null,
|
|
70394
|
+
// 字幕
|
|
70395
|
+
currentJumpPoints: [],
|
|
70396
|
+
// 当前跳转点数组
|
|
70397
|
+
currentSubtitles: [],
|
|
70398
|
+
// 当前字幕数组
|
|
70399
|
+
currentSubtitle: '',
|
|
70400
|
+
// 当前字幕,
|
|
70401
|
+
jumpIndex: 0,
|
|
70402
|
+
// 当前跳转索引
|
|
70403
|
+
subtitleIndex: 0,
|
|
70404
|
+
// 当前字幕索引
|
|
70405
|
+
isTourRunning: false // 是否正在导览
|
|
70237
70406
|
};
|
|
70238
70407
|
},
|
|
70239
70408
|
computed: {
|
|
@@ -70251,12 +70420,12 @@ const startTime = null;
|
|
|
70251
70420
|
};
|
|
70252
70421
|
}
|
|
70253
70422
|
},
|
|
70254
|
-
mounted() {
|
|
70423
|
+
async mounted() {
|
|
70255
70424
|
this.initWebSocket();
|
|
70256
70425
|
if (this.appendToBody) {
|
|
70257
70426
|
this.appendToBodyHandler();
|
|
70258
70427
|
}
|
|
70259
|
-
this.fetchTimeJumpPoints();
|
|
70428
|
+
await Promise.all([this.fetchTimeJumpPoints(), this.fetchSubTitlePoints()]);
|
|
70260
70429
|
this.$nextTick(() => {
|
|
70261
70430
|
const chatEl = this.$el;
|
|
70262
70431
|
const style = window.getComputedStyle(chatEl);
|
|
@@ -70276,16 +70445,27 @@ const startTime = null;
|
|
|
70276
70445
|
document.removeEventListener('mouseup', this.stopDrag);
|
|
70277
70446
|
},
|
|
70278
70447
|
methods: {
|
|
70448
|
+
initGuide() {
|
|
70449
|
+
this.jumpIndex = 0;
|
|
70450
|
+
this.subtitleIndex = 0;
|
|
70451
|
+
this.jumpedTimePoints.clear();
|
|
70452
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70453
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70454
|
+
},
|
|
70455
|
+
setRobotStatus(status) {
|
|
70456
|
+
this.robotStatus = status || ROBOT_STATUS.LEAVING;
|
|
70457
|
+
},
|
|
70458
|
+
setAvatarStatus(status) {
|
|
70459
|
+
this.avaterStatus = status || AVATAR_STATUS.NORMAL;
|
|
70460
|
+
},
|
|
70279
70461
|
toggleWindow() {
|
|
70280
|
-
if (this.avaterStatus === 'thinking') return;
|
|
70281
70462
|
this.visible = !this.visible;
|
|
70282
70463
|
if (this.visible) {
|
|
70283
70464
|
this.currentX = this.initialX;
|
|
70284
70465
|
this.currentY = this.initialY;
|
|
70285
70466
|
}
|
|
70286
70467
|
},
|
|
70287
|
-
startDrag() {
|
|
70288
|
-
console.log('startDrag');
|
|
70468
|
+
startDrag(event) {
|
|
70289
70469
|
if (this.robotStatus !== 'leaving' && this.visible) return;
|
|
70290
70470
|
this.isDragging = true;
|
|
70291
70471
|
this.hasMoved = false;
|
|
@@ -70337,9 +70517,18 @@ const startTime = null;
|
|
|
70337
70517
|
document.removeEventListener('mousemove', this.onDrag);
|
|
70338
70518
|
document.removeEventListener('mouseup', this.stopDrag);
|
|
70339
70519
|
if (!this.hasMoved) {
|
|
70340
|
-
this.
|
|
70520
|
+
this.handleClick();
|
|
70341
70521
|
}
|
|
70342
70522
|
},
|
|
70523
|
+
handleClick() {
|
|
70524
|
+
if (this.avaterStatus === 'thinking') return;
|
|
70525
|
+
if (this.isInBlacklist()) return;
|
|
70526
|
+
this.toggleWindow();
|
|
70527
|
+
},
|
|
70528
|
+
isInBlacklist() {
|
|
70529
|
+
const tenantId = getCookie('bonyear-tenantId');
|
|
70530
|
+
return tenantId && BLACKLIST.includes(tenantId);
|
|
70531
|
+
},
|
|
70343
70532
|
handleThinkingClick() {
|
|
70344
70533
|
this.thinkStatus = !this.thinkStatus;
|
|
70345
70534
|
},
|
|
@@ -70355,54 +70544,274 @@ const startTime = null;
|
|
|
70355
70544
|
},
|
|
70356
70545
|
async fetchTimeJumpPoints() {
|
|
70357
70546
|
try {
|
|
70358
|
-
const res = await fetch(TIME_JUMP_POINTS_URL);
|
|
70547
|
+
const res = await fetch(TIME_JUMP_POINTS_URL + '?timestamp=' + Date.now());
|
|
70359
70548
|
const data = await res.json();
|
|
70360
|
-
this.timeJumpPoints =
|
|
70361
|
-
console.log('时间跳转点加载完成:', this.timeJumpPoints);
|
|
70549
|
+
this.timeJumpPoints = data;
|
|
70362
70550
|
} catch (err) {
|
|
70363
70551
|
console.error('获取时间跳转点失败:', err);
|
|
70364
|
-
this.timeJumpPoints =
|
|
70552
|
+
this.timeJumpPoints = null;
|
|
70553
|
+
}
|
|
70554
|
+
},
|
|
70555
|
+
async fetchSubTitlePoints() {
|
|
70556
|
+
try {
|
|
70557
|
+
const res = await fetch(SUBTITLE_POINTS_URL + '?timestamp=' + Date.now());
|
|
70558
|
+
const data = await res.json();
|
|
70559
|
+
this.subTitlePoints = data;
|
|
70560
|
+
} catch (err) {
|
|
70561
|
+
console.error('获取字幕跳转点失败');
|
|
70562
|
+
this.subTitlePoints = null;
|
|
70563
|
+
}
|
|
70564
|
+
},
|
|
70565
|
+
normalizeCommand(cmd = '') {
|
|
70566
|
+
return cmd.trim() // 去掉 \n \r 空格
|
|
70567
|
+
.replace(/[\u200B-\u200D]/g, '') // 去零宽字符
|
|
70568
|
+
.replace(/[。!?,、,.!?]/g, ''); // 去标点
|
|
70569
|
+
},
|
|
70570
|
+
// 分析音频语音指令
|
|
70571
|
+
analyzeVoiceCommand(name) {
|
|
70572
|
+
console.log('===== analyzeVoiceCommand =====');
|
|
70573
|
+
console.log('typeof name:', typeof name);
|
|
70574
|
+
console.log('name === "结束导览":', name === '结束导览');
|
|
70575
|
+
console.log('Object.prototype.toString:', Object.prototype.toString.call(name));
|
|
70576
|
+
const normalized = this.normalizeCommand(name);
|
|
70577
|
+
const commandMap = {
|
|
70578
|
+
'开始导览': this.startTheTour,
|
|
70579
|
+
'开始区域看板导览': this.startAreaBoardTour,
|
|
70580
|
+
'开始企业应用导览': this.startEnterpriseApplicationTour,
|
|
70581
|
+
'开始区域应用导览': this.startRegionalApplicationTour,
|
|
70582
|
+
'暂停导览': this.pauseTheTour,
|
|
70583
|
+
'继续导览': this.resumeTheTour,
|
|
70584
|
+
'结束导览': this.offTheTour,
|
|
70585
|
+
'返回首页': this.returnToHome,
|
|
70586
|
+
'未知指令': this.offTheTour
|
|
70587
|
+
};
|
|
70588
|
+
const handler = commandMap[normalized];
|
|
70589
|
+
if (!handler) {
|
|
70590
|
+
console.warn('未定义的指令:', name);
|
|
70591
|
+
return;
|
|
70592
|
+
}
|
|
70593
|
+
handler();
|
|
70594
|
+
},
|
|
70595
|
+
// 启动导览
|
|
70596
|
+
async onTheTour() {
|
|
70597
|
+
if (this.isTourRunning) return;
|
|
70598
|
+
this.isTourRunning = true;
|
|
70599
|
+
const audio = this.$refs.audioPlayer;
|
|
70600
|
+
if (!audio) return;
|
|
70601
|
+
this.setRobotStatus(ROBOT_STATUS.ENTERING);
|
|
70602
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
70603
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70604
|
+
try {
|
|
70605
|
+
await audio.play();
|
|
70606
|
+
} catch (e) {
|
|
70607
|
+
console.error('播放音频失败:', e);
|
|
70608
|
+
} finally {
|
|
70609
|
+
this.isTourRunning = false;
|
|
70610
|
+
}
|
|
70611
|
+
},
|
|
70612
|
+
// 暂停导览
|
|
70613
|
+
pauseTheTour() {
|
|
70614
|
+
this.pause();
|
|
70615
|
+
this.setRobotStatus(ROBOT_STATUS.WAITING);
|
|
70616
|
+
},
|
|
70617
|
+
// 继续导览
|
|
70618
|
+
resumeTheTour() {
|
|
70619
|
+
this.play();
|
|
70620
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70621
|
+
},
|
|
70622
|
+
// 结束导览
|
|
70623
|
+
offTheTour() {
|
|
70624
|
+
this.stop();
|
|
70625
|
+
this.currentSubtitle = '';
|
|
70626
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70627
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70628
|
+
},
|
|
70629
|
+
// 返回首页
|
|
70630
|
+
returnToHome() {
|
|
70631
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70632
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70633
|
+
this.$appOptions.router.push({
|
|
70634
|
+
path: '/'
|
|
70635
|
+
});
|
|
70636
|
+
},
|
|
70637
|
+
initJumpPoints(name) {
|
|
70638
|
+
// 初始化跳转点
|
|
70639
|
+
if (name) {
|
|
70640
|
+
this.currentJumpPoints = this.timeJumpPoints[name] || [];
|
|
70641
|
+
console.log('currentJumpPoints:', this.currentJumpPoints);
|
|
70642
|
+
} else {
|
|
70643
|
+
this.currentJumpPoints = this.timeJumpPoints;
|
|
70644
|
+
}
|
|
70645
|
+
},
|
|
70646
|
+
initSubtitles(name) {
|
|
70647
|
+
console.log('name:', name);
|
|
70648
|
+
if (name) {
|
|
70649
|
+
this.currentSubtitles = this.subTitlePoints[name] || [];
|
|
70650
|
+
} else {
|
|
70651
|
+
this.currentSubtitles = this.subTitlePoints;
|
|
70652
|
+
}
|
|
70653
|
+
},
|
|
70654
|
+
// 开始导览
|
|
70655
|
+
async startTheTour() {
|
|
70656
|
+
await this.setAudio(COLLECTION); // 重置音频源
|
|
70657
|
+
|
|
70658
|
+
// 重置指针
|
|
70659
|
+
this.initGuide();
|
|
70660
|
+
// 重置跳转点指针
|
|
70661
|
+
this.initJumpPoints('开始导览');
|
|
70662
|
+
// 重置字幕指针
|
|
70663
|
+
this.initSubtitles('开始导览');
|
|
70664
|
+
await this.onTheTour();
|
|
70665
|
+
},
|
|
70666
|
+
// 开始区域看板导览
|
|
70667
|
+
async startAreaBoardTour() {
|
|
70668
|
+
// 重置audio
|
|
70669
|
+
await this.setAudio(AREA_BOARD);
|
|
70670
|
+
|
|
70671
|
+
// 重置指针
|
|
70672
|
+
this.initGuide();
|
|
70673
|
+
// 重置跳转点指针
|
|
70674
|
+
this.initJumpPoints('开始区域看板导览');
|
|
70675
|
+
// 重置字幕指针
|
|
70676
|
+
this.initSubtitles('开始区域看板导览');
|
|
70677
|
+
await this.onTheTour();
|
|
70678
|
+
},
|
|
70679
|
+
// 开始企业应用导览
|
|
70680
|
+
async startEnterpriseApplicationTour() {
|
|
70681
|
+
await this.setAudio(ENTERPRISE_APPLICATION);
|
|
70682
|
+
|
|
70683
|
+
// 重置指针
|
|
70684
|
+
this.initGuide();
|
|
70685
|
+
// 重置跳转点指针
|
|
70686
|
+
this.initJumpPoints('开始企业应用导览');
|
|
70687
|
+
// 重置字幕指针
|
|
70688
|
+
this.initSubtitles('开始企业应用导览');
|
|
70689
|
+
await this.onTheTour();
|
|
70690
|
+
},
|
|
70691
|
+
// 开始区域应用导览
|
|
70692
|
+
async startRegionalApplicationTour() {
|
|
70693
|
+
await this.setAudio(REGIONAL_APPLICATION);
|
|
70694
|
+
|
|
70695
|
+
// 重置指针
|
|
70696
|
+
this.initGuide();
|
|
70697
|
+
// 重置跳转点指针
|
|
70698
|
+
this.initJumpPoints('开始区域应用导览');
|
|
70699
|
+
// 重置字幕指针
|
|
70700
|
+
this.initSubtitles('开始区域应用导览');
|
|
70701
|
+
await this.onTheTour();
|
|
70702
|
+
},
|
|
70703
|
+
// 分析音频命令
|
|
70704
|
+
analyzeAudioCommand(command) {
|
|
70705
|
+
console.log('分析音频命令:', command);
|
|
70706
|
+
if (command === 'C5') {
|
|
70707
|
+
this.setRobotStatus(ROBOT_STATUS.ENTERING);
|
|
70708
|
+
setTimeout(() => {
|
|
70709
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70710
|
+
this.play();
|
|
70711
|
+
}, 3000);
|
|
70712
|
+
}
|
|
70713
|
+
if (command === 'C8') {
|
|
70714
|
+
this.setRobotStatus(ROBOT_STATUS.SPEAKING);
|
|
70715
|
+
this.play();
|
|
70716
|
+
}
|
|
70717
|
+
if (command === 'C7') {
|
|
70718
|
+
this.setRobotStatus(ROBOT_STATUS.WAITING);
|
|
70719
|
+
this.pause();
|
|
70720
|
+
}
|
|
70721
|
+
if (command === 'C6') {
|
|
70722
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70723
|
+
this.stop();
|
|
70365
70724
|
}
|
|
70366
70725
|
},
|
|
70726
|
+
// 处理点击跳转时间
|
|
70727
|
+
handleJumpPoint(currentTime) {
|
|
70728
|
+
console.log('jumpIndex:', this.jumpIndex);
|
|
70729
|
+
const point = this.currentJumpPoints[this.jumpIndex];
|
|
70730
|
+
if (!point) return;
|
|
70731
|
+
console.log('currentTime:', currentTime);
|
|
70732
|
+
console.log('point.time:', point.time);
|
|
70733
|
+
if (currentTime >= point.time && !this.jumpedTimePoints.has(point.time)) {
|
|
70734
|
+
this.jumpedTimePoints.add(point.time);
|
|
70735
|
+
this.jumpIndex++;
|
|
70736
|
+
this.$appOptions.store.dispatch('tags/addTagview', {
|
|
70737
|
+
path: point.url,
|
|
70738
|
+
fullPath: point.url,
|
|
70739
|
+
label: point.title,
|
|
70740
|
+
name: point.title,
|
|
70741
|
+
meta: {
|
|
70742
|
+
title: point.title
|
|
70743
|
+
},
|
|
70744
|
+
query: {},
|
|
70745
|
+
params: {}
|
|
70746
|
+
});
|
|
70747
|
+
this.$appOptions.router.push({
|
|
70748
|
+
path: point.url
|
|
70749
|
+
});
|
|
70750
|
+
}
|
|
70751
|
+
},
|
|
70752
|
+
// 处理播放字幕
|
|
70753
|
+
handlePlaySubtitles(currentTime) {
|
|
70754
|
+
const subtitle = this.currentSubtitles[this.subtitleIndex];
|
|
70755
|
+
if (!subtitle) return;
|
|
70756
|
+
if (currentTime < subtitle.start) return;
|
|
70757
|
+
|
|
70758
|
+
// 正在播放当前字幕
|
|
70759
|
+
if (currentTime >= subtitle.start && currentTime <= subtitle.end) {
|
|
70760
|
+
if (this.currentSubtitle !== subtitle.text) {
|
|
70761
|
+
this.currentSubtitle = subtitle.text;
|
|
70762
|
+
}
|
|
70763
|
+
return;
|
|
70764
|
+
}
|
|
70765
|
+
|
|
70766
|
+
// 超过当前字幕,推进游标
|
|
70767
|
+
if (currentTime > subtitle.end) {
|
|
70768
|
+
this.subtitleIndex++;
|
|
70769
|
+
this.currentSubtitle = '';
|
|
70770
|
+
}
|
|
70771
|
+
},
|
|
70772
|
+
async setAudio(src) {
|
|
70773
|
+
return new Promise((resolve, reject) => {
|
|
70774
|
+
const audio = this.$refs.audioPlayer;
|
|
70775
|
+
if (!audio) return reject('未找到音频元素');
|
|
70776
|
+
audio.pause();
|
|
70777
|
+
audio.currentTime = 0;
|
|
70778
|
+
|
|
70779
|
+
// ✅ 用响应式数据
|
|
70780
|
+
this.audioSrc = src;
|
|
70781
|
+
this.$nextTick(() => {
|
|
70782
|
+
audio.load();
|
|
70783
|
+
const onCanPlay = () => {
|
|
70784
|
+
audio.removeEventListener('canplay', onCanPlay);
|
|
70785
|
+
resolve();
|
|
70786
|
+
};
|
|
70787
|
+
audio.addEventListener('canplay', onCanPlay);
|
|
70788
|
+
});
|
|
70789
|
+
});
|
|
70790
|
+
},
|
|
70367
70791
|
// 音频时间更新处理
|
|
70368
70792
|
onTimeUpdate() {
|
|
70793
|
+
const now = performance.now();
|
|
70794
|
+
if (this.lastTimeUpdate && now - this.lastTimeUpdate < 200) return;
|
|
70795
|
+
this.lastTimeUpdate = now;
|
|
70369
70796
|
const audio = this.$refs.audioPlayer;
|
|
70370
70797
|
const currentTime = audio.currentTime;
|
|
70371
|
-
|
|
70372
|
-
this.
|
|
70373
|
-
if (currentTime >= point.time && currentTime < point.time + 1 && !this.jumpedTimePoints.has(point.time)) {
|
|
70374
|
-
console.log('触发跳转:', point.url);
|
|
70375
|
-
this.jumpedTimePoints.add(point.time);
|
|
70376
|
-
this.$appOptions.store.dispatch('tags/addTagview', {
|
|
70377
|
-
path: point.url,
|
|
70378
|
-
fullPath: point.url,
|
|
70379
|
-
label: point.title,
|
|
70380
|
-
name: point.title,
|
|
70381
|
-
meta: {
|
|
70382
|
-
title: point.title
|
|
70383
|
-
},
|
|
70384
|
-
query: {},
|
|
70385
|
-
params: {}
|
|
70386
|
-
});
|
|
70387
|
-
this.$appOptions.router.push({
|
|
70388
|
-
path: point.url
|
|
70389
|
-
});
|
|
70390
|
-
}
|
|
70391
|
-
});
|
|
70798
|
+
this.handleJumpPoint(currentTime);
|
|
70799
|
+
this.handlePlaySubtitles(currentTime);
|
|
70392
70800
|
},
|
|
70393
70801
|
onAudioEnded() {
|
|
70394
|
-
this.
|
|
70395
|
-
this.
|
|
70802
|
+
this.currentSubtitle = '';
|
|
70803
|
+
this.setRobotStatus(ROBOT_STATUS.LEAVING);
|
|
70804
|
+
this.setAvatarStatus(AVATAR_STATUS.NORMAL);
|
|
70396
70805
|
this.jumpedTimePoints.clear();
|
|
70397
70806
|
}
|
|
70398
70807
|
}
|
|
70399
70808
|
});
|
|
70400
70809
|
;// ./components/ChatWindow.vue?vue&type=script&lang=js
|
|
70401
70810
|
/* harmony default export */ var components_ChatWindowvue_type_script_lang_js = (ChatWindowvue_type_script_lang_js);
|
|
70402
|
-
;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=style&index=0&id=
|
|
70811
|
+
;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.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
|
|
70403
70812
|
// extracted by mini-css-extract-plugin
|
|
70404
70813
|
|
|
70405
|
-
;// ./components/ChatWindow.vue?vue&type=style&index=0&id=
|
|
70814
|
+
;// ./components/ChatWindow.vue?vue&type=style&index=0&id=959a9f66&prod&scoped=true&lang=css
|
|
70406
70815
|
|
|
70407
70816
|
;// ./components/ChatWindow.vue
|
|
70408
70817
|
|
|
@@ -70419,7 +70828,7 @@ var ChatWindow_component = normalizeComponent(
|
|
|
70419
70828
|
staticRenderFns,
|
|
70420
70829
|
false,
|
|
70421
70830
|
null,
|
|
70422
|
-
"
|
|
70831
|
+
"959a9f66",
|
|
70423
70832
|
null
|
|
70424
70833
|
|
|
70425
70834
|
)
|