我正在尝试使用针对Xamarin Android的Microsoft认知语音从麦克风构建连续语音识别。我不认为Xamarin有图书馆。文档是:https://docs.microsoft.com/en-us/azure/cognitive-services/speech/api-reference-rest/websocketprotocol
我已经完成了websocket连接的事情,现在我非常坚持将消息发送到websocket服务器。我在文档中注意到了
每次发送消息时,我们都必须在特定路径上发送标题
例如,这些标题是设置语音协议的第一个配置,
Path : speech.config
X-Timestamp : Client UTC clock time stamp in ISO 8601 format
Content-Type : application/json; charset=utf-8
我正在使用 WebSocketClient ,但我找不到任何设置标头或更改路径的方法。有没有办法设置标题和/或更改路径,以便我可以正确地向服务器发送消息?或者我有错误的看法?
我的第二个问题是 WebSocketClient 没有任何事件处理程序来接收消息,我的工作是:
private static async Task DataReceiving(ClientWebSocket ws)
{
while (true)
{
ArraySegment<byte> bytesReceived = new ArraySegment<byte>(new byte[1024]);
WebSocketReceiveResult result = await ws.ReceiveAsync(
bytesReceived, CancellationToken.None);
Log.Info("SOCKETRECEIVED",Encoding.UTF8.GetString(bytesReceived.Array, 0, result.Count));
if (ws.State != WebSocketState.Open)
{
Log.Info("SOCKETCLOSED", "CLOSED");
break;
}
}
}
但我没有收到任何消息或任何消息。
编辑:
以下是标题的代码,
//List<Tuple<string, string>> Headers <<Contains [Title] and [Content]
foreach (var item in Headers)
{
message += item.Item1 + " : " + item.Item2 + Environment.NewLine;
}
message += Environment.Newline; // ensure double carriage return
编辑: 这是我发送WAV标题的代码:
using (MemoryStream stream = new MemoryStream())
{
short channelCount = 1;
int sampleRate = 1024;
int bitsPerSample = 16;
using (var writer = new BinaryWriter(stream, Encoding.UTF8))
{
writer.Write("Path: audio"+Environment.NewLine);
writer.Write("X-Timestamp: " + DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"+Environment.NewLine));
writer.Write("Content-Type : audio/x-wav"+Environment.NewLine);
writer.Write("X-RequestId: " + Guid.NewGuid().ToString().Replace("-",string.Empty)+Environment.NewLine);
writer.Write(Environment.NewLine);
//chunk ID
writer.Write('R');
writer.Write('I');
writer.Write('F');
writer.Write('F');
writer.Write(-1); // -1 - Unknown size
//format
writer.Write('W');
writer.Write('A');
writer.Write('V');
writer.Write('E');
//subchunk 1 ID
writer.Write('f');
writer.Write('m');
writer.Write('t');
writer.Write(' ');
writer.Write(16); //subchunk 1 (fmt) size
writer.Write((short)1); //PCM audio format
writer.Write((short)channelCount);
writer.Write(sampleRate);
writer.Write(sampleRate * 2);
writer.Write((short)2); //block align
writer.Write((short)bitsPerSample);
//subchunk 2 ID
writer.Write('d');
writer.Write('a');
writer.Write('t');
writer.Write('a');
//subchunk 2 (data) size
writer.Write(-1); // -1 - Unknown size
}
byte[] result;
//using (MemoryStream ms = new MemoryStream())
//{
// stream.CopyTo(ms);
// result = ms.ToArray();
//}
result = stream.ToArray();
ArraySegment<byte> byteresult = new ArraySegment<byte>(result);
await _socketclient.SendAsync(byteresult, WebSocketMessageType.Binary, false, CancellationToken.None);
Log.Info("SENDINGWAV", System.Text.Encoding.UTF8.GetString(result));
}
这是我发送数据字节的代码,
public async Task SendByteHeader(byte[] data)
{
string s = "";
s+=("Path: audio" + Environment.NewLine);
s +=("X-Timestamp: " + DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ" + Environment.NewLine));
s +=("Content-Type : audio/x-wav" + Environment.NewLine);
s +=("X-RequestId: " + Guid.NewGuid().ToString().Replace("-", string.Empty) + Environment.NewLine);
s +=(Environment.NewLine);
byte[] array = Encoding.UTF8.GetBytes(s);
List<byte> endres = new List<byte>(array);
endres.AddRange(data);
ArraySegment<byte> byteresult = new ArraySegment<byte>(endres.ToArray());
await _socketclient.SendAsync(byteresult, WebSocketMessageType.Binary, false, CancellationToken.None);
Log.Info("SENDINGBYTE", Encoding.UTF8.GetString(data));
}
我在连接开始时运行它:
Task.Run(()=>DataReceiving(_socketclient));
所以,我首先发送了Wav头,然后开始从录制中发送音频字节(我正在使用Plugin.AudioRecording)。 我还没有收到任何消息/回复。
编辑:
我每200毫秒向服务器发送一些数据以使其“实时”,但我注意到在发送5-6之后,我的所有SendAsync都对此代码崩溃:
await _socketclient.SendAsync(byteresult, WebSocketMessageType.Binary, false, CancellationToken.None);
错误是“无法访问一次性对象(websocket)”。似乎websocket被处理了?或者连接被终止了?
答案 0 :(得分:2)
我正在使用WebSocketClient,但我找不到任何设置标头或更改路径的方法。有没有办法设置标题和/或更改路径,以便我可以正确地向服务器发送消息?或者我有错误的看法?
如果您参考所发布文档的TextWebSocket Message部分。您可以找到以下声明:
文本WebSocket消息携带文本信息的有效负载,该文本信息由一段标题和一个由用于HTTP消息的熟悉的双回车换行换行符分隔的主体组成。
这意味着,您使用client.SendAsync()
发送给服务的邮件可以包含两部分:标题部分和正文部分,两部分由double-carriage-return newline pair
分隔。
我的第二个问题是WebSocketClient没有任何事件处理程序来接收消息
关于此问题,您正确执行此操作,您可以在正确发送邮件后再次尝试。该服务将发回它识别的消息。