4

在 C# 中,我想录制音频流

我正在做一些事情:

HttpWebRequest req;
req = (HttpWebRequest)WebRequest.Create("http://url.com/stream");

Webresponse resp = req.GetResponse();
Stream s = resp.GetResponseStream();

fs = File.Exists(fileName)
    ? new FileStream(fileName, FileMode.Append)
    : new FileStream(fileName, FileMode.Create);

byte[] buffer = new byte[4096];

while (s.CanRead)
{
    Array.Clear(buffer, 0, buffer.Length);
    total += s.Read(buffer, 0, buffer.Length);
    fs.Write(buffer, 0, buffer.Length);
}

并且文件大小增加但无法通过VLC或任何其他程序播放。

这不是我的确切代码,我做了很多错误检查等,但这给出了总体思路。

4

3 回答 3

4
    Array.Clear(buffer, 0, buffer.Length);
    total += s.Read(buffer, 0, buffer.Length);
    fs.Write(buffer, 0, buffer.Length);

您不必在阅读之前清除整个数组 - 这样做没有意义。但是你必须检查你实际读取了多少字节,不能保证每次都填满整个数组(而且可能不会):

    int bytesRead = s.Read(buffer, 0, buffer.Length);
    fs.Write(buffer, 0, bytesRead);
    total+=bytesRead;

此外,文件是否播放(即使在您修复文件写入代码后不再损坏)取决于您下载的格式 - 它是什么编解码器/文件类型?

于 2011-05-06T17:42:16.867 回答
2

问题是流式传输的位没有上下文。当您流式传输到应用程序时,默认您正在处理文件类型 X,然后流式传输程序会尝试播放这些位。

当您流式传输到文件时,您必须添加上下文。最重要的位之一是标识文件类型和其他信息的标题。

如果可以添加标题,则可以从文件系统播放文件。标头不会成为流的一部分,因为服务器和客户端已经就它已经是什么类型的文件达成了一致。

如果您创建一个流播放器,您可以在协商类型时播放您保存的位。但是要让它从文件中自动工作,您必须添加标题。

于 2011-05-06T17:44:43.500 回答
0

如果不详细了解 MP3 的流格式和文件格式,试图将流式 MP3 音频保存到磁盘基本上是不可能的。您从流中得到的是一系列转换为频域的“窗口化”音频块;接收流的播放器将这些块即时转换回时域音频并一个接一个地播放。

要制作 MP3文件,您必须首先写出包含格式信息的标题,然后写入每个数据块。但很可能将这些块存储在文件中的格式与将它们压缩成流的方式不同。

对不起,但我会认真建议你放弃这个。音乐服务流而不是提供文件下载的一个主要原因特别是因为将 MP3 类型的流保存到磁盘非常困难(将未压缩的音频流保存到 WAV 文件将是一件小事)。

于 2011-05-06T17:56:27.207 回答