This commit is contained in:
田岩
2025-12-03 20:54:23 +08:00
parent f250b21b38
commit 11ce05edcf
972 changed files with 121839 additions and 824 deletions
@@ -1,8 +1,15 @@
{
"hash": "030e727a",
"configHash": "c22f3258",
"lockfileHash": "c10b225f",
"browserHash": "77dd6173",
"optimized": {},
"hash": "1d959fb8",
"configHash": "0d2436b6",
"lockfileHash": "6ccee1ba",
"browserHash": "2ee35306",
"optimized": {
"text-encoding": {
"src": "../../../../../node_modules/text-encoding/index.js",
"file": "text-encoding.js",
"fileHash": "ad7e1515",
"needsInterop": true
}
},
"chunks": {}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,259 @@
var __renderjsModules={};
__renderjsModules["5f91482f"] = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// <stdin>
var stdin_exports = {};
__export(stdin_exports, {
default: () => stdin_default
});
// C:/Users/1/Desktop/testAudio/测试流式传输uniapp/uni_modules/sdx-StreamPlayer/plugins/StreamPlayer.js
var StreamPlayer = class {
constructor({
inputSampleRate = 16e3,
numChannels = 1,
bitDepth = 16,
littleEndian = true,
pcmType = "int",
callback = () => {
}
} = {}) {
if (![16, 32].includes(bitDepth))
throw new Error("bitDepth \u5FC5\u987B\u662F 16 \u6216 32");
if (inputSampleRate <= 0)
throw new Error("\u91C7\u6837\u7387\u5FC5\u987B\u5927\u4E8E 0");
if (!["int", "float"].includes(pcmType))
throw new Error("pcmType \u5FC5\u987B\u662F int \u6216 float");
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.inputSampleRate = inputSampleRate;
this.numChannels = numChannels;
this.bitDepth = bitDepth;
this.littleEndian = littleEndian;
this.pcmType = pcmType;
this.audioQueue = [];
this.playbackEndTime = 0;
this.currentSource = null;
this.lastBlockTail = null;
this.callback = callback;
}
appendChunk(audioData) {
console.log("this.audioQueue", this.audioQueue.length);
this.audioQueue.push(audioData);
this._processQueue();
}
destroy() {
this.audioQueue = [];
this.playbackEndTime = 0;
if (this.currentSource) {
this.currentSource.stop();
this.currentSource = null;
}
if (this.audioContext) {
this.audioContext.close();
this.audioContext = null;
}
}
_processQueue() {
return __async(this, null, function* () {
if (this.audioQueue.length === 0) {
this.callback("ended");
return;
}
if (!this.audioContext || this.currentSource)
return;
const buffer = this._mergeArrayBuffers(this.audioQueue);
this.audioQueue = [];
try {
const audioBuffer = this._convertPCM(buffer);
yield this._schedulePlay(audioBuffer);
this._processQueue();
} catch (err) {
console.error("\u97F3\u9891\u5904\u7406\u5931\u8D25:", err);
}
});
}
_convertPCM(buffer) {
const bytesPerSample = this.bitDepth / 8;
const requiredBytes = bytesPerSample * this.numChannels;
const validByteLength = Math.floor(buffer.byteLength / requiredBytes) * requiredBytes;
const validBuffer = buffer.slice(0, validByteLength);
const dataView = new DataView(validBuffer);
const numSamples = validByteLength / requiredBytes;
const audioBuffer = this.audioContext.createBuffer(
this.numChannels,
numSamples,
this.inputSampleRate
);
for (let ch = 0; ch < this.numChannels; ch++) {
const channelData = audioBuffer.getChannelData(ch);
for (let i = 0; i < numSamples; i++) {
const pos = i * this.numChannels * bytesPerSample + ch * bytesPerSample;
let value;
if (this.bitDepth === 16) {
value = dataView.getInt16(pos, this.littleEndian) / 32768;
} else {
if (this.pcmType === "int") {
value = dataView.getInt32(pos, this.littleEndian) / 2147483648;
} else {
value = dataView.getFloat32(pos, this.littleEndian);
}
}
channelData[i] = value;
}
let sum = 0;
for (let i = 0; i < channelData.length; i++) {
sum += channelData[i];
}
const dcOffset = sum / channelData.length;
for (let i = 0; i < channelData.length; i++) {
channelData[i] -= dcOffset;
}
const fadeLength = Math.min(100, channelData.length);
for (let i = 0; i < fadeLength; i++) {
channelData[i] *= i / fadeLength;
}
const startFadeOut = Math.max(0, channelData.length - fadeLength);
for (let i = startFadeOut; i < channelData.length; i++) {
const factor = 1 - (i - startFadeOut) / fadeLength;
channelData[i] *= factor;
}
}
const crossfadeLength = 50;
if (this.lastBlockTail && this.lastBlockTail.length === this.numChannels) {
for (let ch = 0; ch < this.numChannels; ch++) {
const channelData = audioBuffer.getChannelData(ch);
const prevTail = this.lastBlockTail[ch];
if (prevTail.length >= crossfadeLength && channelData.length >= crossfadeLength) {
for (let i = 0; i < crossfadeLength; i++) {
const prevWeight = (crossfadeLength - i) / crossfadeLength;
const currWeight = i / crossfadeLength;
channelData[i] = channelData[i] * currWeight + prevTail[i] * prevWeight;
}
}
}
}
this.lastBlockTail = [];
for (let ch = 0; ch < this.numChannels; ch++) {
const channelData = audioBuffer.getChannelData(ch);
const tailStart = Math.max(0, channelData.length - crossfadeLength);
this.lastBlockTail[ch] = channelData.slice(tailStart);
}
return audioBuffer;
}
_schedulePlay(audioBuffer) {
return new Promise((resolve) => {
const source = this.audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(this.audioContext.destination);
const plannedStartTime = this.playbackEndTime;
const now = this.audioContext.currentTime;
let startTime = Math.max(plannedStartTime, now);
const timeDrift = plannedStartTime - now;
if (timeDrift < -0.02) {
source.playbackRate.value = Math.min(1.04, 1 - timeDrift / audioBuffer.duration);
} else if (timeDrift > 0.02) {
source.playbackRate.value = Math.max(0.96, 1 - timeDrift / audioBuffer.duration);
} else {
source.playbackRate.value = 1;
}
source.start(startTime);
this.playbackEndTime = startTime + audioBuffer.duration / source.playbackRate.value;
source.onended = () => {
this.currentSource = null;
resolve();
};
this.currentSource = source;
});
}
// 合并多个 ArrayBuffer 的辅助函数
_mergeArrayBuffers(buffers) {
let totalLength = 0;
for (let buffer of buffers) {
totalLength += buffer.byteLength;
}
const result = new Uint8Array(totalLength);
let offset = 0;
for (let buffer of buffers) {
const view = new Uint8Array(buffer);
result.set(view, offset);
offset += view.length;
}
return result.buffer;
}
};
// <stdin>
var player = null;
var stdin_default = {
mounted() {
const _this = this;
player = new StreamPlayer({ callback: _this.callback });
},
methods: {
playTTS(base64) {
console.log("base64", base64);
if (!base64)
return;
const binaryStr = atob(base64);
const bytes = new Uint8Array(binaryStr.length);
for (let i = 0; i < binaryStr.length; i++) {
bytes[i] = binaryStr.charCodeAt(i);
}
player.appendChunk(bytes.buffer);
},
stop() {
player && player.destroy();
player = null;
},
callback(e) {
if (e === "ended") {
this.$ownerInstance.callMethod("changeStreamPlaying", { type: false });
}
}
}
};
return __toCommonJS(stdin_exports);
})();
__renderjsModules["1e54c19a"] = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -266,257 +520,3 @@ __renderjsModules["1e54c19a"] = (() => {
};
return __toCommonJS(stdin_exports);
})();
__renderjsModules["5f91482f"] = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// <stdin>
var stdin_exports = {};
__export(stdin_exports, {
default: () => stdin_default
});
// C:/Users/1/Desktop/testAudio/测试流式传输uniapp/uni_modules/sdx-StreamPlayer/plugins/StreamPlayer.js
var StreamPlayer = class {
constructor({
inputSampleRate = 16e3,
numChannels = 1,
bitDepth = 16,
littleEndian = true,
pcmType = "int",
callback = () => {
}
} = {}) {
if (![16, 32].includes(bitDepth))
throw new Error("bitDepth \u5FC5\u987B\u662F 16 \u6216 32");
if (inputSampleRate <= 0)
throw new Error("\u91C7\u6837\u7387\u5FC5\u987B\u5927\u4E8E 0");
if (!["int", "float"].includes(pcmType))
throw new Error("pcmType \u5FC5\u987B\u662F int \u6216 float");
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.inputSampleRate = inputSampleRate;
this.numChannels = numChannels;
this.bitDepth = bitDepth;
this.littleEndian = littleEndian;
this.pcmType = pcmType;
this.audioQueue = [];
this.playbackEndTime = 0;
this.currentSource = null;
this.lastBlockTail = null;
this.callback = callback;
}
appendChunk(audioData) {
console.log("this.audioQueue", this.audioQueue.length);
this.audioQueue.push(audioData);
this._processQueue();
}
destroy() {
this.audioQueue = [];
this.playbackEndTime = 0;
if (this.currentSource) {
this.currentSource.stop();
this.currentSource = null;
}
if (this.audioContext) {
this.audioContext.close();
this.audioContext = null;
}
}
_processQueue() {
return __async(this, null, function* () {
if (this.audioQueue.length === 0) {
this.callback("ended");
return;
}
if (!this.audioContext || this.currentSource)
return;
const buffer = this._mergeArrayBuffers(this.audioQueue);
this.audioQueue = [];
try {
const audioBuffer = this._convertPCM(buffer);
yield this._schedulePlay(audioBuffer);
this._processQueue();
} catch (err) {
console.error("\u97F3\u9891\u5904\u7406\u5931\u8D25:", err);
}
});
}
_convertPCM(buffer) {
const bytesPerSample = this.bitDepth / 8;
const requiredBytes = bytesPerSample * this.numChannels;
const validByteLength = Math.floor(buffer.byteLength / requiredBytes) * requiredBytes;
const validBuffer = buffer.slice(0, validByteLength);
const dataView = new DataView(validBuffer);
const numSamples = validByteLength / requiredBytes;
const audioBuffer = this.audioContext.createBuffer(
this.numChannels,
numSamples,
this.inputSampleRate
);
for (let ch = 0; ch < this.numChannels; ch++) {
const channelData = audioBuffer.getChannelData(ch);
for (let i = 0; i < numSamples; i++) {
const pos = i * this.numChannels * bytesPerSample + ch * bytesPerSample;
let value;
if (this.bitDepth === 16) {
value = dataView.getInt16(pos, this.littleEndian) / 32768;
} else {
if (this.pcmType === "int") {
value = dataView.getInt32(pos, this.littleEndian) / 2147483648;
} else {
value = dataView.getFloat32(pos, this.littleEndian);
}
}
channelData[i] = value;
}
let sum = 0;
for (let i = 0; i < channelData.length; i++) {
sum += channelData[i];
}
const dcOffset = sum / channelData.length;
for (let i = 0; i < channelData.length; i++) {
channelData[i] -= dcOffset;
}
const fadeLength = Math.min(100, channelData.length);
for (let i = 0; i < fadeLength; i++) {
channelData[i] *= i / fadeLength;
}
const startFadeOut = Math.max(0, channelData.length - fadeLength);
for (let i = startFadeOut; i < channelData.length; i++) {
const factor = 1 - (i - startFadeOut) / fadeLength;
channelData[i] *= factor;
}
}
const crossfadeLength = 50;
if (this.lastBlockTail && this.lastBlockTail.length === this.numChannels) {
for (let ch = 0; ch < this.numChannels; ch++) {
const channelData = audioBuffer.getChannelData(ch);
const prevTail = this.lastBlockTail[ch];
if (prevTail.length >= crossfadeLength && channelData.length >= crossfadeLength) {
for (let i = 0; i < crossfadeLength; i++) {
const prevWeight = (crossfadeLength - i) / crossfadeLength;
const currWeight = i / crossfadeLength;
channelData[i] = channelData[i] * currWeight + prevTail[i] * prevWeight;
}
}
}
}
this.lastBlockTail = [];
for (let ch = 0; ch < this.numChannels; ch++) {
const channelData = audioBuffer.getChannelData(ch);
const tailStart = Math.max(0, channelData.length - crossfadeLength);
this.lastBlockTail[ch] = channelData.slice(tailStart);
}
return audioBuffer;
}
_schedulePlay(audioBuffer) {
return new Promise((resolve) => {
const source = this.audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(this.audioContext.destination);
const plannedStartTime = this.playbackEndTime;
const now = this.audioContext.currentTime;
let startTime = Math.max(plannedStartTime, now);
const timeDrift = plannedStartTime - now;
if (timeDrift < -0.02) {
source.playbackRate.value = Math.min(1.04, 1 - timeDrift / audioBuffer.duration);
} else if (timeDrift > 0.02) {
source.playbackRate.value = Math.max(0.96, 1 - timeDrift / audioBuffer.duration);
} else {
source.playbackRate.value = 1;
}
source.start(startTime);
this.playbackEndTime = startTime + audioBuffer.duration / source.playbackRate.value;
source.onended = () => {
this.currentSource = null;
resolve();
};
this.currentSource = source;
});
}
// 合并多个 ArrayBuffer 的辅助函数
_mergeArrayBuffers(buffers) {
let totalLength = 0;
for (let buffer of buffers) {
totalLength += buffer.byteLength;
}
const result = new Uint8Array(totalLength);
let offset = 0;
for (let buffer of buffers) {
const view = new Uint8Array(buffer);
result.set(view, offset);
offset += view.length;
}
return result.buffer;
}
};
// <stdin>
var player = null;
var stdin_default = {
mounted() {
const _this = this;
player = new StreamPlayer({ callback: _this.callback });
},
methods: {
playTTS(base64) {
console.log("base64", base64);
if (!base64)
return;
const binaryStr = atob(base64);
const bytes = new Uint8Array(binaryStr.length);
for (let i = 0; i < binaryStr.length; i++) {
bytes[i] = binaryStr.charCodeAt(i);
}
player.appendChunk(bytes.buffer);
},
stop() {
player && player.destroy();
player = null;
},
callback(e) {
if (e === "ended") {
this.$ownerInstance.callMethod("changeStreamPlaying", { type: false });
}
}
}
};
return __toCommonJS(stdin_exports);
})();
File diff suppressed because one or more lines are too long