如何将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
相关产品推荐
相关产品推荐

