安卓实时弹幕demo(四)科大讯飞语音SDK_xbw12138的博客-程序员宝宝

技术标签: Android开发  

///2016/08/03///

///by  xbw

//android studio//


先感叹一下,科大讯飞的语音识别技术着实厉害,识别率真实牛。

没用过的可以去看看,传送门


帮助文档描述比较清楚了,很好配置。。。

在下载的demo中复制以下文件



然后androidmanifest.xml中的东西也要拷贝过来

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xbw.danmu.danmu">
    <!-- 【必须】 信鸽SDK所需权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <!-- 【常用】 信鸽SDK所需权限 -->
    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 【可选】 信鸽SDK所需权限 -->
    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BATTERY_STATS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <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.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launch"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>






        <!-- 【必须】 (2.30及以上版新增)展示通知的activity -->
        <activity
            android:name="com.tencent.android.tpush.XGPushActivity"
            android:theme="@android:style/Theme.Translucent"
            android:exported="false" >
            <intent-filter>
                <!-- 若使用AndroidStudio,请设置android:name="android.intent.action"-->
                <action android:name="android.intent.action" />
            </intent-filter>
        </activity>

        <!-- 【必须】 信鸽receiver广播接收 -->
        <receiver
            android:name="com.tencent.android.tpush.XGPushReceiver"
            android:process=":xg_service_v2" >
            <intent-filter android:priority="0x7fffffff" >

                <!-- 【必须】 信鸽SDK的内部广播 -->
                <action android:name="com.tencent.android.tpush.action.SDK" />
                <action android:name="com.tencent.android.tpush.action.INTERNAL_PUSH_MESSAGE" />
                <!-- 【必须】 系统广播:网络切换 -->
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

                <!-- 【可选】 系统广播:开屏 -->
                <action android:name="android.intent.action.USER_PRESENT" />

                <!-- 【可选】 一些常用的系统广播,增强信鸽service的复活机会,请根据需要选择。当然,你也可以添加APP自定义的一些广播让启动service -->
                <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
            <!-- 【可选】 usb相关的系统广播,增强信鸽service的复活机会,请根据需要添加 -->
            <intent-filter android:priority="0x7fffffff" >
                <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
                <action android:name="android.intent.action.MEDIA_REMOVED" />
                <action android:name="android.intent.action.MEDIA_CHECKING" />
                <action android:name="android.intent.action.MEDIA_EJECT" />

                <data android:scheme="file" />
            </intent-filter>
        </receiver>
        <!-- 【必须】 信鸽service -->
        <service
            android:name="com.tencent.android.tpush.service.XGPushService"
            android:exported="true"
            android:persistent="true"
            android:process=":xg_service_v2" />

        <!-- 【必须】 通知service,其中android:name部分要改为当前包名 -->
        <service
            android:name="com.tencent.android.tpush.rpc.XGRemoteService"
            android:exported="true" >
            <intent-filter>
                <!-- 【必须】 请修改为当前APP名包.PUSH_ACTION,如demo的包名为:com.qq.xgdemo -->
                <action android:name="com.xbw.danmu.danmu.PUSH_ACTION" />
            </intent-filter>
        </service>

        <!-- 已废弃,可删除之;若不删除也不会有任何副作用 -->
        <!--<service
            android:name="com.tencent.android.tpush.service.XGDaemonService"
            android:process=":qq_push_daemon" />
        -->
        <!-- 【可选】信鸽拉起其他APP应用,若应用在本地找不到可以自动下载 -->
        <!--
              <service
            android:name="com.tencent.android.tpush.XGDownloadService"
            android:enabled="true"
            android:exported="false" />
        -->
        <!-- 【可选】APP实现的Receiver,用于接收消息透传和操作结果的回调,请根据需要添加 -->
        <!-- YOUR_PACKAGE_PATH.CustomPushReceiver需要改为自己的Receiver: -->
        <receiver android:name="com.xbw.danmu.danmu.MessageReceiver"
            android:exported="false" >
            <intent-filter>
                <!-- 接收消息透传 -->
                <action android:name="com.tencent.android.tpush.action.PUSH_MESSAGE" />
                <!-- 监听注册、反注册、设置/删除标签、通知被点击等处理结果 -->
                <action android:name="com.tencent.android.tpush.action.FEEDBACK" />
            </intent-filter>
        </receiver>

        <!-- 【必须】 请修改为APP的AccessId,“21”开头的10位数字,中间没空格 -->
        <meta-data
            android:name="XG_V2_ACCESS_ID"
            android:value="21*******" />
        <!-- 【必须】 请修改为APP的AccessKey,“A”开头的12位字符串,中间没空格 -->
        <meta-data
            android:name="XG_V2_ACCESS_KEY"
            android:value="A******" />
    </application>

</manifest>

string.xml中包含了apiID,必须的添加。

MainActivity.java   这个包含了弹幕跟语音,消息透传

package com.xbw.danmu.danmu;

import android.app.Activity;
import android.os.Environment;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import com.tencent.android.tpush.XGIOperateCallback;
import com.tencent.android.tpush.XGPushManager;
import com.xbw.danmu.danmu.iflytek.speech.util.JsonParser;
import com.xbw.danmu.danmu.opendanmaku.DanmakuView;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.LinkedHashMap;

public class MainActivity extends Activity {
    public static DanmakuView mDanmakuView;
    private ImageView sendDanmu;
    private String danmucontent = "";
    // 语音听写对象
    private SpeechRecognizer mIat;
    // 语音听写UI
    private RecognizerDialog mIatDialog;
    // 引擎类型
    private String mEngineType = SpeechConstant.TYPE_CLOUD;
    private Toast mToast;
    // 用HashMap存储听写结果
    private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
    private ToggleButton danmuOpen;
    private ChangeDialog cd;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cd=new ChangeDialog(this);
        cd.showChangeDialog("输入昵称");
        initXGPush();
        initUI();

    }
    private void initXGPush() {
        XGPushManager.registerPush(this, new XGIOperateCallback() {
            @Override
            public void onSuccess(Object data, int flag) {
                Log.d("TPush", "注册成功,设备token为:" + data);
            }
            @Override
            public void onFail(Object data, int errCode, String msg) {
                Log.d("TPush", "注册失败,错误码:" + errCode + ",错误信息:" + msg);
            }
        });
    }
    int ret = 0;
    private void initUI() {
        mDanmakuView = (DanmakuView) findViewById(R.id.danmakuView);//弹幕
        danmuOpen = (ToggleButton) findViewById(R.id.switch1);
        sendDanmu = (ImageView) findViewById(R.id.imageView5);//发送弹幕
        mIat = SpeechRecognizer.createRecognizer(MainActivity.this, mInitListener);
        // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
        // 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源
        mIatDialog = new RecognizerDialog(MainActivity.this, mInitListener);
        mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        sendDanmu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mIatResults.clear();
                danmucontent = "";
                // 设置参数
                setParam();
                boolean isShowDialog = true;
                if (isShowDialog) {
                    // 显示听写对话框
                    mIatDialog.setListener(mRecognizerDialogListener);
                    mIatDialog.show();
                    showTip(getString(R.string.text_begin));
                } else {
                    // 不显示听写对话框
                    ret = mIat.startListening(mRecognizerListener);
                    if (ret != ErrorCode.SUCCESS) {
                        showTip("听写失败,错误码:" + ret);
                    } else {
                        showTip(getString(R.string.text_begin));
                    }
                }
            }
        });
        danmuOpen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    mDanmakuView.show();
                    mDanmakuView.setVisibility(View.VISIBLE);
                } else {
                    mDanmakuView.hide();
                    mDanmakuView.setVisibility(View.GONE);
                }
            }
        });
    }
    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            //Log.d(TAG, "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                showTip("初始化失败,错误码:" + code);
            }
        }
    };
    /**
     * 听写监听器。
     */
    private RecognizerListener mRecognizerListener = new RecognizerListener() {
        @Override
        public void onBeginOfSpeech() {
            // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
            showTip("开始说话");
        }
        @Override
        public void onError(SpeechError error) {
            // Tips:
            // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
            // 如果使用本地功能(语记)需要提示用户开启语记的录音权限。
            showTip(error.getPlainDescription(true));
        }
        @Override
        public void onEndOfSpeech() {
            // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
            showTip("结束说话");
        }
        @Override
        public void onResult(RecognizerResult results, boolean isLast) {
        }
        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            showTip("当前正在说话,音量大小:" + volume);
        }
        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
        }
    };
    private void printResult(RecognizerResult results) {
        String text = JsonParser.parseIatResult(results.getResultString());
        String sn = null;
        // 读取json结果中的sn字段
        try {
            JSONObject resultJson = new JSONObject(results.getResultString());
            sn = resultJson.optString("sn");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        mIatResults.put(sn, text);
        StringBuffer resultBuffer = new StringBuffer();
        for (String key : mIatResults.keySet()) {
            resultBuffer.append(mIatResults.get(key));
        }
        danmucontent = resultBuffer.toString();
    }
    /**
     * 听写UI监听器
     */
    private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
        public void onResult(RecognizerResult results, boolean isLast) {
            printResult(results);
            if (isLast) {
                // TODO 最后的结果
                //	printResult(results);
                AsyncTask_Insert_Danmu dan = new AsyncTask_Insert_Danmu(MainActivity.this);
                dan.execute(Config.UserName,danmucontent);
            }
        }
        /**
         * 识别回调错误.
         */
        public void onError(SpeechError error) {
            showTip(error.getPlainDescription(true));
        }
    };
    private void showTip(final String str) {
        mToast.setText(str);
        mToast.show();
    }

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

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

        String lag = "mandarin";
        if (lag.equals("en_us")) {
            // 设置语言
            mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");
        } else {
            // 设置语言
            mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
            // 设置语言区域
            mIat.setParameter(SpeechConstant.ACCENT, lag);
        }

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

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

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

        // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
        mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav");
    }

    @Override
    protected void onPause() {
        super.onPause();
        mDanmakuView.hide();
        mDanmakuView.setVisibility(View.GONE);
    }

    @Override
    public void onResume() {
        super.onResume();
        mDanmakuView.show();
        mDanmakuView.setVisibility(View.VISIBLE);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mDanmakuView.clear();
        mIat.cancel();
        mIat.destroy();
    }
}

好了
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xbw12138/article/details/52104148

智能推荐

Cause: java.sql.SQLException: ORA-00933: SQL 命令未正确结束_weixin_44627802的博客-程序员宝宝

项目连接Oracle数据库使用分页插件PageHelper报错Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException:org.springframework.web.util.NestedServletException: Request processing ...

Qt中QT_BEGIN_NAMESPACE和QT_END_NAMESPACE的作用_WangEason1985的博客-程序员宝宝_qt_begin_namespace

在Qt中,我们经常会看到QT_BEGIN_NAMESPACEclass QAction;class QMenu;class QPlainTextEdit;QT_END_NAMESPACE这样的方式表达方式!这样做有什么意义呢?只要深入最终这个宏就知道了。嘻嘻在qglobal.h中我们可以看到这样的定义# define QT_BEGIN_NAMESPACE namespace Q...

vue-router4.0 关于后台管理系统权限动态添加路由解决方案_ViFong的博客-程序员宝宝_vue-router4.0动态添加路由

首先说明一下vue-router4.0删除了 addRoutes的方法, 而是用addRoute代替。那么意味着我们动态添加路由的时候需要一个一个的添加。看下官方文档解释,添加新路由同时需要触发新路由才能显示页面先看下这种方式:在路由守卫中添加动态路由(router4.0中next为可选) // 获取权限的路由数组 const list = await store.dispatch("setUserInfo"); list.forEach((item) =&gt; {

手机动画脚本_Flash脚本-基本补间动画_culi4814的博客-程序员宝宝

Download the sample files here. 在此处下载示例文件 。 You can create a motion tween using one of two methods: 您可以使用以下两种方法之一创建补间动画: Create the starting and ending keyframes for the animation, and use the Mo...

关于Chrome浏览器(Chrome Stable、 Chrome Canary 、Chromium)_weixin_34416754的博客-程序员宝宝

作为开发者,web浏览器一般最常用的可能是Chrome浏览器。但其实Chrome浏览器还有别的一些版本。如:Chrome Stable、 Chrome Canary 、Chromium。大部分人一般用的是Chrome Stable。下面将其大致区别写一下:Chrome Stable:Chrome stable 是最稳定的版本,是经过周详的测试以后,google发版的最新稳定版本。不...

2021年G3锅炉水处理多少分及格及G3锅炉水处理报名考试_安全生产模拟考试一点通考试平台的博客-程序员宝宝_锅炉水处理g3多少分合格

题库来源:安全生产模拟考试一点通公众号小程序G3锅炉水处理多少分及格是安全生产模拟考试一点通总题库中随机出的一套G3锅炉水处理报名考试,在公众号安全生产模拟考试一点通上点击G3锅炉水处理作业手机同步练习。2021年G3锅炉水处理多少分及格及G3锅炉水处理报名考试1、【判断题】电化学分析法是基于被测溶液的各种电化学性质,来确定其组成和含量的分析方法。()( √ )2、【判断题】规范锅炉水(介)质处理工作,促进锅炉运行的安全、经济、节能、环保,是制订《锅炉水(介)质处理监督管理规则》的目的。()(

随便推点

如何改变Discuz!系列版本主题分类前缀名称颜色、字体大小 、加粗等问题解决方法_linyueh的博客-程序员宝宝

不少朋友可能像我一样,在对Discuz!系列版本进行DIY时都会或多或少的遇到一点小小问题和困难,如果我们在后台设置里面找不到我们想对前台进行编辑的功能时,我们内心就会有些烦躁。例如,关于主题分类前缀名称色彩、字体大小、加粗等问题后台也许是没有这个功能可以直接进行操作的,这样如果我们要按我们的喜爱去改变它们的话,我们该如何做?今天,展柜SEO就将如何改变主题分类前缀名称颜色、字体大小 、加粗等问题

【树莓派】搭建局域网内网页实时视频监控_聆雪轻柔的博客-程序员宝宝_树莓派安装picamera

文章目录前言一、软硬件准备1、硬件准备2、软件准备二、搭建流程1、检查是否安装了picamera2、使能摄像头模块3、查询树莓派IP地址4、创建python文件并传输到树莓派5、运行python脚本6、效果如下总结前言上篇文章我们使用Smaba搭建了树莓派的文件共享系统,这里我们就用上这个文件编辑传输的功能吧,接下来使用摄像头搭建一个简单的实时监控。一、软硬件准备1、硬件准备树莓派摄像头树莓派4B2、软件准备VNC远程桌面二、搭建流程1、检查是否安装了

【pytest】常见的 pytest 参数及插件_waitan2018的博客-程序员宝宝

pytest的常见参数:-s :显示标准输出,例如print()的语句; -v :显示详细报告; -q :显示简洁报告; -x :用例失败时立即停止测试; -c file :从 file 加载配置文件; -l (--showlocals) :用例失败信息回溯时显示局部变量及其值; --maxfail=n :失败n后停止运行测试; --lf (--last-failed) :...

Web Hacking 101 翻译完成_布客飞龙的博客-程序员宝宝

原书:Hack, Learn, Earn, with a Free E-Book译者:飞龙在线阅读PDF格式EPUB格式MOBI格式代码仓库 该书的后续版本不做翻译,可以在 Leanpub 上购买。但由于漏洞报告是公开的,会放出漏洞链接。赞助我协议CC BY-NC-SA 4.0

一个c程序的执行是从什么开始的?_木子欢儿的博客-程序员宝宝

一个C语言的执行是从本程序的main函数开始,到main函数结束,但需要注意的是,也是有特殊情况的,若是代码中出现了exit函数,则直接结束程序,对于这一点还是需要了解的。关于c语言需要了解的是,C语言用scanf()、printf()函数作入输入、输出函数,相对来说用法较复杂。而且C语言的最大优点是编译后代码运行效率接近汇编程序,速度快,资源占用少。因此早期很多重要...

LeetCode 95. 不同的二叉搜索树 II_只会写臭虫的博客-程序员宝宝

思路:递归构造,选取当前序列的根节点,然后递给构造以该根节点的左子树集合和右子树集合,因为序列是递增的,所以根节点左边的子树一定比根节点小,右子树一定比右子树大。递归出口是end&gt;begin,返回NULL。参考的题解代码:/** * Definition for a binary tree node. * struct TreeNode { * int val; * ...

推荐文章

热门文章

相关标签