android 搭建本地实现语音识别功能 vosk
implementation 'net.java.dev.jna:jna:5.13.0@aar'
implementation 'com.alphacephei:vosk-android:0.3.47@aar'
在app的build 添加uuid
tasks.register('genUUID') { def uuid = UUID.randomUUID().toString() def odir = file("$buildDir/generated/assets/vosk-model-small-cn") def ofile = file("$odir/uuid") doLast { mkdir odir ofile.text = uuid } } preBuild.dependsOn(genUUID)
去https://alphacephei.com/vosk/models下载自己需要的模型
下载完成后解压放到项目里面的assets文件夹下
package com.xxx.xxx.xxx; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.aipeople.by.R; import org.json.JSONObject; import org.vosk.LibVosk; import org.vosk.LogLevel; import org.vosk.Model; import org.vosk.Recognizer; import org.vosk.android.RecognitionListener; import org.vosk.android.SpeechService; import org.vosk.android.StorageService; import java.io.IOException; import dagger.hilt.android.AndroidEntryPoint; public class MainActivity extends AppCompatActivity implements RecognitionListener { private static final int RECORD_AUDIO_PERMISSION_REQUEST_CODE = 1; private SpeechService speechService; private Model model; private TextView resultTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo); resultTextView = findViewById(R.id.textView); // 初始化 Vosk LibVosk.setLogLevel(LogLevel.INFO); // 下载并解压模型 // String modelUrl = "https://alphacephei.com/vosk/models/vosk-model-small-cn-0.22.zip"; // File modelDir = new File(getFilesDir(), "model"); // if (!modelDir.exists()) { // OkGo.<File>get(modelUrl) // .execute(new FileCallback(modelDir.getPath(), "vosk-model-small-cn-0.22.zip") { // @Override // public void onSuccess(Response<File> response) { // // 下载成功处理 // File file = response.body(); // Toast.makeText(MainActivity.this, "Vosk下载成功", Toast.LENGTH_SHORT).show(); // // 这里可以进行文件操作,比如打开、展示等 // } // // @Override // public void onError(Response<File> response) { // // 下载失败处理 // super.onError(response); // Toast.makeText(MainActivity.this, "Vosk下载失败", Toast.LENGTH_SHORT).show(); // } // // @Override // public void downloadProgress(Progress progress) { // super.downloadProgress(progress); // Log.e("Vosk下载进度","=="+progress.currentSize); // } // }); //// DownloadUtil.downloadAndExtract(modelUrl, modelDir.getPath()); // } // try { // Model model = new Model(modelDir.getPath()); // } catch (IOException e) { // throw new RuntimeException(e); // } // 检查权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, RECORD_AUDIO_PERMISSION_REQUEST_CODE); } else { setupVosk(); } } private void setupVosk() { // 从 assets 加载模型 StorageService.unpack(this, "model-en-us", "model", (model) -> { this.model = model; startListening(); }, (exception) -> Log.e("Vosk", "Failed to unpack the model", exception)); } private void startListening() { try { Recognizer recognizer = new Recognizer(model, 16000.0f); speechService = new SpeechService(recognizer, 16000.0f); speechService.startListening(this); } catch (IOException e) { Log.e("Vosk", "Failed to start speech service", e); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == RECORD_AUDIO_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { setupVosk(); } else { // 权限被拒绝,处理相应逻辑 } } } @Override public void onDestroy() { super.onDestroy(); if (speechService != null) { speechService.stop(); speechService.shutdown(); } } @Override public void onResult(String hypothesis) { if (null==hypothesis) { return; } try { JSONObject jsonObject = new JSONObject(hypothesis); String text = jsonObject.getString("text"); resultTextView.setText(text); Log.e("Vosk","onResult="+text); } catch (Exception e) { // throw new RuntimeException(e); } } @Override public void onFinalResult(String hypothesis) { // resultTextView.setText(hypothesis); // try { // Log.e("Vosk","onFinalResult="+hypothesis); // JSONObject jsonObject = new JSONObject(hypothesis); // String partial = jsonObject.getString("partial"); // if (!TextUtils.isEmpty(partial)) // { // resultTextView.setText(partial); // } // } catch (Exception e) { //// throw new RuntimeException(e); // } } @Override public void onPartialResult(String hypothesis) { try { Log.e("Vosk","onPartialResult="+hypothesis); JSONObject jsonObject = new JSONObject(hypothesis); String partial = jsonObject.getString("partial"); if (!TextUtils.isEmpty(partial)) { resultTextView.setText(partial); } } catch (Exception e) { // throw new RuntimeException(e); } } @Override public void onError(Exception e) { Log.e("Vosk", "Recognition error", e); } @Override public void onTimeout() { speechService.stop(); speechService.startListening(this); } }

浙公网安备 33010602011771号