iflytek/astron-agent · error
音频buffers被释放
Error message
音频buffers被释放
What it means
Recorder-Core's stop() found recSize > 0 but This.buffers[0] is missing, meaning the accumulated PCM buffer store was cleared (or never held) — typically because buffers were released after a previous stop or clear, or recording state and buffer store got out of sync.
Solutions
- Don't call stop() twice; disable the stop button after the first invocation.
- Only call stop() while the recorder is in a recording state (check rec.state).
- Avoid manually mutating rec.buffers; rely on library APIs (start/stop/close).
- After close(), recreate or re-open the recorder instead of stopping again.
- If streaming with takeoffEncodeChunk, don't also expect stop() to return a full blob.
Example fix
// before
rec.stop();
rec.stop(); // second call: buffers released
// after
var stopped = false;
stopBtn.onclick = function() {
if (stopped || rec.state !== 1) return;
stopped = true;
rec.stop(function(blob) { upload(blob); });
}; Defensive patterns
Strategy: validation
Validate before calling
function canStopSafely(rec) {
return rec && rec.state === 1 && rec.recSize > 0 && rec.buffers && rec.buffers[0];
}
if (!canStopSafely(rec)) return; Type guard
function buffersAvailable(rec) { return Array.isArray(rec.buffers) && rec.buffers.length > 0 && !!rec.buffers[0]; } Try / catch
try { rec.stop(cb); } catch (e) {
if (String(e).includes('音频buffers被释放')) resetRecorder();
} Prevention
- Guard against double stop() invocations with a flag or disabled button.
- Never call stop() after close(); recreate the recorder instead.
- Don't mutate rec.buffers manually.
- Reset UI state (recording flag) immediately after the first stop.
When it happens
Trigger: rec.stop() invoked when recSize is nonzero but This.buffers[0] is undefined/falsy, i.e. the buffer array was emptied (e.g. rec.close() or buffer release happened) while recSize was not reset, or a second stop() raced the first.
Common situations: Double-invoking stop(); calling stop() after close() with stale size counters; using takeoffEncodeChunk where buffers are consumed/streamed and then released; manual buffer manipulation by application code.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/30c3fdeb0941345a.
Report an issue: GitHub.
Appendix: source
Thrown at console/frontend/src/utils/record/recorder-core.js:1387
};
if (!This.isMock) {
var isCtxWait = This.state == 3;
if (!This.state || isCtxWait) {
err(
'未开始录音' +
(isCtxWait ? ',开始录音前无用户交互导致AudioContext未运行' : '')
);
return;
}
This._stop(true);
}
var size = This.recSize;
if (!size) {
err('未采集到录音');
return;
}
if (!This.buffers[0]) {
err('音频buffers被释放');
return;
}
if (!This[set.type]) {
err('未加载' + set.type + '编码器');
return;
}
//环境配置检查,此处仅针对mock调用,因为open已经检查过了
if (This.isMock) {
var checkMsg = This.envCheck(
This.mockEnvInfo || { envName: 'mock', canProcess: false }
); //没有提供环境信息的mock时没有onProcess回调
if (checkMsg) {
err('录音错误:' + checkMsg);
return;
}
}
View on GitHub (pinned to 5e758547a8)