All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.nls.client.protocol.commonrequest.CommonRequest Maven / Gradle / Ivy

There is a newer version: 2.2.16
Show newest version
/*
 * Copyright 2015 Alibaba Group Holding Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nls.client.protocol.commonrequest;

import com.alibaba.nls.client.protocol.Constant;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.SpeechReqProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author weibing.dwb
 * @date 2020/2/6
 */
public class CommonRequest extends SpeechReqProtocol {
    static Logger logger = LoggerFactory.getLogger(CommonRequest.class);

    private CountDownLatch taskStartedLatch;
    private CountDownLatch taskStoppedLatch;
    protected long lastSendTime = -1;
    private String nameSpace;
    protected CommonRequestListener commonRequestListener;

    public CommonRequestListener getCommonRequestListener() {
        return commonRequestListener;
    }

    public CommonRequest(NlsClient client, CommonRequestListener listener, String nameSpace) throws Exception {
        this.conn = client.connect(listener);
        this.nameSpace = nameSpace;
        afterConnection(listener);
    }

    public CommonRequest(NlsClient client, String token, CommonRequestListener listener, String nameSpace) throws Exception {
        this.conn = client.connect(token, listener);
        this.nameSpace = nameSpace;
        afterConnection(listener);
    }

    protected void afterConnection(CommonRequestListener listener) {
        header.put(Constant.PROP_NAMESPACE, this.nameSpace);
        header.put(Constant.PROP_NAME, CommonRequestConstant.VALUE_NAME_START);
        payload = new HashMap<>();
        listener.setCommonRequest(this);
        commonRequestListener = listener;
        state = State.STATE_CONNECTED;
    }

    /**
     * 开始任务:发送任务请求,同步接收服务端确认
     * @throws Exception
     */
    @Override
    public void start() throws Exception {
        super.start();
        taskStartedLatch = new CountDownLatch(1);
        taskStoppedLatch = new CountDownLatch(1);
        boolean result = taskStartedLatch.await(10, TimeUnit.SECONDS);
        if (!result) {
            String msg = String.format("timeout after 10 seconds waiting for start confirmation.task_id:%s,state:%s",
                    currentTaskId, state);
            logger.error(msg);
            throw new Exception(msg);
        }
    }

    /**
     * 结束任务:发送结束任务通知,同步接收服务端确认
     * @throws Exception
     */
    public void stop() throws Exception {
        state.checkStop();
        SpeechReqProtocol req = new SpeechReqProtocol();
        req.header.put(Constant.PROP_NAMESPACE, this.nameSpace);
        req.header.put(Constant.PROP_NAME, CommonRequestConstant.VALUE_NAME_STOP);
        req.header.put(Constant.PROP_TASK_ID, currentTaskId);
        req.setAppKey(getAppKey());
        conn.sendText(req.serialize());
        state = State.STATE_STOP_SENT;
        boolean result = taskStoppedLatch.await(10, TimeUnit.SECONDS);
        if (!result) {
            String msg = String.format("timeout after 10 seconds waiting for complete confirmation.task_id:%s,state:%s",
                    currentTaskId, state);
            logger.error(msg);
            throw new Exception(msg);
        }
    }

    /**
     * 发送控制指令
     * @param directive
     * @param payload 如果不需要,传入null
     */
    public void sendDirective(String directive, Map payload) {
        SpeechReqProtocol req = new SpeechReqProtocol();
        req.header.put(Constant.PROP_NAMESPACE, this.nameSpace);
        req.header.put(Constant.PROP_NAME, directive);
        req.header.put(Constant.PROP_TASK_ID, currentTaskId);
        req.setAppKey(getAppKey());
        if (payload != null) {
            req.payload = payload;
        }
        conn.sendText(req.serialize());
    }

    /**
     * 自己控制发送,需要控制发送速率
     *
     * @param data
     */
    public void send(byte[] data) {
        long sendInterval;
        if (lastSendTime != -1 && (sendInterval=(System.currentTimeMillis() - lastSendTime)) > 5000) {
            logger.warn("too large binary send interval: {} million second",sendInterval);
        }
        state.checkSend();
        try {
            conn.sendBinary(Arrays.copyOfRange(data, 0, data.length));
            lastSendTime = System.currentTimeMillis();
        } catch (Exception e) {
            logger.error("fail to send binary,current_task_id:{},state:{}", currentTaskId, state, e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 实时采集音频流
     *
     * @param ins
     */
    public void send(InputStream ins) {
        state.checkSend();
        try {
            byte[] bytes = new byte[8000];
            int len = 0;
            long sendInterval;
            while ((len = ins.read(bytes)) > 0) {
                if (lastSendTime != -1 && (sendInterval=(System.currentTimeMillis() - lastSendTime)) > 5000) {
                    logger.warn("too large binary send interval: {} million second",sendInterval);
                }
                conn.sendBinary(Arrays.copyOfRange(bytes, 0, len));
                lastSendTime = System.currentTimeMillis();
            }
        } catch (Exception e) {
            logger.error("fail to send binary,current_task_id:{},state:{}", currentTaskId, state, e);
            throw new RuntimeException(e);

        }
    }

    /**
     * 语音数据来自文件,发送时需要控制速率,使单位时间内发送的数据大小接近单位时间原始语音数据存储的大小
     * 
    *
  • <对于8k pcm 编码数据,建议每发送3200字节 sleep 100 ms/li> *
  • 对于16k pcm 编码数据,建议每发送6400字节 sleep 200 ms/li> *
  • 对于其它编码格式的数据,用户根据压缩比,自行估算,比如压缩比为10:1的 16k opus ,需要每发送6400/10=640 sleep 200ms/li> *
* * @param ins 离线音频文件流 * @param batchSize 每次发送到服务端的数据大小 * @param sleepInterval 数据发送的间隔,即用于控制发送数据的速率,每次发送batchSize大小的数据后需要sleep的时间 */ public void send(InputStream ins, int batchSize, int sleepInterval) { state.checkSend(); try { byte[] bytes = new byte[batchSize]; int len = 0; long sendInterval; while ((len = ins.read(bytes)) > 0) { if (lastSendTime != -1 && (sendInterval=(System.currentTimeMillis() - lastSendTime)) > 5000) { logger.warn("too large binary send interval: {} million second",sendInterval); } conn.sendBinary(Arrays.copyOfRange(bytes, 0, len)); lastSendTime=System.currentTimeMillis(); Thread.sleep(sleepInterval); } } catch (Exception e) { logger.error("fail to send binary,current_task_id:{},state:{}", currentTaskId, state, e); throw new RuntimeException(e); } } /** * 关闭连接 */ public void close() { conn.close(); } /** * 服务端准备好了进行该任务 */ void markCommonRequestReady() { state = State.STATE_REQUEST_CONFIRMED; if (taskStartedLatch != null) { taskStartedLatch.countDown(); } } /** * 服务端停止了该任务 */ void markCommonRequestComplete() { state = State.STATE_COMPLETE; if (taskStoppedLatch != null) { taskStoppedLatch.countDown(); } } /** * 服务端返回错误 */ void markFailed() { state = State.STATE_FAIL; if (taskStartedLatch != null) { taskStartedLatch.countDown(); } if (taskStoppedLatch != null) { taskStoppedLatch.countDown(); } } /** * 内部调用 */ void markClosed() { state = State.STATE_CLOSED; if (taskStartedLatch != null) { taskStartedLatch.countDown(); } if (taskStoppedLatch != null) { taskStoppedLatch.countDown(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy