You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将AudioDataStream转换为Stream或byte[]?C#语音SDK开发问题

问题描述

我在C#中创建自定义API,使用Microsoft.CognitiveServices.Speech SDK实现文本转语音功能,返回的数据类型为AudioDataStream。但我需要将其转换为Stream或byte[],以便在UI中使用,请问该如何实现转换?或者有没有其他方式能让UI使用流输出?

补充说明:以下是我使用的代码,运行时报错Cannot convert Microsoft.CognitiveServices.Speech.AudioDataStream to System.IO.Stream。我也尝试过使用AudioDataStream.ReadData(),但它的返回类型是uint而非字节数组。

[HttpPost]
public async Task<IActionResult> ConversationIOStreamAsync(IFormFile audioFile)
{
    if (audioFile == null || audioFile.Length == 0)
    {
        return BadRequest("No audio file received.");
    }

    // Save the audio file to a temporary location 
    var filePath = Path.Combine(Path.GetTempPath(), audioFile.FileName);
    using (var stream = new FileStream(filePath, FileMode.Create))
    {
        await audioFile.CopyToAsync(stream);
    }

    var memoryStream = new MemoryStream();
    using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        await stream.CopyToAsync(memoryStream);
    }
    memoryStream.Position = 0;

    try
    {
        var audioStream = await ConversationService.ConversationIOStreamAsync(memoryStream);

        using var stream = AudioDataStream.FromResult(audioStream);


        return File(stream, "audio/wav", audioFile.FileName);
    }
    catch (System.Exception ex)
    {
        return StatusCode(500, $"Internal server error: {ex.Message}");
    }

}
解决方案

方法1:将AudioDataStream转换为MemoryStream

AudioDataStream的ReadData()方法返回的是读取到的字节数,我们可以通过循环读取的方式把数据写入MemoryStream,得到标准的System.IO.Stream:

using var audioDataStream = AudioDataStream.FromResult(audioStream);
var memoryStream = new MemoryStream();
byte[] buffer = new byte[4096]; // 用4KB缓冲区平衡性能和内存占用
uint bytesRead;

do
{
    bytesRead = audioDataStream.ReadData(buffer);
    if (bytesRead > 0)
    {
        memoryStream.Write(buffer, 0, (int)bytesRead);
    }
} while (bytesRead > 0);

memoryStream.Position = 0; // 重置流指针到起始位置,确保后续读取正常

转换完成后,直接用memoryStream作为File方法的参数返回即可:

return File(memoryStream, "audio/wav", $"{Path.GetFileNameWithoutExtension(audioFile.FileName)}.wav");

方法2:直接保存为WAV文件返回(简单但性能略低)

如果不想手动处理内存流,也可以调用AudioDataStream的SaveToWaveFile方法直接保存为WAV文件,再返回文件流:

using var audioDataStream = AudioDataStream.FromResult(audioStream);
var tempWavPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.wav");
audioDataStream.SaveToWaveFile(tempWavPath);

// 返回文件,注意添加删除临时文件的逻辑,避免磁盘占用
return PhysicalFile(tempWavPath, "audio/wav", $"{Path.GetFileNameWithoutExtension(audioFile.FileName)}.wav");

原代码优化建议

  • 原代码中先保存上传文件到临时路径再读入MemoryStream的步骤可以简化,直接复制IFormFile到MemoryStream即可,省去中间文件:
var memoryStream = new MemoryStream();
await audioFile.CopyToAsync(memoryStream);
memoryStream.Position = 0;

内容的提问来源于stack exchange,提问作者Maryam Mirza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:16:01