audio_recorder
麦克风录音、暂停继续和电平监测。
麦克风录音:把音频保存为 .m4a、.caf 或 .wav 文件。
边界:输出文件保存在 App Documents 目录。需要麦克风系统授权;统一 permission 的request("microphone")暂不支持弹窗,首次录音时系统可能提示,或在设置中开启。录音只能放在用户操作回调里,不要在body()中调用。
#模块概览
| 项 | 说明 |
|---|---|
| 导入 | import audio_recorder |
| 适合做什么 | 语音备忘、口述笔记、采集音频片段 |
| 调用时机 | start() / stop() 放在按钮回调 |
| 推荐顺序 | start() → 轮询 status() → stop() 拿文件信息 |
| 有状态 | 支持 pause() / resume() / cancel() 丢弃半成品 |
#快速开始
下面脚本开始录音、等待几秒后停止并打印文件信息:
已复制
import time
import audio_recorder
try:
path = audio_recorder.start()
print("录音中:", path)
time.sleep(3)
info = audio_recorder.stop()
if info:
print("已保存:", info["path"])
print("时长:", info["duration"], "秒")
print("大小:", info["size"], "字节")
except audio_recorder.AudioRecorderError as exc:
print("录音失败:", exc, f"code={exc.code}")
#AppUI 示例
开始/停止放在按钮回调;用 Timer 轮询电平与时长。
已复制
import appui
import audio_recorder
state = appui.State(
recording=False,
path="",
level=0.0,
seconds=0.0,
status="点击开始录音",
)
def tick():
if not state.recording:
return
st = audio_recorder.status()
state.level = float(st.get("average_power", 0.0))
state.seconds = float(st.get("duration", 0.0))
poll_timer = appui.Timer(interval=0.1, repeats=True, action=tick)
def toggle_recording():
if state.recording:
poll_timer.stop()
info = audio_recorder.stop() or {}
state.batch_update(
recording=False,
path=info.get("path", ""),
status=f"已保存 · {info.get('duration', 0):.1f}s",
)
return
try:
path = audio_recorder.start()
state.batch_update(
recording=True,
path=path or "",
status="录音中…",
)
poll_timer.start()
except audio_recorder.AudioRecorderError as exc:
state.status = f"无法开始: {exc}(请检查麦克风权限)"
def cancel_recording():
if not state.recording:
return
poll_timer.stop()
audio_recorder.cancel()
state.batch_update(
recording=False,
path="",
seconds=0.0,
status="已取消并删除临时文件",
)
def body():
label = "停止录音" if state.recording else "开始录音"
return appui.NavigationStack(
appui.Form([
appui.Section("录音", [
appui.LabeledContent("状态", value=state.status),
appui.LabeledContent(
"电平",
value=f"{state.seconds:.1f}s · {state.level:.0f} dB",
),
appui.Text(state.path).font("caption").foreground_color("secondaryLabel"),
]),
appui.Section("操作", [
appui.Button(label, action=toggle_recording)
.button_style("bordered_prominent"),
appui.Button("取消录音", action=cancel_recording, role="destructive"),
], footer="真机测试最可靠;需麦克风权限。"),
]).navigation_title("录音")
)
appui.run(body, state=state)
#API 参考
#速查
| API | 作用 |
|---|---|
start(path, format, ...) | 开始录音 → 文件路径 |
stop() | 停止 → {path, duration, size, format} |
pause() / resume() | 暂停 / 继续 |
cancel() | 停止并删除半成品 |
status() | 状态与电平 |
is_recording() / duration() | 是否录音中 / 已录秒数 |
metering() | {average, peak} 电平(dBFS) |
#录音控制
start(path=None, format="m4a", quality="high", sample_rate=44100, channels=1)
已复制
path = audio_recorder.start()
path = audio_recorder.start(format="wav", quality="high", channels=1)
| 参数 | 说明 |
|---|---|
format | m4a(默认 AAC)/ caf / wav |
quality | low / medium / high / max |
sample_rate | 如 44100、48000 |
channels | 1 单声道 / 2 立体声 |
stop() — 返回文件信息字典;未录音时返回 None。
cancel() — 丢弃半成品,不返回结果。
#状态与电平
status() 返回:
| 字段 | 说明 |
|---|---|
recording / paused | 是否录音 / 暂停 |
duration | 已录秒数 |
average_power / peak_power | 电平 dBFS(0 最大,负值更安静) |
path | 当前文件路径 |
已复制
st = audio_recorder.status()
meter = audio_recorder.metering()
轮询建议 ≥ 0.1s 间隔(如 appui.Timer)。
#异常
失败时抛出 AudioRecorderError,常见 code:
code | 含义 |
|---|---|
already_recording | 重复 start() |
start_failed | 无法启动(含权限或会话占用) |
#常见错误
| 错误写法 | 后果 | 修正 |
|---|---|---|
在 body() 里 start() | 刷新时重复录音 | 放进按钮回调 |
把 permission.request() 当 bool | 判断错误且暂不支持 | 用 try/except 处理 start() |
高频轮询 status() | CPU 浪费 | Timer(interval=0.1) |
放弃录音不 cancel() | 留下垃圾文件 | 调用 cancel() |
#相关文档
| 文档 | 用途 |
|---|---|
| speech_recognition | 录音文件转文字 |
| sound | 播放本地音频 |
| permission | 权限状态查询 |
| 原生能力入口 | MiniApp 场景配方 |
#预期效果
运行示例后,界面应出现文档描述的目标结果;若与预期不符,先看「失败路径」并按返回值或日志排查。