<template>
	<view class="container">
		<button @click="onStartRecord" :disabled="isRecording">开始录音</button>
		<button @click="onStopRecord" :disabled="!isRecording">停止录音</button>
		<view class="tip">{{ status }}</view>
		<view class="tip">当前分贝：{{ currentDecibels }}</view>
		<yao-RecordFrame ref="recordFrame" @onFrameRecorded="frameRecorded" @currentDecibels="onCurrentDecibels"
			@onStop="stopIt">
		</yao-RecordFrame>
		<sdx-StreamPlayer ref="aaa">xx</sdx-StreamPlayer>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				status: "未录音",
				currentDecibels: 0,
				isRecording: false,
				ws: null, // WebSocket 实例
				audioContext: null, // 音频上下文
				scriptProcessor: null, // 音频处理节点
				audioBufferSource: null, // 音频源节点
				frameBufferList: [], // 缓存音频帧
				wsUrl: "ws://172.16.89.58:8000/ws/audio", // 替换为实际后端地址
			};
		},
		onUnload() {
			// 页面卸载时清理资源
			this.stopRecordAndClean();
		},
		methods: {


			// 申请录音权限
			async applyRecordPermission() {
				try {
					const res = await uni.requestPermissions({
						scope: "scope.record"
					});
					const isGranted = res[0].grantStatus === 1;
					if (!isGranted) {
						uni.showToast({
							title: "请授予录音权限",
							icon: "none"
						});
					}
					return isGranted;
				} catch (e) {
					console.error("申请权限失败：", e);
					return false;
				}
			},
			// ArrayBuffer 转字符串
			// 兼容的 ArrayBuffer 转字符串方法
			arrayBufferToStringCompat(buffer) {
			    // 方法1: 使用 String.fromCharCode 和 Uint8Array
			    const uint8Array = new Uint8Array(buffer);
			    let str = '';
			    for (let i = 0; i < uint8Array.length; i++) {
			        str += String.fromCharCode(uint8Array[i]);
			    }
			    return str;
			    
			    // 方法2: 或者使用更简洁的方式
			    // return String.fromCharCode.apply(null, new Uint8Array(buffer));
			},
			// 开始录音
			async onStartRecord() {
				// 1. 申请权限
				// const hasPermission = await this.applyRecordPermission();
				// if (!hasPermission) return;
				this.ws = uni.connectSocket({
					url: this.wsUrl, //仅为示例，并非真实接口地址。
					complete: () => {
						console.log('complete');
					},
					success: () => {
						console.log('web');
						this.ws.onOpen((res) => {
							console.log('WebSocket连接已打开', res);
							

							this.ws.onMessage((res) => {
								let messageData = res.data;
								// 处理不同类型的数据
								if (typeof messageData === 'string') {
									// 文本数据
									try {
										const parsedData = JSON.parse(messageData);
										this.handleMessage(parsedData);
									} catch (e) {
										this.handleMessage(messageData);
									}
								} else if (messageData instanceof ArrayBuffer) {
									// 二进制数据
									try {
										this.$refs.aaa.appendBuffer(messageData)
										// const str = this.arrayBufferToStringCompat(messageData);
										// console.log('转换后的字符串:', str);
										
									} catch (e) {
										console.log('二进制数据解析失败:', e);
									}
								}
							})
						});
					},
					fail: () => {
						console.log('fail');
					},
				});

				// await this.initWebSocket();

				// 3. 启动录音
				try {
					this.$refs.recordFrame.start({
						sampleRate: 16000,
						frameSize: 1024,
						gain: 1.0,
						onFrameRecorded: ({
							isLastFrame,
							frameBuffer
						}) => {
							// 处理帧数据（如实时上传/渲染）
							// console.log('帧数据:', frameData);
							this.ws.send({
								data: frameBuffer
							});
						},
						onDecibels: (decibels) => {
							// 处理分贝数据（如实时更新UI）
							// console.log('当前分贝:', decibels);
							this.currentDecibels = decibels;
						}
					});
					this.isRecording = true;
					this.status = "录音中...";
				} catch (e) {
					console.error("启动录音失败：", e);
					this.status = "启动录音失败";
					this.isRecording = false;
				}
			},
			
			// 停止录音
			onStopRecord() {
				this.stopRecordAndClean();
			},

			// 停止录音并清理资源
			stopRecordAndClean() {
				if (this.isRecording) {
					// 停止录音组件
					this.$refs.recordFrame.stop();
					this.isRecording = false;
					this.status = "已停止录音";
				}

				// 关闭 WebSocket
				if (this.ws) {
					this.ws.close();
					this.ws = null;
				}

				// 清理音频上下文
				if (this.audioContext) {
					this.audioContext.close();
					this.audioContext = null;
					this.scriptProcessor = null;
					this.frameBufferList = [];
				}

				// 重置状态
				this.currentDecibels = 0;
			},

			// 接收音频帧并处理
			frameRecorded({
				isLastFrame,
				frameBuffer
			}) {
				// console.log("收到音频帧：", isLastFrame, frameBuffer.length);

				// 2. 通过 WebSocket 发送给后端
				if (this.ws) {
					try {
						this.ws.send({
							data: frameBuffer
						});
					} catch (e) {
						console.error("发送音频帧失败：", e);
					}
				}


			},

			// 监听分贝值
			onCurrentDecibels(decibels) {
				// this.currentDecibels = decibels.toFixed(2);
				// console.log("当前分贝：", this.currentDecibels);
			},

			// 录音停止回调
			stopIt(base64) {
				this.stopRecordAndClean();
				console.log("录音停止，最终音频Base64：", base64?.substring(0, 50) + "...");
			},
		},
	};
</script>

<style scoped>
	.container {
		padding: 20rpx;
	}

	button {
		margin: 10rpx 0;
		padding: 15rpx 30rpx;
		background: #007aff;
		color: white;
		border: none;
		border-radius: 8rpx;
	}

	button:disabled {
		background: #ccc;
	}

	.tip {
		margin: 15rpx 0;
		font-size: 28rpx;
		color: #333;
	}
</style>