GenAI Speech Recognition API

在机器学习套件的 GenAI 语音识别 API 中,您可以将音频内容转写为文本。此 API 支持以下模式:

  • 高级:语音识别 API 使用 GenAI 模型,该模型可提供更广泛的语言覆盖范围和更好的整体质量。您无需为每种语言下载单独的语言包,从而节省存储空间。
  • 基本:Speech Recognition API 使用传统的设备端语音识别模型,类似于 SpeechRecognizer API。

Speech Recognition API 可将音频内容转写为相同语言的文本。如需将音频转写为其他语言的文本,请使用 Speech Translation API。

主要功能

  • 捕获来自麦克风或音频文件的流式输入。
  • 使用 AudioSource.fromFile() 或 AudioSource.fromUri() 方法转写整个预录制文件。如需了解详情,请参阅音频输入要求。
  • 对于流式输入,提供每个识别出的字词的确切开始时间,以帮助您同步界面动画、生成字幕或在字词被说出时突出显示。每个识别出的字词的开始时间(以毫秒为单位)是相对于事件开始时间(即时间戳 0)的偏移量。
  • 转录文本以连续流的形式提供,最初可能不完整(且可能会发生变化),然后才会成为最终识别的文本。

示例结果

音频 模式 语言区域 转录
audio_2 高级 es-ES "Este es un mensaje corto."
audio_1 基本 en-US “这是一条简短消息”

与平台语音识别 API 相比

使用基本模式时,ML Kit Speech Recognition API 涵盖了平台 SpeechRecognizer API 的基本功能。机器学习套件的一大优势在于,它不绑定到特定平台版本。

此外,机器学习套件 语音识别 API 在使用高级模式时支持使用设备端 Gemini 模型进行语音识别,从而提供更广泛的语言覆盖范围。

开始使用

在 build.gradle 配置中将 ML Kit Speech Recognition API 添加为依赖项:

implementation("com.google.mlkit:genai-speech-recognition:1.0.0-alpha1")

如需将 Speech Recognition API 集成到您的应用中,请创建一个 SpeechRecognizer 客户端。检查必要的设备端模型功能的状态,如果设备上还没有该模型,则下载该模型。在 SpeechRecognizerRequest 中准备好音频输入后,使用客户端运行推理,以从 Kotlin 流接收流式输出。最后,请务必关闭客户端以释放资源。

// 1. Create a SpeechRecognizer with desired options.
val options: SpeechRecognizerOptions =
    speechRecognizerOptions {
        locale = Locale.US
        preferredMode = SpeechRecognizerOptions.Mode.MODE_ADVANCED
    }
val speechRecognizer: SpeechRecognizer = SpeechRecognition.getClient(options)

// 2. Check if the recognition model is available or needs downloading.
launch {
    val status: Int = speechRecognizer.checkStatus()
    if (status == FeatureStatus.DOWNLOADABLE) {
        // 3. If needed, download the model and monitor progress.
        speechRecognizer.download.collect { downloadStatus ->
            when (downloadStatus) {
                is DownloadStatus.DownloadCompleted -> {
                    // Model is ready, start recognition.
                    startMyRecognition(speechRecognizer)
                }
                is DownloadStatus.DownloadFailed -> {
                    // Handle download failure (e.g., inform the user).
                }
                is DownloadStatus.DownloadProgress -> {
                    // Handle download progress (e.g., update a progress bar).
                }
            }
        }
    } else if (status == FeatureStatus.AVAILABLE) {
        // Model is already ready, start recognition immediately.
        startMyRecognition(speechRecognizer)
    } else {
        // Handle other statuses (e.g., DOWNLOADING, UNAVAILABLE).
    }
}

// 4. Define your recognition logic using a suspend function.
suspend fun startMyRecognition(recognizer: SpeechRecognizer) {
    // Create a request (e.g., specifying audio source).
    val request: SpeechRecognizerRequest
        = speechRecognizerRequest { audioSource = AudioSource.fromMic() }
    // Start recognition and process the continuous stream of responses.
    recognizer.startRecognition(request).collect {
        // Process the SpeechRecognitionResponse data here.
    }
}

// 5. Stop recognition and clean up resources when the session is complete.
launch {
    recognizer.stopRecognition()
    recognizer.close()
}

音频输入要求

GenAI Speech Recognition API 支持通过文件描述符从麦克风或自定义来源输入。

如果您使用 AudioSource.fromPfd(parcelFileDescriptor),则输入音频必须满足以下严格要求:

  • 格式:原始、无标头 16 位 PCM。
  • 声道:单声道(单声道)。
  • 采样率:16 kHz。

对于大多数使用场景,建议使用 AudioSource.fromMic(),因为它会自动处理这些限制。

支持的音频输入格式

Speech Recognition API 支持以下音频输入格式:

  • MP3、WAV、FLAC、M4A 和 OGG 文件会在设备上自动解码。
  • 原始、无标头音频(.raw 或 .pcm)必须采用 16 位 PCM、16 kHz、单声道格式。

如果格式无效或不受支持,则在识别开始时会返回 ErrorResponse 值。

实现 Speech Recognition API

以下介绍了如何使用 Speech Recognition API 转写音频并使用字词时间。

转录音频

语音识别 API 支持通过 ParcelFileDescriptor 对象从设备麦克风、预先录制的文件或自定义流水线输入音频。

如需准备音频数据,请使用下表中列出的某个工厂方法构建 AudioSource 对象:

方法 音频模式 推荐的使用场景
AudioSource.fromMic() STREAMING 捕获用户的实时语音输入。

需要 RECORD_AUDIO 权限。
AudioSource.fromFile(file)

AudioSource.fromUri(context, uri)
ONE_SHOT 转写预先录制的音频文件。直接在设备上自动解码标准文件格式。
AudioSource.fromPfd(pfd, mode)

AudioSource.fromPfd(pfd, mode, audioFormat)
STREAMING 或 ONE_SHOT 自定义音频流水线(例如在应用中的其他位置处理的音频数据)。

AudioSource.Mode 常量控制 API 如何处理传入的音频:

  • AudioSource.Mode.STREAMING 常量会将识别器配置为在音频数据到达时持续返回部分和最终转写结果。提供自定义 ParcelFileDescriptor 对象时,您必须以实时速度向数据流写入数据(对于标准 16 kHz、16 位、单声道 PCM 音频,大约为每秒 32,000 字节)。写入数据过快可能会导致缓冲区溢出。
  • AudioSource.Mode.ONE_SHOT 常量会将识别器配置为等待整个音频源传输完毕,然后再执行推理并提供最终转写内容。您可以尽快写入音频数据,但必须关闭文件描述符的写入端,以指示文件结束。在收到此文件结束信号之前,系统不会提供最终转写结果。

以下示例会转写预先录制的音频文件:

suspend fun recognizeFromFile(recognizer: SpeechRecognizer, audioFile: File) {
    val audioSource = AudioSource.fromFile(audioFile)
    val request = speechRecognizerRequest { this.audioSource = audioSource }
    try {
        recognizer.startRecognition(request).collect { response ->
            when (response) {
                is SpeechRecognizerResponse.FinalTextResponse -> {
                    // Process the transcription of the whole file.
                }
                is SpeechRecognizerResponse.ErrorResponse -> {
                    // Handle the error, for example an unsupported audio format.
                }
                else -> {}
            }
        }
    } finally {
        audioSource.close()
    }
}

使用字词时间

您可以在请求的 recognitionOptions 配置块中将 enableWordTiming 参数设置为 true,以请求每个识别出的字词的开始时间。

启用字词时间设置后,每个 SpeechRecognizerResponse.FinalTextResponse 对象都包含一个 wordTimings 属性,其中包含 SpeechRecognizerResponse.WordTiming 对象列表。每个对象都提供识别出的字词字符串 (text) 及其从语音识别会话开始时算起的毫秒偏移量 (timestampMs)。停用字词时间戳(默认设置)后,返回的 wordTimings 列表为空。

以下代码示例演示了如何配置和启用字词时间:

suspend fun recognizeWithWordTiming(recognizer: SpeechRecognizer) {
    val request = speechRecognizerRequest {
        audioSource = AudioSource.fromMic()
        recognitionOptions { enableWordTiming = true }
    }
    recognizer.startRecognition(request).collect { response ->
        if (response is SpeechRecognizerResponse.FinalTextResponse) {
            for (wordTiming in response.wordTimings) {
                val word: String = wordTiming.text
                val timestamp: Long = wordTiming.timestampMs
            }
        }
    }
}

支持的语言

Mode 语言区域
高级 ar-SA(Beta 版)、cmn-Hans-CN、cmn-Hant-TW、da-DK(Beta 版)、de-DE、en-US、es-ES、fr-FR、hi-IN(Beta 版)、id-ID(Beta 版)、it-IT、ja-JP、ko-KR、nl-NL(Beta 版)、pl-PL(Beta 版)、pt-PT、ru-RU、sv-SE(Beta 版)、th-TH、tr-TR(Beta 版)、vi-VN(Beta 版)
基本 cmn-Hans-CN(Beta 版)、cmn-Hant-TW(Beta 版)、de-DE(Beta 版)、en-US、es-ES(Beta 版)、fr-FR(Beta 版)、hi-IN(Beta 版)、it-IT(Beta 版)、ja-JP(Beta 版)、ko-KR(Beta 版)、pl-PL(Beta 版)、pt-BR(Beta 版)、ru-RU(Beta 版)、tr-TR(Beta 版)、vi-VN(Beta 版)

支持的设备

Mode 支持的设备
基本 使用 API 级别 31 及更高级别的 Android 设备。
高级

Pixel 10 和 Pixel 11 系列,以及搭载以下芯片组且支持 Gemini Nano 的设备(包括 Samsung Galaxy S26、Z Flip8 和 Z Fold8 系列等):

  • Qualcomm Snapdragon:SM8750、SM8845、SM8850、SM8950、SM8975
  • MediaTek Dimensity:MT6991、MT6993、MT6995
  • Samsung Exynos:Exynos 2600

常见设置问题

机器学习套件生成式 AI API 依赖于 Android AICore 应用来访问 Gemini Nano。当设备刚设置完毕(包括重置)或 AICore 应用刚重置(例如清除数据、卸载后重新安装)时,AICore 应用可能没有足够的时间完成初始化(包括从服务器下载最新配置)。因此,ML Kit GenAI API 可能无法按预期运行。以下是您可能会看到的常见设置错误消息以及处理方法:

错误消息示例 如何处理
AICore 失败,错误类型为 4-CONNECTION_ERROR,错误代码为 601-BINDING_FAILURE:AICore 服务未能绑定。 如果您在设备设置完成后立即安装使用机器学习套件生成式 AI API 的应用,或者在应用安装后卸载 AICore,就可能会发生这种情况。更新 AICore 应用,然后重新安装您的应用,应该可以解决此问题。
AICore 失败,错误类型为 3-PREPARATION_ERROR,错误代码为 606-FEATURE_NOT_FOUND:功能…不可用。 如果 AICore 尚未完成最新配置的下载,就可能会发生这种情况。设备连接到网络后,通常需要几分钟到几小时才能完成更新。重启设备可以加快更新速度。

请注意,如果设备的引导加载程序已解锁,您也会看到此错误,因为此 API 不支持引导加载程序已解锁的设备。
AICore 失败,错误类型为 1-DOWNLOAD_ERROR,错误代码为 0-UNKNOWN:功能…失败,失败状态为 0,错误为 esz: UNAVAILABLE: Unable to resolve host… 请保持网络连接,等待几分钟,然后重试。

示例代码

  • 在 GitHub 上探索机器学习套件语音识别 API 代码示例