Android 科大讯飞、语音听写集成指南

2023-05-16

 

前提说明:讯飞SDK与appID(后台申请)是一一对应的、否则就会导致初始化不成功!

1、创建appID并下载SDK(没有账号的先行注册)

https://console.xfyun.cn/app/myapp

创建完成后、如图

下载解压包

simple就是官方demo、默认会填写你已经申请好的appid、你可以比这官方Demo写


 

2、自己再封装lib、仅保留语音转文字功能、

语音转换核心控制类:

/**
 * 音频读写转换
 */
public class RecognizeSpeechManager implements RecognizerListener, InitListener {

    private static final String TAG = "RecognizeSpeechManager";

    private RecognizeListener recognizeListener;

    // 语音听写对象
    private SpeechRecognizer iat;

    private StringBuffer charBufffer = new StringBuffer();

    private WeakReference<Context> bindContext;

    private static RecognizeSpeechManager instance;

    private RecognizeSpeechManager() {
    }

    public static RecognizeSpeechManager instance() {
        if (instance == null) {
            instance = new RecognizeSpeechManager();
        }
        return instance;
    }

    public void setRecognizeListener(RecognizeListener recognizeListener) {
        this.recognizeListener = recognizeListener;
    }

    public void init(Context context) {
        if (bindContext == null) {
            bindContext = new WeakReference<Context>(context);
        }
        if (iat == null) {
            iat = SpeechRecognizer.createRecognizer(bindContext.get(), this);
        }
    }

    @Override
    public void onInit(int code) {
        if (code != ErrorCode.SUCCESS) {
            Log.d(TAG, "init error code " + code);
        }
    }

    /**
     * 开始监听
     * ErrorCode.SUCCESS 监听成功状态码
     */
    public int startRecognize() {
        setParam();
        return iat.startListening(this);
    }

    /**
     * 取消听写
     */
    public void cancelRecognize() {
        iat.cancel();
    }

    /**
     * 停止听写
     */
    public void stopRecognize() {
        iat.stopListening();
    }

    public void release() {
        iat.cancel();
        iat.destroy();
        iat = null;
        bindContext.clear();
        bindContext = null;
        charBufffer.delete(0, charBufffer.length());
    }

    @Override
    public void onVolumeChanged(int i, byte[] bytes) {

    }

    @Override
    public void onBeginOfSpeech() {
        Log.d(TAG, "onBeginOfSpeech");
    }

    @Override
    public void onEndOfSpeech() {
        Log.d(TAG, "onEndOfSpeech isListening " + iat.isListening());
    }

    @Override
    public void onResult(RecognizerResult results, boolean b) {
        if (recognizeListener != null) {
            recognizeListener.onNewResult(printResult(results));
            recognizeListener.onTotalResult(charBufffer.toString(), iat.isListening());
        }
    }


    @Override
    public void onError(SpeechError speechError) {
        if (recognizeListener != null) {
            recognizeListener.onError(speechError);
        }
    }

    @Override
    public void onEvent(int i, int i1, int i2, Bundle bundle) {
        Log.d(TAG, "onEvent type " + i);
    }


    private String printResult(RecognizerResult results) {
        String text = JsonParser.parseIatResult(results.getResultString());
        Log.d(TAG, "printResult " + text + " isListening " + iat.isListening());
        String sn = null;
        // 读取json结果中的sn字段
        try {
            JSONObject resultJson = new JSONObject(results.getResultString());
            sn = resultJson.optString("sn");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if (!TextUtils.isEmpty(text)) {
            charBufffer.append(text);
        }
        return text;
    }

    /**
     * 参数设置
     *
     * @return
     */
    private void setParam() {
        // 清空参数
        iat.setParameter(SpeechConstant.PARAMS, null);

        // 设置听写引擎
        iat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        // 设置返回结果格式
        iat.setParameter(SpeechConstant.RESULT_TYPE, "json");


        iat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        iat.setParameter(SpeechConstant.ACCENT, "mandarin");

        //此处用于设置dialog中不显示错误码信息
        //iat.setParameter("view_tips_plain","false");

        // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
        iat.setParameter(SpeechConstant.VAD_BOS, "10000");

        // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
        iat.setParameter(SpeechConstant.VAD_EOS, "10000");

        // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
        iat.setParameter(SpeechConstant.ASR_PTT, "1");

        // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
       /* iat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        iat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav");*/
    }

}
RecognizeListener 接口、用于语音转换成功后、文本回调
/**
 * 听写回调
 */
public interface RecognizeListener {

    void onNewResult(String result);

    void onTotalResult(String result,boolean isLast);

    void onError(SpeechError speechError);
}

解析工具类、来自官方Demo

/**
 * Json结果解析类
 */
public class JsonParser {

	public static String parseIatResult(String json) {
		StringBuffer ret = new StringBuffer();
		try {
			JSONTokener tokener = new JSONTokener(json);
			JSONObject joResult = new JSONObject(tokener);

			JSONArray words = joResult.getJSONArray("ws");
			for (int i = 0; i < words.length(); i++) {
				// 转写结果词,默认使用第一个结果
				JSONArray items = words.getJSONObject(i).getJSONArray("cw");
				JSONObject obj = items.getJSONObject(0);
				ret.append(obj.getString("w"));
//				如果需要多候选结果,解析数组其他字段
//				for(int j = 0; j < items.length(); j++)
//				{
//					JSONObject obj = items.getJSONObject(j);
//					ret.append(obj.getString("w"));
//				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return ret.toString();
	}
	
	public static String parseGrammarResult(String json) {
		StringBuffer ret = new StringBuffer();
		try {
			JSONTokener tokener = new JSONTokener(json);
			JSONObject joResult = new JSONObject(tokener);

			JSONArray words = joResult.getJSONArray("ws");
			for (int i = 0; i < words.length(); i++) {
				JSONArray items = words.getJSONObject(i).getJSONArray("cw");
				for(int j = 0; j < items.length(); j++)
				{
					JSONObject obj = items.getJSONObject(j);
					if(obj.getString("w").contains("nomatch"))
					{
						ret.append("没有匹配结果.");
						return ret.toString();
					}
					ret.append("【结果】" + obj.getString("w"));
					ret.append("【置信度】" + obj.getInt("sc"));
					ret.append("\n");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			ret.append("没有匹配结果.");
		} 
		return ret.toString();
	}
	
	public static String parseLocalGrammarResult(String json) {
		StringBuffer ret = new StringBuffer();
		try {
			JSONTokener tokener = new JSONTokener(json);
			JSONObject joResult = new JSONObject(tokener);

			JSONArray words = joResult.getJSONArray("ws");
			for (int i = 0; i < words.length(); i++) {
				JSONArray items = words.getJSONObject(i).getJSONArray("cw");
				for(int j = 0; j < items.length(); j++)
				{
					JSONObject obj = items.getJSONObject(j);
					if(obj.getString("w").contains("nomatch"))
					{
						ret.append("没有匹配结果.");
						return ret.toString();
					}
					ret.append("【结果】" + obj.getString("w"));
					ret.append("\n");
				}
			}
			ret.append("【置信度】" + joResult.optInt("sc"));

		} catch (Exception e) {
			e.printStackTrace();
			ret.append("没有匹配结果.");
		} 
		return ret.toString();
	}

	public static String parseTransResult(String json,String key) {
		StringBuffer ret = new StringBuffer();
		try {
			JSONTokener tokener = new JSONTokener(json);
			JSONObject joResult = new JSONObject(tokener);
			String errorCode = joResult.optString("ret");
			if(!errorCode.equals("0")) {
				return joResult.optString("errmsg");
			}
			JSONObject transResult = joResult.optJSONObject("trans_result");
			ret.append(transResult.optString(key));
			/*JSONArray words = joResult.getJSONArray("results");
			for (int i = 0; i < words.length(); i++) {
				JSONObject obj = words.getJSONObject(i);
				ret.append(obj.getString(key));
			}*/
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret.toString();
	}
}

 权限配置

   <!--连接网络权限,用于执行云端语音能力 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <!--读取网络信息状态 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!--获取当前wifi状态 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <!--允许程序改变网络连接状态 -->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <!--读取手机信息权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <!--外存储写权限,构建语法需要用到此权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--外存储读权限,构建语法需要用到此权限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!--配置权限,用来记录应用配置信息 -->
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
    <!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

 3、主工程Application中初始化 、并依赖recognizespeech lib库

//注意、appid=xxxx 不能省略(xxxx 写上自己的appid)
SpeechUtility.createUtility(
    this,
    "appid=xxxxx"
)

如图:

测试类代码

class MainActivity : AppCompatActivity(),RecognizeListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        RecognizeSpeechManager.instance().init(this)
        RecognizeSpeechManager.instance().setRecognizeListener(this)

        btStart.setOnClickListener {
            RecognizeSpeechManager.instance().startRecognize()
        }

        btCancel.setOnClickListener {
            RecognizeSpeechManager.instance().cancelRecognize()
        }

        btStop.setOnClickListener {
            RecognizeSpeechManager.instance().stopRecognize()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        RecognizeSpeechManager.instance().release()
    }

    @SuppressLint("SetTextI18n")
    override fun onNewResult(result: String?) {
        tvContent.append("最新翻译:$result \n")
    }

    @SuppressLint("SetTextI18n")
    override fun onTotalResult(result: String, isLast: Boolean) {
        tvContent.append("所有翻译:$result \n")
    }

    override fun onError(speechError: SpeechError?) {
        Toast.makeText(this,"出错了 $speechError",Toast.LENGTH_SHORT).show()
    }
}

 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

  <TextView
      android:id="@+id/tvContent"
      android:padding="20dp"
      android:layout_gravity="top"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>

  <Button
      android:layout_marginTop="50dp"
      android:id="@+id/btStart"
      android:text="开始识别"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btCancel"
        android:layout_marginTop="20dp"
        android:text="取消"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btStop"
        android:text="停止"
        android:layout_marginTop="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

至此OVer、Demo https://download.csdn.net/download/BirdEatBug/19714846?spm=1001.2014.3001.5501

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 科大讯飞、语音听写集成指南 的相关文章

随机推荐

  • Linux入门之使用 dmesg 查看引导日志

    文档 https en wikipedia org wiki Dmesg dmesg 1 Linux manual page 1 简介 在许多 Linux 系统上 引导过程会生成特别密集的内核消息流 许多管理问题与引导过程中是否成功枚举所需
  • http协议入门之 SameSite cookies

    文档 SameSite cookies HTTP MDN SameSite cookies explained 1 简介 响应标头 Set Cookie 的SameSite属性允许声明 cookie 是否应限制为第一方或同一站点上下文 准确
  • cloudflare入门之 /cdn-cgi/ 端点

    1 简介 将域添加到 Cloudflare时 xff0c Cloudflare 会向该域添加一个 cdn cgi 端点 此端点由 Cloudflare 管理 它不能被修改或定制 一些使用此端点的例子包括 xff1a Cloudflare 机
  • cloudflare入门之附加 cookie

    文档 Cloudflare Cookies Cloudflare Fundamentals docs 1 简介 Cloudflare 使用 cookie 来最大化网络资源 管理流量并保护网站免受恶意流量的侵害 2 cflb 使用Cloudf
  • Linux入门之使用 ps 查看系统进程

    文档 PS Command ps command in Linux with Examples GeeksforGeeks ps 1 Linux manual page 1 简介 ps命令允许显示有关正在运行的进程的信息 它从 proc文件
  • Linux入门之使用 top 查看系统进程

    文档 Top command top command in Linux with Examples GeeksforGeeks top 1 Linux manual page 1 简介 top命令显示系统上正在运行的进程的实时列表 还显示有
  • android入门之使用 adb 进行屏幕截图

    文档 xff1a https developer android com studio command line adb screencap 1 进入shell adb shell shell 64 2 截图 在 shell 里进行截图 x
  • node.js实战之使用 jsdom

    文档 GitHub jsdom jsdom 1 简介 jsdom 是许多 web 标准的纯 JavaScript 实现 特别是 WHATWG DOM和HTML标准 该项目的目标是模拟足够多的 Web 浏览器子集 以用于测试和抓取真实世界的
  • CentOS-7 MySQL 5.7.20安装

    1 检查系统是否安装了mariadb rpm qa grep mariadb 发现已经安装 xff0c 卸载 rpm e nodeps mariadb libs 5 5 52 1 el7 x86 64 2 创建mysql用户组和mysql用
  • mac os入门之安装 brew

    nbsp 文档 The Missing Package Manager for macOS or Linux Homebrew 1 简介 Homebrew 安装了Apple 或 Linux 系统 不需要的东西 nbsp Homebrew 将
  • node.js入门之 mac os下安装 nvm

    1 安装 安装脚本与 linux 下一样 wget qO https raw githubusercontent com nvm sh nvm v0 39 1 install sh bash gt Downloading nvm from
  • make入门之编写 makefile

    文档 GNU make 1 简介 Makefile 包含五种内容 显式规则 隐式规则 变量定义 指令和注释 显式规则 何时及如何重新制作目标 列出了依赖的先决条件 提供创建或更新目标的配方 隐式规则 何时及如何根据文件名重新制作目标 描述如
  • 记一个 Nvidia Control Panel 打不开的问题

    1 简介 Nvidia Control Panel 打不开 xff0c 找到了应用点击没反应 2 解决 找到 NVIDIA Display Container LS 服务 xff0c 启动后 xff0c 右下角出现 NVIDIA 图标 右键
  • 记一个 Europe/Pari 时区冬令时从+2:00变成+1:00问题

    1 简介 代码里写死了时区 Europe Paris xff0c 而且时间点都是以文字时区为准 但是今天发现 xff0c 在本地对应的时间没有运行 最后发现 xff0c 之前Europe Paris 是 43 2 00 xff0c 早上10
  • android入门之 Support Library

    Use legacy support library option in android Stack Overflow https developer android com topic libraries support library
  • 记一个 react 配置路由前缀问题

    react 配置路由前缀需要注意两点 1 资源使用相对路径 默认情况下 xff0c react 编译后的资源使用根路径 xff0c 也就是长下面这样 lt script src 61 34 static js 2 dfc7d8c4 chun
  • nginx 配置SPA应用路由前缀

    1 配置 location xxx alias your directory try files uri uri xxx index html 路由匹配要使用 用 alias 改变当前目录 try files 的最后一个回退项目也必须有前缀
  • geckodriver selenium火狐浏览器驱动

    火狐浏览器驱动对浏览器版本没什么大的要求 xff0c 直接下载这个压缩包就可以 xff0c 在selenium使用中谷歌浏览器bug会很多 xff0c 并非网站反爬 xff0c 火狐或许可以解决 xff0c Releases mozilla
  • B站高清视频下载方法揭密

    有很多文章都介绍过B站的视频如何下载 xff0c 大部分介绍的都是如何通过第三方网站提供的工具下载 xff0c 使用起来有诸多不便 xff0c 也不能实现批量下载 xff0c 今天就给大家介绍一款命令行小工具 xff0c 保证让你爱不释手
  • Android 科大讯飞、语音听写集成指南

    前提说明 xff1a 讯飞SDK与appID xff08 后台申请 xff09 是一一对应的 否则就会导致初始化不成功 xff01 1 创建appID并下载SDK xff08 没有账号的先行注册 xff09 https console xf