Sanas 如何用 Expo 在 3 个月内打造出一款实时视频翻译应用
Sanas 用 Expo 打造全球首款即时翻译视频通话应用,支持 25 种以上语言并保留说话者语气。
中文
复制

几十年来,工程师们一直梦想造出真正的通用翻译器:让两个说不同语言的人交谈,却能像说同一种语言那样听懂彼此。在 Sanas,我们决心把这个梦想变成现实。
短短几个月里,Sanas 这支小团队就做到了——Sanas 是一家语音 AI 公司,我们用 Expo 打造并上线了全球第一款即时语言翻译视频通话应用。它把先进的大语言模型(LLM)翻译研究与 Expo 的现代移动开发工具结合起来,让实时多语言对话成为可能。

要做成这么一件野心勃勃的事,开发栈必须在灵活性、原生性能和迭代速度之间取得平衡。Expo 正好给了我们这样的基础。统一的开发体验、快速的迭代周期,再加上对原生 API 的访问能力,让我们可以专注于解决 AI 中最具人情味的问题之一:帮人们听懂彼此。
实时、低延迟语音翻译难在哪
实时低延迟语音翻译是通信技术中最难的问题之一。要让人感觉自然,它必须即时采集并传输语音,在通话过程中足够快地完成翻译和音频合成,同时还要保留每位说话者独特的语气和情绪。这一切还得在不可预测的网络条件下正常工作,扩展到 25 种以上的语言,并在移动视频通话中稳定交付。
要在移动视频通话里同时做到这些,就意味着必须一并解决延迟、性能和音质保真三个问题。哪怕几百毫秒的延迟,也会让对话听起来生硬。我们需要一套让用户在 iOS 和 Android 上都觉得毫不费力的系统,也需要一个能让我们每天测试并上线改进的开发框架。

Sanas 为什么选择 Expo
我们团队在斯坦福时就用过 Expo,好几门课程的移动开发都推荐这个框架。我们知道它能让我们快速推进,又不必放弃原生 API。用 Expo,我们可以每天构建、测试、部署,同时对性能关键的组件保持完全控制。
Expo 的统一工具链和集成服务让我们能专注于真正棘手的问题:翻译准确度、延迟和自然度。
-
Expo SDK 54 让我们在保持一致的开发体验的同时,深度接入原生 API。
-
EAS Build 包办了 iOS 和 Android 的 CI/CD,省去了手动配置的麻烦。
-
EAS Update 让我们能通过 OTA 即时向内部测试人员和早期用户推送版本。
把构建、更新和原生配置这些复杂事务交给 Expo 之后,我们得以腾出精力,专注在最重要的事情上:把语音翻译推到极限。
关键 Expo 模块与集成
为了实现即时翻译和流畅沟通,我们围绕一系列 Expo 模块和自定义原生集成来构建应用。
-
expo-audio:音频录制与播放,用于实时采集和语音合成
-
expo-camera:实时视频流和参会者画面控制
-
expo-webrtc(自定义集成):加密的点对点通话层
-
expo-haptics:用细微的触觉反馈提示翻译事件
-
expo-notifications:通话邀请、未接来电提醒和翻译更新
-
expo-secure-store:本地加密存储认证信息和 API 凭据
-
expo-updates:无缝的 OTA 功能发布
-
自定义原生模块:用于 LLM 流式推理和设备端声音克隆
有了这些模块,一支小团队就能做出生产级的产品体验——即时、直观,同时在安全性、音色保真度和翻译速度上都不妥协。
Sanas 应用架构一览
在幕后,应用运行在一套精简的架构上,在边缘智能和设备端效率之间取得平衡。每一层都旨在把延迟压到最低、把保真度提到最高:
-
客户端是一个 React Native + Expo 应用,负责 UI、状态管理以及本地音视频处理。
-
边缘服务器使用经过微调的多语言 LLM,处理低延迟的语音识别、翻译和语音合成。
-
WebRTC 传输负责实时双向通信,并动态调整质量,确保网络状况不佳时依然稳定。
-
EAS Build 和 Update 负责构建自动化、预发布渠道和功能开关,用于 A/B 延迟测试。
通过在设备与边缘之间智能分配计算,我们实现了近乎即时的翻译体验,同时在各个平台上保持一致的性能。
示例:实时流式翻译
构建即时翻译最棘手的部分之一,是在单条连接上以最低延迟协调实时音频采集、转录、翻译和合成语音播放。下面是我们具体的实现方式:
// A single WebSocket handles the entire translation pipeline
ws.onmessage = event => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'ready':
// Server is ready — start streaming audio chunks
LiveAudioStream.on('data', (data: string) => {
ws.send(JSON.stringify({ type: 'audio', data }));
});
LiveAudioStream.start();
break;
case 'transcription':
// Progressive transcription with complete + partial words
const completeText = message.complete.map(w => w.word).join('');
const partialText = message.partial.map(w => w.word).join('');
updateTranscription(completeText, partialText);
break;
case 'translation':
// Full translation arrives after user stops speaking
displayTranslation(message.complete.map(w => w.word).join(''));
break;
case 'speech':
// Streamed TTS audio chunks with character-level timestamps
audioChunks.push(base64ToUint8Array(message.audio));
break;
}
};
这一方案用单个持久 WebSocket 复用转录、翻译和语音合成,让我们免去了分别调用 API 带来的往返开销。用户说话时就能看到文字被转录出来,说完后几乎立刻就能听到翻译结果。
用 Expo 构建的回报
仅用三个月,一支小团队就把想法从原型推到了生产环境,同时上线 App Store 和 Google Play。这款应用目前支持 25 种以上语言,每种语言都能保留说话者自然的语气和身份特征。平均翻译延迟低于 2 秒,体验流畅自然,在各设备上都很原生。
Expo 是实现这一速度的关键。统一的工具链、开源的灵活性,以及基于云的构建系统,给了我们规模化交付所需的一切。我们不必再管理复杂的原生配置,可以把时间集中在改进核心翻译模型和优化实时体验上。
正如我们一位工程师所说:“Expo 让我们能把全部精力放在突破翻译的极限上,而不是配置构建系统。”
Sanas 的下一步是什么?
工作不会止步于此。我们的团队正专注于下一个前沿:让实时翻译更有表现力、更像真人。更多信息请阅读我们的技术文章。
Expo 仍将是这段旅程中的关键一环。它快速、可靠的更新系统让我们每周都能发布模型改进和新功能,把研究突破几乎立刻变成真实的用户体验。
在 Sanas,我们的目标始终很简单:帮助人们理解别人,也被别人理解,无论说的是哪种语言。Expo 帮我们把这一愿景变成现实。