|
|
|
@ -4,11 +4,12 @@ import android.content.Context |
|
|
|
import android.util.Base64 |
|
|
|
import android.util.Log |
|
|
|
import okhttp3.* |
|
|
|
import okio.ByteString |
|
|
|
import okio.ByteString.Companion.toByteString |
|
|
|
import org.json.JSONObject |
|
|
|
import java.net.URLEncoder |
|
|
|
import java.nio.charset.StandardCharsets |
|
|
|
import java.security.MessageDigest |
|
|
|
import java.util.UUID |
|
|
|
import javax.crypto.Mac |
|
|
|
import javax.crypto.spec.SecretKeySpec |
|
|
|
|
|
|
|
@ -16,77 +17,62 @@ class XunFeiAsrHelper(private val context: Context) { |
|
|
|
private val tag = "XunFeiAsrHelper" |
|
|
|
|
|
|
|
private val appId = "43d87d22" |
|
|
|
private val accessKeyId = "2bd01ce06ac35957fc0c082f9b6284ec" |
|
|
|
private val accessKeyId = "83f063755e8d342670002f50a4471d42" |
|
|
|
|
|
|
|
private var webSocket: WebSocket? = null |
|
|
|
private val client = OkHttpClient() |
|
|
|
|
|
|
|
// Status: "UNDEFINED", "CONNECTING", "OPEN", "CLOSING", "CLOSED" |
|
|
|
private var btnStatus = "UNDEFINED" |
|
|
|
private var currentSessionId = "" |
|
|
|
|
|
|
|
private var resultText = "" |
|
|
|
fun start(callback: AzureAsrHelper.ContinuousRecognizeCallback) { |
|
|
|
currentSessionId = UUID.randomUUID().toString() |
|
|
|
|
|
|
|
var onResult: ((String) -> Unit)? = null |
|
|
|
var onError: ((String) -> Unit)? = null |
|
|
|
var onStatusChange: ((String) -> Unit)? = null |
|
|
|
|
|
|
|
fun connectWebSocket() { |
|
|
|
val url = getWebSocketUrl() |
|
|
|
val request = Request.Builder().url(url).build() |
|
|
|
|
|
|
|
changeBtnStatus("CONNECTING") |
|
|
|
|
|
|
|
webSocket = client.newWebSocket(request, object : WebSocketListener() { |
|
|
|
override fun onOpen(webSocket: WebSocket, response: Response) { |
|
|
|
Log.d(tag, "WebSocket Opened") |
|
|
|
changeBtnStatus("OPEN") |
|
|
|
callback.onSessionStarted(currentSessionId) |
|
|
|
} |
|
|
|
|
|
|
|
override fun onMessage(webSocket: WebSocket, text: String) { |
|
|
|
renderResult(text) |
|
|
|
renderResult(text, callback) |
|
|
|
} |
|
|
|
|
|
|
|
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) { |
|
|
|
Log.d(tag, "WebSocket Closing: $code / $reason") |
|
|
|
changeBtnStatus("CLOSING") |
|
|
|
webSocket.close(1000, null) |
|
|
|
} |
|
|
|
|
|
|
|
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { |
|
|
|
Log.d(tag, "WebSocket Closed: $code / $reason") |
|
|
|
changeBtnStatus("CLOSED") |
|
|
|
callback.onSessionStopped(currentSessionId) |
|
|
|
} |
|
|
|
|
|
|
|
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) { |
|
|
|
Log.e(tag, "WebSocket Error", t) |
|
|
|
changeBtnStatus("CLOSED") |
|
|
|
onError?.invoke(t.message ?: "WebSocket connection failed") |
|
|
|
callback.onError(currentSessionId, 1004, "Xunfei connection failed: ${t.message}") |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
fun sendAudio(frameBuffer: ByteArray) { |
|
|
|
webSocket?.let { ws -> |
|
|
|
ws.send(ByteString.of(frameBuffer, 0, frameBuffer.size)) |
|
|
|
webSocket?.let { ws: WebSocket -> |
|
|
|
ws.send(frameBuffer.toByteString(0, frameBuffer.size)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fun close() { |
|
|
|
webSocket?.let { ws -> |
|
|
|
fun stop() { |
|
|
|
webSocket?.let { ws: WebSocket -> |
|
|
|
ws.send("{\"end\": true}") |
|
|
|
changeBtnStatus("CLOSING") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private fun changeBtnStatus(status: String) { |
|
|
|
btnStatus = status |
|
|
|
if (status == "CONNECTING") { |
|
|
|
resultText = "" |
|
|
|
} |
|
|
|
onStatusChange?.invoke(status) |
|
|
|
} |
|
|
|
|
|
|
|
private fun renderResult(resultData: String) { |
|
|
|
private fun renderResult( |
|
|
|
resultData: String, |
|
|
|
callback: AzureAsrHelper.ContinuousRecognizeCallback |
|
|
|
) { |
|
|
|
try { |
|
|
|
val jsonData = JSONObject(resultData) |
|
|
|
val action = jsonData.optString("action") |
|
|
|
@ -120,16 +106,15 @@ class XunFeiAsrHelper(private val context: Context) { |
|
|
|
} |
|
|
|
|
|
|
|
if (st.optInt("type") == 0) { |
|
|
|
resultText += resultTextTemp |
|
|
|
onResult?.invoke(resultText) |
|
|
|
callback.onResult(currentSessionId, resultTextTemp, "zh-CN") |
|
|
|
} else { |
|
|
|
onResult?.invoke(resultText + resultTextTemp) |
|
|
|
callback.onRecognizing(currentSessionId, resultTextTemp, "zh-CN") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
"error" -> { |
|
|
|
Log.e(tag, "Error: $resultData") |
|
|
|
onError?.invoke(jsonData.toString()) |
|
|
|
callback.onError(currentSessionId, 1005, "Xunfei error: $resultData") |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e: Exception) { |
|
|
|
|