WebSocket系列:Android端Websocket实时语音识别

Posted zhangjin1120

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebSocket系列:Android端Websocket实时语音识别相关的知识,希望对你有一定的参考价值。

看效果图:

  • 网络权限:
<uses-permission android:name="android.permission.INTERNET" />
  • 导入WebSocket和fastjson
    implementation "org.java-websocket:Java-WebSocket:1.3.4"
    implementation 'com.alibaba:fastjson:1.2.21'
  • MainActivity.java代码:
public class MainActivity extends AppCompatActivity {
    private static final String BASE_URL = "wss://zjexample.cn:5005/asr"; //这个地址是假的哈,找后端同事要。
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SSS");

    // 每次发送的数据大小 1280 字节
    private static final int CHUNK_SIZE = 1280;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    startLoop();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void startLoop() throws Exception {
        while (true) {
            URI url = new URI(BASE_URL);
            CountDownLatch handshakeSuccess = new CountDownLatch(1);
            CountDownLatch connectClose = new CountDownLatch(1);
            MyWebSocketClient webSocketClient = new MyWebSocketClient(url, handshakeSuccess, connectClose);
            webSocketClient.connect();

            while (!webSocketClient.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
                System.out.println(getCurrentTimeStr() + "\\t连接中");
                Thread.sleep(1000);
            }

            // 等待握手成功
            handshakeSuccess.await();
            // 发送文本内容
            webSocketClient.send("{\\"update\\":true,\\"text\\":\\"I have a good friend\\"}");
            System.out.println(sdf.format(new Date()) + " 开始发送音频数据");
            // 发送音频
            byte[] bytes = new byte[CHUNK_SIZE];
            try {
                InputStream is = getResources().getAssets().open("record_pcm.pcm");
                int len = -1;
                long lastTs = 0;
                while ((len = is.read(bytes)) != -1) {
                    if (len < CHUNK_SIZE) {
                        send(webSocketClient, bytes = Arrays.copyOfRange(bytes, 0, len));
                        break;
                    }
                    long curTs = System.currentTimeMillis();
                    if (lastTs == 0) {
                        lastTs = System.currentTimeMillis();
                    } else {
                        long s = curTs - lastTs;
                        if (s < 40) {
                            System.out.println("error time interval: " + s + " ms");
                        }
                    }
                    send(webSocketClient, bytes);
                    // 每隔40毫秒发送一次数据
                    Thread.sleep(40);
                }

                // 发送结束标识
                webSocketClient.send("{ \\"final\\":true, \\"text\\":\\"I have a good friend.\\" }");
                System.out.println(getCurrentTimeStr() + "\\t发送结束标识完成");
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 等待连接关闭
            connectClose.await();
            break;
        }
    }

    public static void send(WebSocketClient client, byte[] bytes) {
        if (client.isClosed()) {
            throw new RuntimeException("client connect closed!");
        }
        client.send(bytes);
    }

    public static String getCurrentTimeStr() {
        return sdf.format(new Date());
    }


    public static class MyWebSocketClient extends WebSocketClient {
        private CountDownLatch connectClose;
        private CountDownLatch handshakeSuccess;

        public MyWebSocketClient(URI serverUri, CountDownLatch handshakeSuccess, CountDownLatch connectClose) {
            super(serverUri);
            this.handshakeSuccess = handshakeSuccess;
            this.connectClose = connectClose;
            if(serverUri.toString().contains("wss")){
                trustAllHosts(this);
            }
        }

        @Override
        public void onOpen(ServerHandshake handshake) {
            System.out.println(getCurrentTimeStr() + "\\t连接建立成功!");
        }

        @Override
        public void onMessage(String msg) {
            System.out.println(msg);
            JSONObject msgObj = JSON.parseObject(msg);
            String action = msgObj.getString("action");
            if (Objects.equals("started", action)) {
                // 握手成功
                System.out.println(getCurrentTimeStr() + "\\t握手成功!sid: " + msgObj.getString("sid"));
                handshakeSuccess.countDown();
            } else if (Objects.equals("result", action)) {
                // 转写结果
//                System.out.println(getCurrentTimeStr() + "\\tresult: " + getContent(msgObj.getString("data")));
            } else if (Objects.equals("error", action)) {
                // 连接发生错误
                System.out.println("Error: " + msg);
                System.exit(0);
            }
        }

        @Override
        public void onError(Exception e) {
            System.out.println(getCurrentTimeStr() + "\\t连接发生错误:" + e.getMessage() + ", " + new Date());
            e.printStackTrace();
            System.exit(0);
        }

        @Override
        public void onClose(int arg0, String arg1, boolean arg2) {
            System.out.println(getCurrentTimeStr() + "\\t链接关闭");
            connectClose.countDown();
        }

        @Override
        public void onMessage(ByteBuffer bytes) {
            try {
                System.out.println(getCurrentTimeStr() + "\\t服务端返回:" + new String(bytes.array(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        public void trustAllHosts(MyWebSocketClient appClient) {
            System.out.println("wss");
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[]{};
                }

                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }
            }};

            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                appClient.setSocket(sc.getSocketFactory().createSocket());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

以上是关于WebSocket系列:Android端Websocket实时语音识别的主要内容,如果未能解决你的问题,请参考以下文章

WebSocket服务端和客户端代码示例

从零玩转Websocket实时通讯服务之前后端分离版本-websocket

nodejs-websocket介绍

springboot整合webSocket(看完即入门)

WebSocket 实战

WebSocket入门及使用指南