Files
aistream-test/测试流式传输uniapp/unpackage/dist/dev/app-plus/app-service.js
T
2025-12-01 21:00:54 +08:00

445 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
Promise.prototype.finally = function(callback) {
const promise = this.constructor;
return this.then(
(value) => promise.resolve(callback()).then(() => value),
(reason) => promise.resolve(callback()).then(() => {
throw reason;
})
);
};
}
;
if (typeof uni !== "undefined" && uni && uni.requireGlobal) {
const global = uni.requireGlobal();
ArrayBuffer = global.ArrayBuffer;
Int8Array = global.Int8Array;
Uint8Array = global.Uint8Array;
Uint8ClampedArray = global.Uint8ClampedArray;
Int16Array = global.Int16Array;
Uint16Array = global.Uint16Array;
Int32Array = global.Int32Array;
Uint32Array = global.Uint32Array;
Float32Array = global.Float32Array;
Float64Array = global.Float64Array;
BigInt64Array = global.BigInt64Array;
BigUint64Array = global.BigUint64Array;
}
;
if (uni.restoreGlobal) {
uni.restoreGlobal(Vue, weex, plus, setTimeout, clearTimeout, setInterval, clearInterval);
}
(function(vue) {
"use strict";
function formatAppLog(type, filename, ...args) {
if (uni.__log__) {
uni.__log__(type, filename, ...args);
} else {
console[type].apply(console, [...args, filename]);
}
}
function resolveEasycom(component, easycom) {
return typeof component === "string" ? easycom : component;
}
const block0$1 = (Comp) => {
(Comp.$renderjs || (Comp.$renderjs = [])).push("record");
(Comp.$renderjsModules || (Comp.$renderjsModules = {}))["record"] = "1e54c19a";
};
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _sfc_main$3 = {
data() {
return {
options: null,
status: null,
onFrameRecorded: () => {
},
onDecibels: () => {
}
};
},
methods: {
start(option) {
this.options = option;
this.status = "start";
if (option.onFrameRecorded && typeof option.onFrameRecorded === "function") {
this.onFrameRecorded = option.onFrameRecorded;
}
if (option.onDecibels && typeof option.onDecibels === "function") {
this.onDecibels = option.onDecibels;
}
},
stop() {
this.status = "stop";
this.options = null;
},
frameRecorded({
isLastFrame,
frameBuffer
}) {
this.onFrameRecorded({
isLastFrame,
frameBuffer: this.base64ToUint8Array(frameBuffer)
});
},
decibels(value) {
this.onDecibels(value);
},
base64ToUint8Array(base64) {
const binaryString = atob(base64.split(",")[1] || base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
},
toShowToast() {
uni.showToast({
title: "发生错误,请检查是否有麦克风权限",
icon: "none"
});
this.stop();
},
recordedChunks(base64) {
this.$emit("onStop", base64);
}
}
};
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock("view", {
options: vue.wp($data.options),
"change:options": _ctx.record.startRecord,
status: vue.wp($data.status),
"change:status": _ctx.record.onStop
}, null, 8, ["options", "change:options", "status", "change:status"]);
}
if (typeof block0$1 === "function")
block0$1(_sfc_main$3);
const __easycom_0 = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2], ["__file", "C:/Users/1/Desktop/testAudio/测试流式传输uniapp/uni_modules/yao-RecordFrame/components/yao-RecordFrame/yao-RecordFrame.vue"]]);
const block0 = (Comp) => {
(Comp.$renderjs || (Comp.$renderjs = [])).push("renderJS");
(Comp.$renderjsModules || (Comp.$renderjsModules = {}))["renderJS"] = "5f91482f";
};
const _sfc_main$2 = {
data() {
return {
currBuffer: null,
isStop: false,
isStreamPlaying: false
};
},
methods: {
connect() {
this.ws = uni.connectSocket({
url: "ws://172.16.89.58:8000/ws/audio",
complete: () => {
formatAppLog("log", "at uni_modules/sdx-StreamPlayer/components/sdx-StreamPlayer/sdx-StreamPlayer.vue:27", "complete");
},
success: () => {
formatAppLog("log", "at uni_modules/sdx-StreamPlayer/components/sdx-StreamPlayer/sdx-StreamPlayer.vue:30", "web");
this.ws.onOpen((res) => {
formatAppLog("log", "at uni_modules/sdx-StreamPlayer/components/sdx-StreamPlayer/sdx-StreamPlayer.vue:32", "WebSocket连接已打开", res);
this.ws.onMessage((res2) => {
let messageData = res2.data;
if (typeof messageData === "string") {
try {
const parsedData = JSON.parse(messageData);
this.handleMessage(parsedData);
} catch (e) {
this.handleMessage(messageData);
}
} else if (messageData instanceof ArrayBuffer) {
this.isStreamPlaying = true;
this.currBuffer = uni.arrayBufferToBase64(messageData);
}
});
});
}
});
},
end() {
this.isStop = !this.isStop;
},
changeStreamPlaying(e) {
this.isStreamPlaying = e.type;
},
appendBuffer(messageData) {
this.isStreamPlaying = true;
this.currBuffer = uni.arrayBufferToBase64(messageData);
}
}
};
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createElementVNode("button", {
type: "default",
onClick: _cache[0] || (_cache[0] = (...args) => $options.connect && $options.connect(...args))
}, "播放音频"),
vue.createElementVNode("button", {
type: "default",
onClick: _cache[1] || (_cache[1] = (...args) => $options.end && $options.end(...args))
}, "结束播放"),
vue.createCommentVNode(" 逻辑层和renderjs的交互需要通过这种方式传递数据,具体看文档 "),
vue.createElementVNode("view", {
isStop: vue.wp($data.isStop),
"change:isStop": _ctx.renderJS.stop,
prop: vue.wp($data.currBuffer),
"change:prop": _ctx.renderJS.playTTS,
type: "renderjs",
module: "renderJS"
}, null, 8, ["isStop", "change:isStop", "prop", "change:prop"])
],
64
/* STABLE_FRAGMENT */
);
}
if (typeof block0 === "function")
block0(_sfc_main$2);
const __easycom_1 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1], ["__file", "C:/Users/1/Desktop/testAudio/测试流式传输uniapp/uni_modules/sdx-StreamPlayer/components/sdx-StreamPlayer/sdx-StreamPlayer.vue"]]);
const _sfc_main$1 = {
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) {
formatAppLog("error", "at pages/index/index.vue:51", "申请权限失败:", e);
return false;
}
},
// ArrayBuffer 转字符串
// 兼容的 ArrayBuffer 转字符串方法
arrayBufferToStringCompat(buffer) {
const uint8Array = new Uint8Array(buffer);
let str = "";
for (let i = 0; i < uint8Array.length; i++) {
str += String.fromCharCode(uint8Array[i]);
}
return str;
},
// 开始录音
async onStartRecord() {
this.ws = uni.connectSocket({
url: this.wsUrl,
//仅为示例,并非真实接口地址。
complete: () => {
formatAppLog("log", "at pages/index/index.vue:77", "complete");
},
success: () => {
formatAppLog("log", "at pages/index/index.vue:80", "web");
this.ws.onOpen((res) => {
formatAppLog("log", "at pages/index/index.vue:82", "WebSocket连接已打开", res);
this.ws.onMessage((res2) => {
let messageData = res2.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);
} catch (e) {
formatAppLog("log", "at pages/index/index.vue:104", "二进制数据解析失败:", e);
}
}
});
});
},
fail: () => {
formatAppLog("log", "at pages/index/index.vue:111", "fail");
}
});
try {
this.$refs.recordFrame.start({
sampleRate: 16e3,
frameSize: 1024,
gain: 1,
onFrameRecorded: ({
isLastFrame,
frameBuffer
}) => {
this.ws.send({
data: frameBuffer
});
},
onDecibels: (decibels) => {
this.currentDecibels = decibels;
}
});
this.isRecording = true;
this.status = "录音中...";
} catch (e) {
formatAppLog("error", "at pages/index/index.vue:142", "启动录音失败:", e);
this.status = "启动录音失败";
this.isRecording = false;
}
},
// 停止录音
onStopRecord() {
this.stopRecordAndClean();
},
// 停止录音并清理资源
stopRecordAndClean() {
if (this.isRecording) {
this.$refs.recordFrame.stop();
this.isRecording = false;
this.status = "已停止录音";
}
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
}) {
if (this.ws) {
try {
this.ws.send({
data: frameBuffer
});
} catch (e) {
formatAppLog("error", "at pages/index/index.vue:194", "发送音频帧失败:", e);
}
}
},
// 监听分贝值
onCurrentDecibels(decibels) {
},
// 录音停止回调
stopIt(base64) {
this.stopRecordAndClean();
formatAppLog("log", "at pages/index/index.vue:210", "录音停止,最终音频Base64", (base64 == null ? void 0 : base64.substring(0, 50)) + "...");
}
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_yao_RecordFrame = resolveEasycom(vue.resolveDynamicComponent("yao-RecordFrame"), __easycom_0);
const _component_sdx_StreamPlayer = resolveEasycom(vue.resolveDynamicComponent("sdx-StreamPlayer"), __easycom_1);
return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [
vue.createElementVNode("button", {
onClick: _cache[0] || (_cache[0] = (...args) => $options.onStartRecord && $options.onStartRecord(...args)),
disabled: $data.isRecording
}, "开始录音", 8, ["disabled"]),
vue.createElementVNode("button", {
onClick: _cache[1] || (_cache[1] = (...args) => $options.onStopRecord && $options.onStopRecord(...args)),
disabled: !$data.isRecording
}, "停止录音", 8, ["disabled"]),
vue.createElementVNode(
"view",
{ class: "tip" },
vue.toDisplayString($data.status),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "tip" },
"当前分贝:" + vue.toDisplayString($data.currentDecibels),
1
/* TEXT */
),
vue.createVNode(_component_yao_RecordFrame, {
ref: "recordFrame",
onOnFrameRecorded: $options.frameRecorded,
onCurrentDecibels: $options.onCurrentDecibels,
onOnStop: $options.stopIt
}, null, 8, ["onOnFrameRecorded", "onCurrentDecibels", "onOnStop"]),
vue.createVNode(
_component_sdx_StreamPlayer,
{ ref: "aaa" },
{
default: vue.withCtx(() => [
vue.createTextVNode("xx")
]),
_: 1
/* STABLE */
},
512
/* NEED_PATCH */
)
]);
}
const PagesIndexIndex = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__scopeId", "data-v-1cf27b2a"], ["__file", "C:/Users/1/Desktop/testAudio/测试流式传输uniapp/pages/index/index.vue"]]);
__definePage("pages/index/index", PagesIndexIndex);
const _sfc_main = {
onLaunch: function() {
formatAppLog("log", "at App.vue:4", "App Launch");
},
onShow: function() {
formatAppLog("log", "at App.vue:7", "App Show");
},
onHide: function() {
formatAppLog("log", "at App.vue:10", "App Hide");
}
};
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "C:/Users/1/Desktop/testAudio/测试流式传输uniapp/App.vue"]]);
function createApp() {
const app = vue.createVueApp(App);
return {
app
};
}
const { app: __app__, Vuex: __Vuex__, Pinia: __Pinia__ } = createApp();
uni.Vuex = __Vuex__;
uni.Pinia = __Pinia__;
__app__.provide("__globalStyles", __uniConfig.styles);
__app__._component.mpType = "app";
__app__._component.render = () => {
};
__app__.mount("#app");
})(Vue);