private async Task <ResultModel <string> > DoFragmentAsr(byte[] data, FrameState state = FrameState.First) { try { if (_ws == null && _status == FrameState.First) { _ws = new ClientWebSocket(); _status = FrameState.First; _host = ApiAuthorization.BuildAuthUrl(_settings); await _ws.ConnectAsync(new Uri(_host), CancellationToken.None); if (_ws.State != WebSocketState.Open) { throw new Exception("Connect to xfyun api server failed."); } _receiveTask = StartReceiving(_ws); } //开始发送数据 for (int i = 0; i < data.Length; i += _frameSize) { byte[] buffer = null; if (_rest.Length == 0) //没有上次分片的数据 { if (data.Length - i < _frameSize) //最后一帧不满一个完整的识别帧,那么加入缓存,下个分片的时候继续使用 { if (state != FrameState.Last) { int length = data.Length - i; Array.Copy(data, i, _rest.Cache, 0, length); _rest.Length = length; } else { buffer = SubArray(data, i, _frameSize); _status = FrameState.Last; } } else { buffer = SubArray(data, i, _frameSize); if (state == FrameState.Last && data.Length - i == _frameSize) { _status = FrameState.Last; if (buffer == null) { buffer = new byte[1] { 0 }; } } } } else //有上次分片的数据 { if (data.Length + _rest.Length <= _frameSize) { buffer = new byte[_rest.Length + data.Length]; Array.Copy(_rest.Cache, 0, buffer, 0, _rest.Length); //最后分片加上缓存不满一个帧大小的情况 Array.Copy(data, i, buffer, _rest.Length, data.Length); _status = FrameState.Last; i = data.Length - _frameSize; } else { buffer = new byte[_frameSize]; Array.Copy(_rest.Cache, 0, buffer, 0, _rest.Length); Array.Copy(data, i, buffer, _rest.Length, _frameSize - _rest.Length); i -= _rest.Length; } _rest.Clear(); //清空 } if (_rest.Length != 0) { break; } switch (_status) { case FrameState.First: FirstFrameData firstFrame = new FirstFrameData { common = _common, business = _business, data = _data }; firstFrame.data.status = FrameState.First; firstFrame.data.audio = System.Convert.ToBase64String(buffer); await _ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(firstFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); _status = FrameState.Continue; break; case FrameState.Continue: //中间帧 ContinueFrameData continueFrame = new ContinueFrameData { data = _data }; continueFrame.data.status = FrameState.Continue; continueFrame.data.audio = System.Convert.ToBase64String(buffer); await _ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(continueFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); break; case FrameState.Last: // 最后一帧音频 LastFrameData lastFrame = new LastFrameData { data = _data }; lastFrame.data.status = FrameState.Last; lastFrame.data.audio = System.Convert.ToBase64String(buffer); await _ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(lastFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); break; } await Task.Delay(_intervel); } if (state == FrameState.Last) { while (_receiveTask.Status != TaskStatus.RanToCompletion) { await Task.Delay(10); } await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "NormalClosure", CancellationToken.None); } return(new ResultModel <string>() { Code = ResultCode.Success, Data = null, }); } catch (Exception ex) { //服务器主动断开连接或者自动断开连接了 if (ex.Message.ToLower().Contains("unable to read data from the transport connection")) { try { await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "NormalClosure", CancellationToken.None); } catch { } while (_receiveTask.Status != TaskStatus.RanToCompletion) { await Task.Delay(10); } return(new ResultModel <string>() { Code = ResultCode.Disconnect, Message = "服务器主动断开连接,可能是整个会话是否已经超过了60s、读取数据超时、静默检测超时等原因引起的。", }); } else { return(new ResultModel <string>() { Code = ResultCode.Error, Message = ex.Message, }); } } }
/// <summary> /// 语音转写一个完整的音频文件 /// </summary> /// <param name="data"></param> /// <returns></returns> public async Task <ResultModel <string> > ConvertAudio(byte[] data) { try { using (_ws = new ClientWebSocket()) { Status = ServiceStatus.Running; _host = ApiAuthorization.BuildAuthUrl(_settings); await _ws.ConnectAsync(new Uri(_host), CancellationToken.None); _receiveTask = StartReceiving(_ws); //开始发送数据 for (int i = 0; i < data.Length; i += _frameSize) { byte[] buffer = SubArray(data, i, _frameSize); if (buffer == null || data.Length - i < _frameSize) { _status = FrameState.Last; //文件读完 } switch (_status) { case FrameState.First: FirstFrameData firstFrame = new FirstFrameData { common = _common, business = _business, data = _data }; firstFrame.data.status = FrameState.First; firstFrame.data.audio = System.Convert.ToBase64String(buffer); await _ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(firstFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); _status = FrameState.Continue; break; case FrameState.Continue: //中间帧 ContinueFrameData continueFrame = new ContinueFrameData { data = _data }; continueFrame.data.status = FrameState.Continue; continueFrame.data.audio = System.Convert.ToBase64String(buffer); await _ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(continueFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); break; case FrameState.Last: // 最后一帧音频 LastFrameData lastFrame = new LastFrameData { data = _data }; lastFrame.data.status = FrameState.Last; lastFrame.data.audio = System.Convert.ToBase64String(buffer); await _ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(lastFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); break; } await Task.Delay(_intervel); } while (_receiveTask.Status != TaskStatus.RanToCompletion) { await Task.Delay(10); } await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "NormalClosure", CancellationToken.None); } StringBuilder result = new StringBuilder(); foreach (var item in _result) { result.Append(item.data); } ResetState(); return(new ResultModel <string>() { Code = ResultCode.Success, Data = result.ToString(), }); } catch (Exception ex) { return(new ResultModel <string>() { Code = ResultCode.Error, Message = ex.Message, }); } }
public async Task <ResultModel <string> > Convert(byte[] data) { try { int frameSize = 1280, intervel = 10; FrameState status = FrameState.First; string host = BuildAuthUrl(); using (var ws = new ClientWebSocket()) { await ws.ConnectAsync(new Uri(host), CancellationToken.None); StartReceiving(ws); //开始发送数据 for (int i = 0; i < data.Length; i += frameSize) { byte[] buffer = SubArray(data, i, frameSize); if (buffer == null) { status = FrameState.Last; //文件读完 } switch (status) { case FrameState.First: FirstFrameData firstFrame = new FirstFrameData { common = _common, business = _business, data = _data }; firstFrame.data.status = FrameState.First; firstFrame.data.audio = System.Convert.ToBase64String(buffer); await ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonHelper.SerializeObject(firstFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); status = FrameState.Continue; break; case FrameState.Continue: //中间帧 ContinueFrameData continueFrame = new ContinueFrameData { data = _data }; continueFrame.data.status = FrameState.Continue; continueFrame.data.audio = System.Convert.ToBase64String(buffer); await ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonHelper.SerializeObject(continueFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); break; case FrameState.Last: // 最后一帧音频 LastFrameData lastFrame = new LastFrameData { data = _data }; lastFrame.data.status = FrameState.Last; lastFrame.data.audio = System.Convert.ToBase64String(buffer); await ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonHelper.SerializeObject(lastFrame))) , WebSocketMessageType.Text , true , CancellationToken.None); break; } await Task.Delay(intervel); } } return(new ResultModel <string>() { Code = ResultCode.Success, Data = _resultStringBuilder == null ? "" : _resultStringBuilder.ToString(), }); } catch (Exception ex) { return(new ResultModel <string>() { Code = ResultCode.Error, Message = ex.Message, }); } }