OneScript
基础

audio

用麦克风录音到文件,并读取实时电平与录制时长。

audio 通过 AVAudioRecorder 把麦克风声音直接录制到文件。record 返回一个正在录音的 AudioRecording,用 stop 结束;levels 是异步可迭代对象,交付实时电平,可用于电平表和计时显示。音频会话由 OneScript 自动配置,不需要脚本设置。

import { audio } from "onescript";

const recording = await audio.record("memo.m4a");
await new Promise(resolve => setTimeout(resolve, 5_000));
const { path, duration } = await recording.stop();
console.log(path, duration);

类型

interface AudioPermission {
  status: "notDetermined" | "denied" | "authorized";
}

interface AudioRecording {
  readonly path: string;                              // 录音文件的绝对路径
  readonly state: "recording" | "paused" | "ended";
  readonly finished: Promise<AudioRecordingResult>;
  pause(): Promise<void>;
  resume(): Promise<void>;
  stop(): Promise<AudioRecordingResult>;
  levels(options?: { interval?: number; signal?: AbortSignal }): AsyncIterable<AudioLevel>;
}

interface AudioRecordingResult {
  path: string;
  duration: number;                                   // 秒
  reason: "stopped" | "maxDuration" | "interrupted";
}

interface AudioLevel {
  currentTime: number;                                // 已录制秒数,不含暂停
  average: number;                                    // 平均功率(dBFS)
  peak: number;                                       // 峰值功率(dBFS)
  channels: { average: number; peak: number }[];
}

授权

function audio.getPermission(): Promise<AudioPermission>;
function audio.requestPermission(): Promise<AudioPermission>;

record 首次调用时会申请麦克风授权,通常不需要自己申请。需要提前申请时调用 requestPermission;授权已决定时它直接返回当前状态。

status含义
notDetermined尚未询问用户。
denied用户拒绝了麦克风访问。
authorized脚本可以录音。

audio.record

function audio.record(path: string, options?: {
  sampleRate?: number;
  channels?: 1 | 2;
  bitRate?: number;
  maxDuration?: number;
}): Promise<AudioRecording>;

开始录音,Promise 兑现时已经在录音。path 与 fs 相同:相对路径以项目目录为基准,文件已存在时覆盖,父目录必须存在。扩展名决定格式:

扩展名格式
.m4aAAC,体积小,适合语音与分享。
.wav16 位 PCM,无损,适合后续处理。
选项说明
sampleRate采样率(Hz),默认 48000,范围 8000–192000。
channels声道数,默认 1。
bitRateAAC 码率(bit/s),仅 .m4a;默认由编码器决定。
maxDuration最长录制时长(秒,不含暂停),到达后自动结束。
const recording = await audio.record("recordings/interview.m4a", {
  bitRate: 64_000,
  maxDuration: 10 * 60
});
const result = await recording.finished;
console.log(result.reason); // "maxDuration"

同一时刻只能有一个录音,正在录音时再次调用 record 抛出 AUDIO_UNAVAILABLE。

控制录音

pause 暂停录音,resume 继续,已处于目标状态时没有效果。stop 结束录音并完成文件,可以重复调用,总是返回同一结果。

finished 在录音以任何方式结束时兑现,reason 说明原因:

reason含义
stopped调用了 stop。
maxDuration到达 maxDuration。
interrupted被来电、Siri 等打断,或 OneScript 进入后台。

录音被打断时立即结束并保存,文件完整可用;需要继续时再调用一次 record。录音失败时 finished 与 stop 以 AUDIO_RECORDING_FAILED 拒绝。

录音期间脚本保持运行,直到录音结束。脚本结束(或开始录音的 worker 线程结束)时,录音随之结束,已录制的内容保留在文件中,finished 拒绝。

电平

recording.levels(options?: { interval?: number; signal?: AbortSignal }): AsyncIterable<AudioLevel>;

按 interval(毫秒,默认 50,最小 16)采样电平与已录制时长,直到 break、signal 中止或录音结束。电平是当前状态,循环体处理较慢时会跳过中间值,只交付最新的电平。暂停期间不产生电平。

功率单位为 dBFS,范围 -160(静音)到 0(满幅)。average 与 peak 为各声道的均值。换算为 0–1 的线性值:10 ** (db / 20)。

const recording = await audio.record("memo.m4a", { maxDuration: 30 });

for await (const level of recording.levels({ interval: 100 })) {
  const bar = "█".repeat(Math.round(10 ** (level.peak / 20) * 30));
  console.log(level.currentTime.toFixed(1), bar);
}
// 到达 maxDuration 后录音结束,循环随之结束。
console.log(await recording.finished);

可用范围

APIApp操作扩展小组件
getPermission✓✓✓
requestPermission、record✓——

错误

错误带有 code 属性:

code含义
AUDIO_PERMISSION_DENIED麦克风访问被拒绝。
AUDIO_UNAVAILABLE没有可用的输入设备、无法激活音频会话,或已有录音在进行。
AUDIO_CONTEXT_UNAVAILABLE当前环境不支持该操作,例如在小组件中录音。
AUDIO_RECORDING_FAILED录音无法开始,或编码等系统错误导致录音失败。
ENOENT录音文件的父目录不存在。

参数无效(例如不支持的扩展名、.wav 搭配 bitRate)时抛出 TypeError;录音结束后调用 pause 或 resume 抛出 ERR_INVALID_STATE。

How is this guide?

最后更新于

本页目录