您好,登錄后才能下訂單哦!
用Kotlin開發android平臺語音識別,語義理解應用(olamisdk)
轉載請注明CSDN博文地址:http://blog.csdn.net/ls0609/article/details/75084994
本文使用Kotlin開發Android平臺的一個語音識別方面的應用,用的是歐拉密開放平臺olamisdk。
Kotlin是由JetBrains創建的基于JVM的編程語言,IntelliJ正是JetBrains的杰作,而android Studio是
基于IntelliJ修改而來的。Kotlin是一門包含很多函數式編程思想的面向對象編程語言。
后來了解到Kotlin原來是以一個島的名字命名的(Котлин),它是一門靜態類型編程語言,支持JVM平臺,android平臺,瀏覽器js運行環境,本地機器碼等。支持與Java,Android 100% 完全互操作。Kotlin生來就是為了彌補Java缺失的現代語言的特性,并極大的簡化了代碼,使得開發者可以編寫盡量少的樣板代碼。
1.輸出Hello,World!
JAVA: System.out.println("Hello,World!");
Kotlin: println("Hello,World!")
Swift: print("Hello,World!")
2.變量和常量
Java: int mVariable =10;
mVariable =20;
static final int mConstant = 10;
Kotlin:var mVariable = 10
mVariable = 20
val mConstant = 10
Swift:var mVariable = 10
mVariable = 20
let mConstant = 10
感覺Swift和Kotlin比Java簡潔,Kotlin和swift很像。
3.強制類型轉換
Swift:
let label = "Hello world "
let width = 80
let widthLabel = label + String(width)
Kotlin:
val label = "Hello world "
val width = 80
val widthLabel =label + width
4數組
Swift :
var tempList = ["one", "two","three"]
tempList[1] = "zero"
Kotlin :
val tempList = arrayOf("one", "two","three")
tempList[1] = "zero"
5.函數
Swift :func greet(_ name: String,_day: String) -> String {
return"Hello\(name),today is \(day)." }
greet("Bob", "Tuesday")
Kotlin :
fun greet(name: String, day: String): String {
return"Hello$name, today is $day."}
greet("Bob", "Tuesday")
6.類聲明及用法
Swift:
聲明:classShape {
var numberOfSides = 0
func simpleDescription() -> String {
return"A shapewith \(numberOfSides) sides."
}
}
用法:varshape = Shape()
shape.numberOfSides = 7
var shapeDescription =shape.simpleDescription()
Kotlin :
聲明:classShape {
var numberOfSides = 0
fun simpleDescription() = "A shapewith $numberOfSides sides."
}
用法:var shape = Shape()
shape.numberOfSides = 7
var shapeDescription= shape.simpleDescription()
可見,Kotlin和Swift好像,現代語言的特征,比java這樣的高級語言更加簡化,更貼近自然語言。
本文使用的是android
studio2.0版本,啟動androd
studio。
如下圖在configure下拉菜單中選擇plugins,在搜索框中搜索Kotlin,找到結果列表中的”Kotlin”插件。
如下圖,找了一張還沒有安裝kotlin插件的圖
點擊右側intall,安裝后重啟studio.
你可以像以前使用android stuio一樣新建一個andoid項目,建立一個activity。本文用已經完成的一個demo來做示范。
如下圖是一個stuio的demo工程
選擇MainActivity和MessageConst兩個java文件,然后選擇導航欄上的code,在下拉菜單中選擇convert Java file to kotlin file
系統會自動進行轉化,轉化完后會生成對應的MainActivity.kt MessageConst.kt文件,打開MainActivity.kt,編譯器上方會提示”Kotlin not configured”,點擊一下Configure按鈕,IDE就會自動幫我們配置好了!
將兩個kt文件復制到src/kotlin目錄下,如下圖
轉化后的文件,也許有些語法錯誤,需要按照kotlin的語法修改。
環境配置好后,來看下gradle更新有哪些區別
project的gradle代碼如下:
buildscript {
ext.kotlin_version = '1.1.3-2'
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
//此處多了kotlin插件依賴
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
jcenter()
}
}
再來看看某個module的gradle代碼:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'//此處多了這條插件聲明
android {
compileSdkVersion 14
buildToolsVersion "24.0.0"
defaultConfig {
applicationId "com.olami"
minSdkVersion 8
targetSdkVersion 14
}
buildTypes {
release {
minifyEnabled false
proguardFilesgetDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'//生成的***.kt文件需要copy到對應的目錄
}
}
dependencies {
compile 'com.android.support:support-v4:18.0.0'
compile files('libs/voicesdk_android.jar')
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"//此處多了kotlin包的依賴
}
repositories {
mavenCentral()
}
如上所示,如果不是通過轉化的方式新建kotlin工程,則需要自己按照上面的gradle中增加的部分配置好。
先貼一張識別后的效果圖:
在MainActivity.kt中
override funonCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initHandler()//初始化handler用于處理消息
initView()//初始化view控件,比如點擊開始錄音的button
initViaVoiceRecognizerListener()//初始化語音識別回調,用于返回錄音狀態和識別結果
init()//初始化語音識別對象
}
fun init()
{
initHandler()
//定義olami語音識別對象
mOlamiVoiceRecognizer =OlamiVoiceRecognizer(this@MainActivity)
val telephonyManager = this.getSystemService(
Context.TELEPHONY_SERVICE) as TelephonyManager
val imei = telephonyManager.deviceId
mOlamiVoiceRecognizer!!.init(imei)
//set null if you do not want to notifyolami server.
//設置回調,用于更新錄音狀態和數據等的界面
mOlamiVoiceRecognizer!!.setListener(mOlamiVoiceRecognizerListener)
//設置支持的語言類型,默認請設置簡體中文
mOlamiVoiceRecognizer!!.setLocalization(
OlamiVoiceRecognizer.LANGUAGE_SIMPLIFIED_CHINESE)
mOlamiVoiceRecognizer!!.setAuthorization("51a4bb56ba954655a4fc834bfdc46af1",
"asr", "68bff251789b426896e70e888f919a6d", "nli")
//注冊Appkey,在olami官網注冊應用后生成的appkey
//注冊api,請直接填寫“asr”,標識語音識別類型
//注冊secret,在olami官網注冊應用后生成的secret
mOlamiVoiceRecognizer!!.setVADTailTimeout(2000)
//錄音時尾音結束時間,建議填//2000ms
mOlamiVoiceRecognizer!!.setLatitudeAndLongitude(
31.155364678184498, 121.34882432933009)
//設置經緯度信息,不愿上傳位置信息,可以填0
}
代碼比較簡單,點擊開始錄音button后,啟動錄音,在OlamiVoiceRecognizerListener中回調處理,然后通過handler發送消息用于更新界面。
來看一下初始化view的代碼,看看跟java方式書寫有哪些不同
private fun initView()
{
mBtnStart = findViewById(R.id.btn_start) asButton
mBtnStop = findViewById(R.id.btn_stop) as Button
mBtnCancel = findViewById(R.id.btn_cancel) asButton
mBtnSend = findViewById(R.id.btn_send) as Button
mInputTextView = findViewById(R.id.tv_inputText) asTextView
mEditText = findViewById(R.id.et_content) asEditText
mTextView = findViewById(R.id.tv_result) asTextView
mTextViewVolume = findViewById(R.id.tv_volume) asTextView
mBtnStart!!.setOnClickListener {
if (mOlamiVoiceRecognizer != null)
mOlamiVoiceRecognizer!!.start()
}
mBtnStop!!.setOnClickListener {
if (mOlamiVoiceRecognizer != null)
mOlamiVoiceRecognizer!!.stop()
mBtnStart!!.text = "開始"
Log.i("led", "MusicActivity mBtnStop onclick 開始")
}
mBtnCancel!!.setOnClickListener {
if (mOlamiVoiceRecognizer != null)
mOlamiVoiceRecognizer!!.cancel()
}
mBtnSend!!.setOnClickListener {
if (mOlamiVoiceRecognizer != null)
mOlamiVoiceRecognizer!!.sendText(mEditText!!.text.toString())
mInputTextView!!.text = "輸入: " + mEditText!!.text
}
}
是不是感覺代碼更簡練了?
下面兩句賦值,效果相同,第二句可以用id之間進行文本賦值,比以前簡練好多。
mInputTextView!!.text = "輸入: " + mEditText!!.text
tv_inputText.text ="輸入: " + et_content.text
再來看看handler:
private funinitHandler() {
mHandler = object : Handler() {
override fun handleMessage(msg:Message) {
when (msg.what) {
MessageConst.CLIENT_ACTION_START_RECORED-> mBtnStart!!.text
= "錄音中"
MessageConst.CLIENT_ACTION_STOP_RECORED -> mBtnStart!!.text
= "識別中"
MessageConst.CLIENT_ACTION_CANCEL_RECORED-> {
mBtnStart!!.text = "開始"
mTextView!!.text = "已取消"
}
MessageConst.CLIENT_ACTION_ON_ERROR-> {
mTextView!!.text = "錯誤代碼:" + msg.arg1
mBtnStart!!.text = "開始"
}
MessageConst.CLIENT_ACTION_UPDATA_VOLUME-> mTextViewVolume!!.text
= "音量: " + msg.arg1
MessageConst.SERVER_ACTION_RETURN_RESULT-> {
if (msg.obj != null)
mTextView!!.text = "服務器返回: " + msg.obj.toString()
mBtnStart!!.text = "開始"
try {
val message = msg.obj as String
var input: String?= null
val jsonObject =JSONObject(message)
val jArrayNli =
jsonObject.optJSONObject("data").optJSONArray("nli")
val jObj =jArrayNli.optJSONObject(0)
var jArraySemantic:JSONArray? = null
if (message.contains("semantic")) {
jArraySemantic= jObj.getJSONArray("semantic")
input =
jArraySemantic!!.optJSONObject(0).optString("input")
} else {
input = jsonObject.optJSONObject("data")
.optJSONObject("asr").optString("result")
}
if (input != null)
mInputTextView!!.text ="輸入: " + input
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
}
}
原來的switch case的方式,變成了when***,代碼不僅簡練,更貼近現代語言,更容易理解。
上面的MessageConst.SERVER_ACTION_RETURN_RESULT時,獲取了服務器返回的結果,緊接著對這段語義進行了簡單的解析
{
"data": {
"asr": {
"result": "我要聽三國演義",
"speech_status": 0,
"final": true,
"status": 0
},
"nli": [
{
"desc_obj": {
"result": "正在努力搜索中,請稍等",
"status": 0
},
"semantic": [
{
"app": "musiccontrol",
"input": "我要聽三國演義",
"slots": [
{
"name": "songname",
"value": "三國演義"
}
],
"modifier": [
"play"
],
"customer": "58df512384ae11f0bb7b487e"
}
],
"type": "musiccontrol"
}
]
},
"status": "ok"
}
1)解析出nli中type類型是musiccontrol,這是語法返回app的類型,而這個在線聽書的demo只關心musiccontrol這個app類型,其他的忽略。
2)用戶說的話轉成文字是在asr中的result中獲取
3)在nli中的semantic中,input值是用戶說的話,同asr中的result。
modifier代表返回的行為動作,此處可以看到是play就是要求播放,slots中的數據表示歌曲名稱是三國演義。
那么動作是play,內容是歌曲名稱是三國演義,在這個demo中調用
mBookUtil.searchBookAndPlay(songName,0,0);會先查詢,查詢到結果會再發播放消息要求播放,我要聽三國演義這個流程就走完了。
這段是在線聽書應用中的語義解析,詳情請看博客:http://blog.csdn.net/ls0609/article/details/71519203
用Koltlin實現android平臺語音識別語義理解
語音在線聽書博客:http://blog.csdn.net/ls0609/article/details/71519203
語音記賬demo:http://blog.csdn.net/ls0609/article/details/72765789
基于JavaScript用olamisdk實現web端語音識別語義理解(speex壓縮)
http://blog.csdn.net/ls0609/article/details/73920229
olami開放平臺語法編寫簡介:http://blog.csdn.net/ls0609/article/details/71624340
olami開放平臺語法官方介紹:https://cn.olami.ai/wiki/?mp=nli&content=nli2.html
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。