GenAI Speech Recognition API

ML Kit의 GenAI Speech Recognition API를 사용하면 오디오 콘텐츠를 텍스트로 변환할 수 있습니다. 이 API는 다음 모드를 지원합니다.

  • 고급: Speech Recognition API는 더 광범위한 언어 범위와 더 나은 전반적인 품질을 제공하는 생성형 AI 모델을 사용합니다. 언어별로 별도의 언어 팩을 다운로드할 필요가 없으므로 저장용량이 절약됩니다.
  • 기본: Speech Recognition API는 SpeechRecognizer API와 유사한 기존의 기기 내 음성 인식 모델을 사용합니다.

Speech Recognition API는 오디오 콘텐츠를 동일한 언어의 텍스트로 변환합니다. 오디오를 다른 언어의 텍스트로 변환하려면 Speech Translation API를 사용합니다.

주요 기능

  • 마이크 또는 오디오 파일에서 스트리밍 입력을 캡처합니다.
  • AudioSource.fromFile() 또는 AudioSource.fromUri() 메서드를 사용하여 사전 녹음된 파일 전체를 스크립트로 작성합니다. 자세한 내용은 오디오 입력 요구사항을 참조하세요.
  • 스트리밍 입력의 경우 인식된 각 단어의 정확한 시작 시간을 제공하여 UI 애니메이션을 동기화하거나, 자막을 생성하거나, 단어가 발음될 때 강조표시할 수 있습니다. 인식된 각 단어의 시작 시간(밀리초)은 이벤트 시작 시간(타임스탬프 0)으로부터의 오프셋입니다.
  • 스크립트 작성된 텍스트는 연속 스트림으로 제공되며, 처음에는 부분적일 수 있고 (변경될 수 있음) 최종 인식된 텍스트가 됩니다.

결과 예시

오디오 모드 언어 스크립트 작성
audio_2 고급 es-ES "Este es un mensaje corto."
audio_1 기본 en-US "This is a short message"

플랫폼 Speech Recognition API와의 비교

ML Kit Speech Recognition API는 기본 모드를 사용할 때 플랫폼 SpeechRecognizer API의 기본 기능을 다룹니다. ML Kit의 주요 장점은 특정 플랫폼 버전에 종속되지 않는다는 것입니다.

또한 ML Kit Speech Recognition API는 고급 모드를 사용할 때 기기 내 Gemini 모델을 사용하여 음성 인식을 지원하므로 언어 지원 범위가 확장됩니다.

시작하기

ML Kit Speech Recognition API를 build.gradle 구성에 종속 항목으로 추가합니다.

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
  • 채널: 모노 (단일 채널)
  • 샘플링 레이트: 16kHz

대부분의 사용 사례에서는 이러한 제약 조건을 자동으로 처리하는 AudioSource.fromMic()를 사용하는 것이 좋습니다.

지원되는 오디오 입력 형식

Speech Recognition API는 다음 오디오 입력 형식을 지원합니다.

  • MP3, WAV, FLAC, M4A, OGG 파일은 기기에서 자동으로 디코딩됩니다.
  • 원시, 헤더 없는 오디오 (.raw 또는 .pcm)는 16비트 PCM, 16kHz, 모노 형식이어야 합니다.

형식이 잘못되었거나 지원되지 않는 경우 인식이 시작될 때 ErrorResponse 값이 반환됩니다.

Speech Recognition API 구현

Speech Recognition API를 사용하여 오디오 스크립트를 작성하고 단어 타이밍을 사용하는 방법은 다음과 같습니다.

오디오 스크립트 작성

Speech Recognition 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 객체를 제공하는 경우 실시간 속도 (표준 16kHz, 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 객체에는 SpeechRecognizerResponse.WordTiming 객체 목록이 포함된 wordTimings 속성이 포함됩니다. 각 객체는 음성 인식 세션의 시작부터 인식된 단어 문자열 (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 (베타), cmn-Hans-CN, cmn-Hant-TW, da-DK (베타), de-DE, en-US, es-ES, fr-FR, hi-IN (베타), id-ID (베타), it-IT, ja-JP, ko-KR, nl-NL (베타), pl-PL (베타), pt-PT, ru-RU, sv-SE (베타), th-TH, tr-TR (베타), vi-VN (베타)
기본 cmn-Hans-CN (베타), cmn-Hant-TW (베타), de-DE (베타), en-US, es-ES (베타), fr-FR (베타), hi-IN (베타), it-IT (베타), ja-JP (베타), ko-KR (베타), pl-PL (베타), pt-BR (베타), ru-RU (베타), tr-TR (베타), vi-VN (베타)

지원되는 기기

Mode(최빈값) 지원되는 기기
기본 API 수준 31 이상을 사용하는 Android 기기
고급

Pixel 10 및 Pixel 11 시리즈와 다음 칩셋에서 Gemini Nano를 사용하는 기기 (삼성 갤럭시 S26, Z Flip8, Z Fold8 시리즈 등):

  • Qualcomm Snapdragon: SM8750, SM8845, SM8850, SM8950, SM8975
  • MediaTek Dimensity: MT6991, MT6993, MT6995
  • 삼성 Exynos: Exynos 2600

일반적인 설정 문제

ML Kit GenAI API는 Android AICore 앱을 사용하여 Gemini Nano에 액세스합니다. 기기가 방금 설정되었거나 (재설정 포함) AICore 앱이 방금 재설정된 경우 (예: 데이터 삭제, 제거 후 재설치) AICore 앱이 초기화 (서버에서 최신 구성 다운로드 포함)를 완료할 시간이 충분하지 않을 수 있습니다. 따라서 ML Kit GenAI API가 예상대로 작동하지 않을 수 있습니다. 다음은 표시될 수 있는 일반적인 설정 오류 메시지와 해결 방법입니다.

오류 메시지 예 대응 방법
AICore가 오류 유형 4-CONNECTION_ERROR 및 오류 코드 601-BINDING_FAILURE로 인해 실패했습니다. AICore 서비스를 바인딩할 수 없습니다. 이러한 상황은 기기 설정 직후 ML Kit GenAI API를 사용하여 앱을 설치하거나 앱이 설치된 후 AICore가 제거될 때 발생할 수 있습니다. AICore 앱을 업데이트한 후 앱을 다시 설치하면 문제가 해결됩니다.
AICore가 오류 유형 3-PREPARATION_ERROR 및 오류 코드 606-FEATURE_NOT_FOUND로 실패했습니다. … 기능을 사용할 수 없습니다. AICore가 최신 구성 다운로드를 완료하지 않은 경우에 발생할 수 있습니다. 기기가 인터넷에 연결되어 있으면 업데이트하는 데 일반적으로 몇 분에서 몇 시간이 걸립니다. 기기를 다시 시작하면 업데이트 속도가 빨라질 수 있습니다.

기기의 부트로더가 잠금 해제된 경우에도 이 오류가 표시됩니다. 이 API는 부트로더가 잠금 해제된 기기를 지원하지 않습니다.
AICore가 오류 유형 1-DOWNLOAD_ERROR 및 오류 코드 0-UNKNOWN으로 실패했습니다. … 기능이 실패 상태 0 및 오류 esz: UNAVAILABLE: 호스트 …을(를) 확인할 수 없음으로 실패했습니다. 네트워크 연결을 유지하고 몇 분 정도 기다린 후 다시 시도하세요.

샘플 코드

  • GitHub에서 ML Kit Speech Recognition API 코드 샘플 살펴보기