x
This commit is contained in:
+12
-5
@@ -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
+254
-254
@@ -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);
|
||||
})();
|
||||
|
||||
+2047
-52
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user