Android14下用RecognizerIntent的EXTRA_AUDIO_SOURCE实现PCM转文字遇阻
Android 14下PCM音频转文字:EXTRA_AUDIO_SOURCE使用异常及相关API疑问
环境与需求
- 设备系统:Android 14
- 开发需求:将存放在
res/raw目录下的自有PCM音频文件转换为文字
问题详情
参考API 33的RecognizerIntent.EXTRA_AUDIO_SOURCE文档说明,需传入音频源的ParcelFileDescriptor,但实际运行时设备未识别自定义音频资源,反而调用麦克风进行语音识别。相关实现代码如下:
private var audioPfd : ParcelFileDescriptor? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val testFilePath = copyFiletoStorage(R.raw.test, "test.pcm") val testFile = File(testFilePath) testFile.setReadable(true) audioPfd = ParcelFileDescriptor.open(testFile, ParcelFileDescriptor.MODE_READ_ONLY) println("audioPfd size:${audioPfd?.statSize}") startSpeechToText(audioPfd) } private fun copyFiletoStorage(resourceId: Int, resourceName: String): String? { val filePath = filesDir.path + "/" + resourceName try { println("openRawResource") val `in` = resources.openRawResource(resourceId) var out: FileOutputStream? = null out = FileOutputStream(filePath) val buff = ByteArray(1024) var read = 0 try { while (`in`.read(buff).also { read = it } > 0) { out.write(buff, 0, read) } } finally { `in`.close() out.close() } } catch (e: FileNotFoundException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } return filePath } private fun startSpeechToText(pcmFile: ParcelFileDescriptor?) { val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH) intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM) intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault().toLanguageTag()) intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, packageName) intent.putExtra(RecognizerIntent.EXTRA_AUDIO_SOURCE_CHANNEL_COUNT, 1) intent.putExtra(RecognizerIntent.EXTRA_AUDIO_SOURCE_ENCODING, AudioFormat.ENCODING_PCM_16BIT) intent.putExtra(RecognizerIntent.EXTRA_AUDIO_SOURCE_SAMPLING_RATE, 16000) intent.putExtra(RecognizerIntent.EXTRA_AUDIO_SOURCE, pcmFile) speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this, ComponentName("com.google.android.tts", "com.google.android.apps.speech.tts.googletts.service.GoogleTTSRecognitionService")) speechRecognizer?.setRecognitionListener(object : RecognitionListener { override fun onReadyForSpeech(p0: Bundle?) { println("onReadyForSpeech") } override fun onBeginningOfSpeech() { println("onBeginningOfSpeech") } override fun onRmsChanged(p0: Float) { println("onRmsChanged sound: $p0") } override fun onBufferReceived(p0: ByteArray?) { println("onBufferReceived") } override fun onEndOfSpeech() { println("onEndOfSpeech") } override fun onError(p0: Int) { println("onError:$p0") stopRecognizer() } override fun onResults(p0: Bundle?) { println("onResults: $p0") val matches = p0?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION) if (matches != null && matches.isNotEmpty()) { val text = matches[0] Toast.makeText(applicationContext, "Recognized Text: $text", Toast.LENGTH_LONG).show() textResult?.setText(text) } } override fun onPartialResults(p0: Bundle?) { val matches = p0?.getStringArrayList(SpeechRecognizer.RECOGNITION_PARTS) println("onPartialResults:${matches?.get(0)}") } override fun onEvent(p0: Int, p1: Bundle?) { println("onEvent") } }) speechRecognizer?.startListening(intent) }
核心疑问
- Android是否支持通过
EXTRA_AUDIO_SOURCE实现自有PCM音频转文字的需求?若支持,求实现指引(目前未找到该API的使用示例)。 - 在Android S(API 31)模拟器中尝试使用
EXTRA_AUDIO_INJECT_SOURCE传入音频Uri的用法是否正确?示例代码如下:
val url = Uri.parse("android.resource://" + getPackageName() + "/" + "raw" + "/" + "test.pcm") val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH) intent.putExtra(RecognizerIntent.EXTRA_AUDIO_INJECT_SOURCE, url)
内容的提问来源于stack exchange,提问作者oak yang
相关产品推荐
相关产品推荐

