跳转到内容

@ottervoice/runtime-react-native

React Native Runtime 不硬依赖 Expo 包:由你注入录音 / 播音原语,便于测试与 Expo Go。

import { createExpoRuntime } from '@ottervoice/runtime-react-native';
const runtime = createExpoRuntime({
input: {
requestPermission: () => /* requestRecordingPermissionsAsync */,
createPcmStream: (options, onBuffer) => /* useAudioStream bridge */,
},
output: {
createSound: (uri) => /* createAudioPlayer */,
createPcmPlaylist: () => /* AudioPlaylist */,
writePcmChunk: (input) => /* PCM16 → temp WAV URI */,
deleteAudioFile: (uri) => /* cleanup */,
},
});

完整绑定见 examples/react-native-expo/src/expo-adapters.ts

字段 说明
input 必填,见 ExpoAudioInputOptions
output 必填,见 ExpoAudioOutputOptions

network 适配器:Provider 使用 React Native 的全局 fetch / WebSocket

字段 说明
createPcmStream 推荐:原生 PCM mic(Expo SDK 57 useAudioStream 可包装)
requestPermission 麦克风权限
createRecording / readAudioFile 旧版整文件录音路径;全双工场景优先 PCM
now 测试时钟

推荐 16 kHz · mono · PCM16。Chunk 可设 delivery: 'stream' | 'turn':流式 ASR 吃小缓冲;batch / Audio LLM 吃整轮 WAV。

字段 说明
createSound URI → 可播放 sound
createPcmPlaylist 无缝 PCM 播放列表(流式回复)
writePcmChunk 单段 PCM16 → 临时 WAV URI
writeAudioFile / deleteAudioFile 整段缓冲落盘与清理

createSound 的状态桥接必须转发原生 playing 字段。播放生命周期提供两个不同信号:

runtime.audioOutput.onPlaybackRequested(() => {
// 已准备好音频,即将调用原生 play/playAsync;后续仍可能失败或取消。
});
runtime.audioOutput.onStart(() => {
// 原生 sound/playlist 首次报告 playing: true;暂停恢复不会重复触发。
});

整段音频与流式 PCM 都遵循相同顺序:onPlaybackRequestedonStartonEnd。如果播放在出声前失败或取消,只会收到第一个信号。

start() / stop() 可以安全地跨 React Native 生命周期并发调用。若原生麦克风、 sound 或 playlist 在 stop() 之后才完成初始化,Runtime 会立即停止 / 销毁该对象, 不会在 App 进入后台后恢复采集或播放。writeAudioFilewritePcmChunk 生成的 临时文件会通过 deleteAudioFile 在完成、取消和失败路径尽力清理。

助手播放期间可暂停编码采集,但保留音量回调,以便检测真实 barge-in。

示例:examples/react-native-expo。类型详情:API 参考