From a5bac22f6e10b1b662e5ae41055714f234b63d37 Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期四, 03 四月 2025 17:27:04 +0800
Subject: [PATCH] GIS系统隐藏

---
 src/components/chat/components/playBar/hook/useSpeech.ts |  181 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 181 insertions(+), 0 deletions(-)

diff --git a/src/components/chat/components/playBar/hook/useSpeech.ts b/src/components/chat/components/playBar/hook/useSpeech.ts
new file mode 100644
index 0000000..3d4e88f
--- /dev/null
+++ b/src/components/chat/components/playBar/hook/useSpeech.ts
@@ -0,0 +1,181 @@
+import axios from 'axios';
+import { ElMessage } from 'element-plus';
+import type { Ref } from 'vue';
+import { reactive, ref } from 'vue';
+
+type UseSpeechProps = {
+	inputText: Ref<string>;
+};
+export const useSpeech = (props: UseSpeechProps) => {
+	const { inputText } = props;
+	const isSupportSpeech = ref(!!navigator.mediaDevices);
+	const baiduSpeechConfig = {
+		format: 'wav',
+		rate: 16000,
+		channel: 1,
+		cuid: 'jVNmJvBApXOwDVb5aLKETdTjMK8bm3nI',
+		token: '',
+		dev_pid: 80001,
+		ak: 'aV5EwAw2hb80x8kVel8NUKfF',
+		sk: 'TKVhvcIa4rNskak0lfhPLINlxZWaCIUM',
+	};
+
+	const recordState = reactive({
+		isRecording: false,
+		audioContext: null,
+		mediaRecorder: null as MediaRecorder | null,
+		audioChunks: [],
+	});
+
+	const getAccessToken = async () => {
+		try {
+			const response = await axios.post(
+				`https://wi.beng35.com/api/baidu-token/oauth/2.0/token?grant_type=client_credentials&client_id=${baiduSpeechConfig.ak}&client_secret=${baiduSpeechConfig.sk}`
+			);
+			baiduSpeechConfig.token = response.data.access_token;
+			return response.data.access_token;
+		} catch (error) {
+			console.error('鑾峰彇 access token 澶辫触:', error);
+			ElMessage.error('鑾峰彇璇煶璇嗗埆鎺堟潈澶辫触');
+			throw error;
+		}
+	};
+	const startRecording = async () => {
+		try {
+			// 纭繚鏈� access token
+			if (!baiduSpeechConfig.token) {
+				await getAccessToken();
+			}
+
+			const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+			recordState.audioContext = new AudioContext({
+				sampleRate: 16000,
+				latencyHint: 'interactive',
+			});
+
+			const source = recordState.audioContext.createMediaStreamSource(stream);
+			const processor = recordState.audioContext.createScriptProcessor(4096, 1, 1);
+
+			// 瀛樺偍鍘熷闊抽鏁版嵁
+			const audioData = [];
+
+			processor.onaudioprocess = (e) => {
+				const inputData = e.inputBuffer.getChannelData(0);
+				// 灏� Float32Array 杞崲涓� Int16Array
+				const int16Data = new Int16Array(inputData.length);
+				for (let i = 0; i < inputData.length; i++) {
+					int16Data[i] = inputData[i] * 32767;
+				}
+				audioData.push(int16Data);
+			};
+
+			recordState.mediaRecorder = new MediaRecorder(stream);
+			recordState.audioChunks = [];
+
+			recordState.mediaRecorder.ondataavailable = (event) => {
+				if (event.data.size > 0) {
+					recordState.audioChunks.push(event.data);
+				}
+			};
+
+			recordState.mediaRecorder.onstop = async () => {
+				// 鍚堝苟鎵�鏈夐煶棰戞暟鎹�
+				const totalLength = audioData.reduce((acc, curr) => acc + curr.length, 0);
+				const mergedData = new Int16Array(totalLength);
+				let offset = 0;
+				audioData.forEach((data) => {
+					mergedData.set(data, offset);
+					offset += data.length;
+				});
+
+				// 灏� Int16Array 杞崲涓� base64
+				const buffer = mergedData.buffer;
+
+				let base64Data = '';
+				let len = 0;
+				// 鍒嗘壒澶勭悊澶у瀷鏁版嵁
+				// 涓嶇劧 String.fromCharCode 鍜屽睍寮�杩愮畻绗�... 浼氱垎鏍�
+				const chunkSize = 0.1 * 1024 * 1024; // 0.5MB chunks
+				const uint8Array = new Uint8Array(buffer);
+				const chunks = [];
+
+				for (let i = 0; i < uint8Array.length; i += chunkSize) {
+					const chunk = uint8Array.slice(i, i + chunkSize);
+					chunks.push(String.fromCharCode.apply(null, chunk));
+				}
+
+				base64Data = btoa(chunks.join(''));
+				len = mergedData.length * 2;
+
+				try {
+					// 璋冪敤鐧惧害璇煶璇嗗埆API
+					const response = await fetch('https://wi.beng35.com/api/baidu-speech/pro_api', {
+						method: 'POST',
+						headers: {
+							'Content-Type': 'application/json',
+						},
+						body: JSON.stringify({
+							format: 'pcm',
+							rate: 16000,
+							channel: 1,
+							cuid: baiduSpeechConfig.cuid,
+							dev_pid: 80001, // 鏅�氳瘽璇嗗埆
+							speech: base64Data,
+							len: len, // PCM 16浣�,姣忎釜閲囨牱鐐�2瀛楄妭
+							token: baiduSpeechConfig.token,
+						}),
+					});
+
+					const result = await response.json();
+
+					if (result.err_no === 0 && result.result && result.result.length > 0) {
+						inputText.value = result.result[0];
+						// showToast('璇煶璇嗗埆鎴愬姛');
+					} else {
+						ElMessage.error('璇煶璇嗗埆澶辫触锛�' + result.err_msg);
+					}
+				} catch (error) {
+					console.error('璇煶璇嗗埆璇锋眰澶辫触:', error);
+					ElMessage.error('璇煶璇嗗埆璇锋眰澶辫触');
+				}
+			};
+
+			recordState.mediaRecorder.start();
+			recordState.isRecording = true;
+			source.connect(processor);
+			processor.connect(recordState.audioContext.destination);
+		} catch (error) {
+			console.error('褰曢煶澶辫触:', error);
+			ElMessage.error('褰曢煶澶辫触,璇锋鏌ラ害鍏嬮鏉冮檺');
+		}
+	};
+
+	const stopRecording = () => {
+		if (recordState.mediaRecorder && recordState.isRecording) {
+			recordState.mediaRecorder.stop();
+			recordState.isRecording = false;
+			if (recordState.audioContext) {
+				recordState.audioContext.close();
+			}
+			
+		}
+	};
+
+	const cancelRecording = () => {
+		if (recordState.mediaRecorder && recordState.isRecording) {
+			recordState.mediaRecorder.resume();
+			recordState.isRecording = false;
+			if (recordState.audioContext) {
+				recordState.audioContext.close();
+			}
+		}
+	};
+
+	return {
+		isSupportSpeech,
+		startRecording,
+		stopRecording,
+		recordState,
+		cancelRecording,
+	};
+};

--
Gitblit v1.9.3