diff --git a/src/pages/sparring/components/talk-camera.nvue b/src/pages/sparring/components/talk-camera.nvue index cbbe00dc..f7d5a6c7 100644 --- a/src/pages/sparring/components/talk-camera.nvue +++ b/src/pages/sparring/components/talk-camera.nvue @@ -12,11 +12,8 @@ :whiteness="0" aspect="9:16" mode="SD" - device-position="front" - orientation > - @@ -27,9 +24,8 @@ const livePusherContext = ref(null); const isPreviewing = ref(false); const init = (componentProxy) => { - console.log('init'); - livePusherContext.value = uni.createLivePusherContext('livePusher', componentProxy); + livePusherContext.value.switchCamera() }; // 切换摄像头 const switchCamera = () => { @@ -59,13 +55,10 @@ console.error('complete预览:', err); } }); + if (getPhoneEnvBool('AND')) { console.log('切换前置'); - // setTimeout(() =>{ - // switchCamera() - // }, 1000) } - }); }; @@ -83,7 +76,6 @@ console.error('complete预览:', err); } }); - isPreviewing.value = false; }; defineExpose({ init, switchCamera, stopPreview, startPreview }); diff --git a/src/pages/sparring/js/useMicrophone.js b/src/pages/sparring/js/useMicrophone.js deleted file mode 100644 index af6863c2..00000000 --- a/src/pages/sparring/js/useMicrophone.js +++ /dev/null @@ -1,149 +0,0 @@ -import { - ref, - onUnmounted, - watch -} from 'vue'; - import { - ProtocolCodec, - MessageType, - SerializationType, - CompressionType, - ControlCommand, - ProtocolConst - } from './ProtocolCodec'; -/** - * 麦克风操作Hook(封装开始/停止录音、状态管理) - * @param {Object} options - 录音配置项 - * @param {number} options.duration - 最大录音时长(秒,默认60) - * @param {string} options.format - 录音格式(mp3/wav/pcm,默认mp3) - * @param {number} options.sampleRate - 采样率(默认16000) - * @param {number} options.bitRate - 码率(默认16000) - * @param {Function} options.onData - 实时音频数据回调(仅H5/PCM格式生效) - * @param {Function} options.onStop - 结束回调 - * @param {Function} options.onError - 错误回调 - * @returns {Object} 录音控制方法+状态 - */ -export default function useMicrophone(options = {}) { - console.log('options', options); - const send = options.send - const recordFrame = ref(null) - const renderJSModule = ref(null) - - // 默认配置 - const defaultOptions = { - duration: 60, - format: 'mp3', - sampleRate: 16000, - bitRate: 16000, - onData: () => {}, - onStop: () => {}, - onError: (err) => console.error('录音错误:', err) - }; - const finalOptions = { - ...defaultOptions, - ...options - }; - - // 响应式状态 - const isRecording = ref(false); // 是否正在录音 - const recordTime = ref(0); // 录音时长(秒) - const recordResult = ref(null); // 录音结果(临时文件路径/Blob) - const recorderManager = ref(null); // 录音管理器实例(uniapp/小程序) - const audioContext = ref(null); // AudioContext(H5) - const mediaRecorder = ref(null); // MediaRecorder(H5) - const timer = ref(null); // 录音时长定时器 - - // 平台判断 - const platform = uni.getSystemInfoSync().platform; - - // ==================== 核心方法:开始录音 ==================== - const startRecording = async () => { - // 防止重复点击 - if (isRecording.value) return; - - // 重置状态 - recordTime.value = 0; - recordResult.value = null; - console.log('开始', recordFrame.value); - recordFrame.value.start({ - sampleRate: 16000, - frameSize: 1024, - gain: 1.0, - onFrameRecorded: ({ isLastFrame, frameBuffer }) => { - // console.log('录音返回', frameBuffer); - const data = ProtocolCodec.pack(MessageType.AUDIO_DATA, frameBuffer) - // console.log('录音返回', data); - send(data) - // try { - // ws.value.send({ - // data: ProtocolCodec.pack(MessageType.AUDIO_DATA, frameBuffer) - // }); - // } catch (e) {} - }, - onDecibels: (decibels) => { - // this.currentDecibels = decibels; - } - }); - // this.isRecording = true; - // this.status = '录音中...'; - // isRecording.value = true; - - }; - - // ==================== 核心方法:停止录音 ==================== - const stopRecord = () => { - // if (!isRecording.value) return; - - // try { - // if (isH5) { - // mediaRecorder.value?.stop(); - // } else if (isMiniProgram || platform === 'app-plus') { - // recorderManager.value?.stop(); - // } - // isRecording.value = false; - // clearInterval(timer.value); - // } catch (err) { - // finalOptions.onError(`停止录音失败:${err.message}`); - // } - }; - - // ==================== 资源清理 ==================== - const cleanup = () => { - // stopRecord(); - // // H5端额外清理 - // if (isH5) { - // if (mediaRecorder.value) mediaRecorder.value = null; - // if (audioContext.value) audioContext.value.close(); - // // 释放Blob URL - // if (recordResult.value?.url) { - // URL.revokeObjectURL(recordResult.value.url); - // } - // } - // // 小程序/APP端清理 - // if (recorderManager.value) recorderManager.value = null; - }; - - // 组件卸载时自动清理 - // onUnmounted(() => { - // cleanup(); - // }); - - // 监听最大时长,自动停止 - // watch( - // () => recordTime.value, - // (val) => { - // if (val >= finalOptions.duration) { - // stopRecord(); - // } - // } - // ); - - // 返回控制方法+状态 - return { - - isRecording, - renderJSModule, - startRecording, - recordFrame - }; -}; \ No newline at end of file diff --git a/src/pages/sparring/js/useSpeaker.js b/src/pages/sparring/js/useSpeaker.js deleted file mode 100644 index 568ca088..00000000 --- a/src/pages/sparring/js/useSpeaker.js +++ /dev/null @@ -1,129 +0,0 @@ -import { - ref, - onUnmounted, - watch -} from 'vue'; - -/** - * 扬声器管理Hook(音频输出) - * @param {Object} options - 播放配置 - * @param {number} options.sampleRate - 播放采样率(默认16000,需与音频源一致) - * @param {number} options.volume - 初始音量(0~1,默认1) - * @param {boolean} options.autoPlay - 是否自动播放(默认false,需用户交互触发) - * @param {Function} options.onPlay - 播放开始回调 - * @param {Function} options.onError - 播放错误回调 - * @returns {Object} 播放控制方法+状态 - */ -export const useSpeaker = (options = {}) => { - // 默认配置 - const defaultOptions = { - sampleRate: 16000, - volume: 1.0, - autoPlay: false, - onPlay: () => {}, - onError: (err) => console.error('扬声器播放错误:', err) - }; - const finalOptions = { - ...defaultOptions, - ...options - }; - - // 响应式状态 - const isPlaying = ref(false); // 是否正在播放 - const volume = ref(finalOptions.volume); // 播放音量(0~1) - const audioContext = ref(null); // 音频播放上下文(H5) - const audioBufferSource = ref(null); // 音频缓冲源(播放PCM流) - const audioElement = ref(null); // 音频元素(播放文件/URL) - const playQueue = ref([]); // 音频数据播放队列(适配实时流) - - // 平台判断 - const isH5 = uni.getSystemInfoSync().platform === 'h5'; - - // ==================== 初始化播放上下文 ==================== - const initAudioContext = () => { - - }; - - // ==================== 核心方法:播放PCM音频流(实时) ==================== - /** - * 播放PCM音频数据(适配WebSocket传输的实时流) - * @param {ArrayBuffer} pcmData - PCM音频数据(16位单声道) - */ - const playPCM = (pcmData) => { - - - - }; - - // ==================== 控制方法:暂停/停止/调节音量 ==================== - const pausePlay = () => { - if (!isPlaying.value) return; - - if (isH5) { - if (audioBufferSource.value) { - audioBufferSource.value.stop(); - audioBufferSource.value = null; - } - audioElement.value?.pause(); - } else { - uni.createInnerAudioContext().pause(); - } - isPlaying.value = false; - }; - - const stopPlay = () => { - pausePlay(); - playQueue.value = []; // 清空播放队列 - if (audioContext.value) { - audioContext.value.close().then(() => { - audioContext.value = null; - }); - } - audioElement.value = null; - }; - - const setVolume = (val) => { - if (val < 0) val = 0; - if (val > 1) val = 1; - volume.value = val; - - if (isH5) { - audioContext.value?.destination.setVolume(val); - audioElement.value.volume = val; - } else { - uni.createInnerAudioContext().volume = val; - } - }; - - // ==================== 资源清理 ==================== - const cleanup = () => { - stopPlay(); - isPlaying.value = false; - volume.value = finalOptions.volume; - playQueue.value = []; - }; - - // 组件卸载时自动清理 - onUnmounted(() => { - cleanup(); - }); - - // 监听音量变化,同步更新 - watch(volume, (newVal) => { - setVolume(newVal); - }); - - // 返回控制方法+状态 - return { - // 响应式状态 - isPlaying, // 是否正在播放 - volume, // 当前音量(0~1) - // 核心方法 - playPCM, // 播放实时PCM音频流(适配WebSocket) - playAudio, // 播放音频文件/URL - pausePlay, // 暂停播放 - stopPlay, // 停止播放 - setVolume, // 调节音量(0~1) - cleanup // 手动清理资源 - }; -}; \ No newline at end of file diff --git a/src/pages/sparring/talk.vue b/src/pages/sparring/talk.vue index e6c4e677..d2d07257 100644 --- a/src/pages/sparring/talk.vue +++ b/src/pages/sparring/talk.vue @@ -1,11 +1,13 @@