如何将实时音频流终结点连接到直线语音终结点?

问题描述 投票:1回答:1

[我正在尝试连接实时音频终结点,该终结点将与直接语音(DLS)终结点产生连续的音频流,并最终与Azure机器人api进行交互。

我有一个websocket API,可以连续接收二进制格式的音频流,这就是我打算将其转发到DLS端点,以便与我的机器人进行连续Speech2Text的过程。

基于反馈和answer here,我已经能够将实时语音端点与实时流连接起来。

我尝试了一个示例wav文件,该文件已被DLS正确转录,并且我的机器人可以正确检索文本以对其进行操作。

我已经使用ListenOnce() API,并且正在使用PushAudioInputStream方法将音频流推送到DLS语音端点。

下面的代码是ListenOnce()方法的内部

// Create a push stream
using (var pushStream = AudioInputStream.CreatePushStream())
{
    using (var audioInput = AudioConfig.FromStreamInput(pushStream))
    {
        // Create a new Dialog Service Connector
        this.connector = new DialogServiceConnector(dialogServiceConfig, audioInput);
        // ... also subscribe to events for this.connector

        // Open a connection to Direct Line Speech channel
        this.connector.ConnectAsync();
        Debug.WriteLine("Connecting to DLS");

        pushStream.Write(dataBuffer, dataBuffer.Length);

        try
        {
            this.connector.ListenOnceAsync();
            System.Diagnostics.Debug.WriteLine("Started ListenOnceAsync");
        }
    }
}

以上代码中的dataBuffer是我在Websocket上接收到的二进制数据的“块”。

const int maxMessageSize = 1024 * 4; // 4 bytes
var dataBuffer = new byte[maxMessageSize];

while (webSocket.State == WebSocketState.Open)
{
    var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(dataBuffer), CancellationToken.None);
    if (result.MessageType == WebSocketMessageType.Close)
    {
        Trace.WriteLine($"Received websocket close message: {result.CloseStatus.Value}, {result.CloseStatusDescription}");
        await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
    }
    else if (result.MessageType == WebSocketMessageType.Text)
    {
        var message = Encoding.UTF8.GetString(dataBuffer);
        Trace.WriteLine($"Received websocket text message: {message}");
    }
    else // binary
    {
        Trace.WriteLine("Received websocket binary message");
        ListenOnce(dataBuffer); //calls the above 
    }
}

但是以上代码不起作用。我相信我对此方法有几个问题/疑问-

  1. 我相信我没有正确地将数据分块到Direct Line Speech,以确保其接收到完整的音频以进行正确的S2T转换。
  2. 我知道DLS API支持ListenOnceAsync(),但不确定是否支持ASR(它知道另一侧的扬声器何时停止讲话)
  3. 我能否仅获取直接语音端点的websocket URL,并假设DLS正确使用了直接websocket流?
c# botframework microsoft-cognitive
1个回答
1
投票

我相信我没有正确地将数据分块到Direct Line Speech,以确保其接收到完整的音频以进行正确的S2T转换。

DialogServiceConnector.ListenOnceAsync会监听,直到关闭流(或检测到足够的静音)。除了在using块的末尾处理流之外,您不会关闭流。您可以等待ListenOnceAsync,但必须确保先关闭流。如果您不等待ListenOnceAsync,则可以随时关闭流,但是您可能应该在完成向流的写入后立即进行操作,并且必须确保不丢弃流(或ListenOnceAsync之前的配置)。

您还想确保ListenOnceAsync完整发声。如果一次只接收4个字节,那肯定不是一个完整的话语。如果您希望将块保持为4个字节,那么最好在该循环的多次迭代中保持ListenOnceAsync运行,而不是每获得4个字节就反复调用它。

我知道DLS API支持ListenOnceAsync(),但不确定是否支持ASR(它知道另一侧的扬声器何时停止讲话)

我认为您必须确定发言人何时停止在客户端停止讲话,然后从WebSocket收到消息,指示您应关闭ListenOnceAsync的音频流。

看起来ListenOnceAsync确实支持ASR。

我能否仅获取直接语音端点的websocket URL,并假设DLS正确使用了直接websocket流?

您可以尝试,但我不会认为自己。直线语音仍处于预览状态,我不认为兼容性会很容易。

© www.soinside.com 2019 - 2024. All rights reserved.