
# 流式一句话
#### 功能介绍
流式一句话模式的语音长度限制为一分钟，适合于对话聊天等识别场景。
该接口支持用户将一整段语音分段，以流式输入，最后得到识别结果。实时语音识别引擎在获得分段的输入语音的同时，就可以同步地对这段数据进行特征提取和解码工作，而不用等到所有数据都获得后再开始工作。因此这样就可以在最后一段语音结束后，仅延迟很短的时间（即等待处理最后一段语音数据以及获取最终结果的时间）即可返回最终识别结果。这种流式输入方式能缩短整体上获得最终结果的时间，极大地提升用户体验。
#### wss-URI
- wss-URI格式 wss /v1/{project_id}/rasr/short-stream
  

- 参数说明
  表1参数说明 
  | 参数名        | 是否必选 | 说明                                                                               |
  |:---|:---|:---|
  | project_id | 是    | 项目编号。获取方法，请参见[获取项目ID](https://support.huaweicloud.com/api-sis/sis_03_0008.html)。 |
     
  表2请求Header参数 
  | 参数                    | 是否必选 | 参数类型   | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
  |:---|:---|:---|:---|
  | X-Auth-Token          | 是    | String | 用户Token。 用于获取操作API的权限。获取方法请参见[认证鉴权](https://support.huaweicloud.com/api-sis/sis_03_0058.html)。响应消息头中X-Subject-Token的值即为Token。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
  | Enterprise-Project-Id | 否    | String | 企业项目ID。SIS支持通过企业项目管理（EPS）对不同用户组和用户的资源使用，进行分账。 获取方法：进入"[企业项目管理](https://console.huaweicloud.com/eps/?#/eps/manager/projects)"页面，单击企业项目名称，在企业项目详情页获取Enterprise-Project-Id（企业项目ID）。 ![](https://support.huaweicloud.com/api-sis/zh-cn_image_0000001902373765.png "点击放大") 企业项目创建步骤请参见用户指南。 说明： 账户创建企业项目后，在传参时，有以下三类场景。 - 携带正确的ID，正常使用SIS服务，账单归到企业ID对应的企业项目中。  - 携带错误的ID，正常使用SIS服务，账单的企业项目会被分类为"default"。  - 不携带ID，正常使用SIS服务，账单的企业项目会被分类为"default"。   |
     
  
- 请求示例（伪码）
  ```
  wss://{endpoint}/v1/{project_id}/rasr/short-stream
  Request Header:
  X-Auth-Token: MIINRwYJKoZIhvcNAQcCoIINODCCDTQCAQExDTALBglghkgBZQMEAgEwgguVBgkqhkiG...
  ```
  ![](https://support.huaweicloud.com/api-sis/public_sys-resources/note_3.0-zh-cn.png)
  "endpoint"即调用API的请求地址，不同接口不同区域的"endpoint"不同，具体请参见[终端节点](https://support.huaweicloud.com/api-sis/sis_03_0004.html)。
  
- Python3语言请求代码示例
  ```
  # -*- coding: utf-8 -*-
  # 此demo仅供测试使用，强烈建议使用sdk。需提前安装websocket-client, 执行pip install websocket-client
  import websocket
  import threading
  import time
  import json
  def rasr_demo():
      url = "wss://{{endpoint}}/v1/{{project_id}}/rasr/short-stream"  # endpoint和project_id需替换
      audio_path = "音频路径"
      token = "用户对应region的token"
      header = {
          "X-Auth-Token": token
      }
      with open(audio_path, "rb") as f:
          data = f.read()
      body = {
          "command": "START",
          "config": {
              "audio_format": "pcm8k16bit",
              "property": "chinese_8k_general"
          }
      }
      def _on_message(ws, message):
          print(message)
      def _on_error(ws, error):
          print(error)
      ws = websocket.WebSocketApp(url, header, on_message=_on_message, on_error=_on_error)
      _thread = threading.Thread(target=ws.run_forever, args=(None, None, 30, 20))
      _thread.start()
      time.sleep(1)
      ws.send(json.dumps(body), opcode=websocket.ABNF.OPCODE_TEXT)
      now_index = 0
      byte_len = 4000
      while now_index < len(data):
          next_index = now_index + byte_len
          if next_index > len(data):
              next_index = len(data)
          send_array = data[now_index: next_index]
          ws.send(send_array, opcode=websocket.ABNF.OPCODE_BINARY)
          now_index += byte_len
          time.sleep(0.05)
      ws.send("{\"command\": \"END\", \"cancel\": \"false\"}", opcode=websocket.ABNF.OPCODE_TEXT)
      time.sleep(10)
      ws.close()
  if __name__ == '__main__':
      rasr_demo()
  ```
  
- Java语言请求代码示例
  ```
  import okhttp3.OkHttpClient;
  import okhttp3.Request;
  import okhttp3.Response;
  import okhttp3.WebSocket;
  import okhttp3.WebSocketListener;
  import okio.ByteString;
  import java.net.URL;
  /**
   * 此demo仅供测试使用，强烈建议使用SDK
   * 使用前需已配置okhttp、okio jar包。jar包可通过下载SDK获取。
   */
  public class RasrDemo {
    public void rasrDemo() {
      try {
        // endpoint和projectId需要替换成实际信息。
        String url = "wss://{{endpoint}}/v1/{{project_id}}/rasr/short-stream";
        String token = "对应region的token";
        byte[] data = null;  // 存放将要发送音频的byte数组
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url).header("X-Auth-Token", token).build();
        WebSocket webSocket = okHttpClient.newWebSocket(request, new MyListener());
        webSocket.send("{\"command\": \"START\", \"config\": {\"audio_format\": \"pcm8k16bit\", \"property\": \"chinese_8k_general\"}}");
        webSocket.send(ByteString.of(data));
        webSocket.send("{  \"command\": \"END\",  \"cancel\": false}");
        Thread.sleep(10000);
        webSocket.close(1000, null);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    class MyListener extends WebSocketListener {
      @Override
      public void onOpen(WebSocket webSocket, Response response) {
        System.out.println("connected");
      }
      @Override
      public void onClosed(WebSocket webSocket, int code, String reason) {
        System.out.println("closed");
      }
      @Override
      public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        t.printStackTrace();
      }
      @Override
      public void onMessage(WebSocket webSocket, String text) {
        System.out.println(text);
      }
    }
    public static void main(String[] args) {
      RasrDemo rasrDemo = new RasrDemo();
      rasrDemo.rasrDemo();
    }
  }
  ```
  
- JavaScript（nodejs推荐使用v18.20.2 (LTS)版本）
  ```
  // 导入 Node.js 的 ws 库
  const WebSocket = require("ws");
  function shortStreamDemo(endpoint,audioPath, projectID, token) {
      const url = "wss://${endpoint}/v1/${projectID}/rasr/short-stream";  // 替换 endpoint 和 projectID
      // 读取音频文件内容
      const fs = require("fs");
      let data = fs.readFileSync(audioPath);
      // HTTP Headers中携带Token
      const headers = {
          "X-Auth-Token": token,
          // 企业id 可选加
          // "Enterprise-Project-Id": 企业id
      };
      // 创建WebSocket实例
      const ws = new WebSocket(url, {
          headers // 添加自定义HTTP头
      });
      ws.on("open", async () => {
          const body = {
              command: "START",
              config: {
                  audio_format: "pcm16k16bit",
                  property: "chinese_16k_general"
              }
          };
          ws.send(JSON.stringify(body));
          let nowIndex = 0;
          const byteLen = 3200; // 禁止空值输入 建议范围 2000-10000
          while (nowIndex < data.length) {
              const nextIndex = nowIndex + byteLen;
              const sendArray = data.slice(nowIndex, nextIndex > data.length ? data.length : nextIndex);
              ws.send(sendArray, { binary: true });
              nowIndex += byteLen;
              await new Promise(resolve => setTimeout(resolve, 100)); // 模拟延时(单位ms)
          }
          const endCommand = JSON.stringify({ command: "END", cancel: "false" });
          ws.send(endCommand);
      });
      ws.on("message", (data) => {
          if (data instanceof Buffer) {
              // 将Buffer转换为UTF-8编码的字符串
              const messageString = data.toString("utf8");
              console.log("Received (converted from Buffer):", messageString);
              const type = JSON.parse(messageString).resp_type;
              if (type ==="END"|| type ==="ERROR") {
                  ws.close();
              }
          }
      });
      ws.on("error", (error) => {
          console.error("WebSocket Error:", error);
      });
  };
  shortStreamDemo(endpoint,audioPath, projectID, token);
  ```
  
 
