【问题标题】:NAudio: Convert IEEE Float input stream to MP3 output stream in WCFNAudio:将 IEEE Float 输入流转换为 WCF 中的 MP3 输出流
【发布时间】:2017-08-20 10:00:48
【问题描述】:

我在字节数组(来自数据库)中有 16000Hz、32 位、1 通道格式的 IEEE 浮点 WAV 数据。我想即时将其转换为 mp3 并通过 WCF 服务的响应对象将其流式传输。

使用 NAudio 包,到目前为止,我正在使用 MediaFoundationEncoder.EncodetoMp3() 写入文件。但是,一旦将该文件写出到响应中,它就没有用了。我想跳过文件写入步骤并输出到流或字节数组并将其写入响应对象。

有没有办法让 MediaFoundationEncoder 在某种内存对象(没有文件)中输出 mp3?

或者,尝试使用 LameMP3FileWriter,它确实写入流, 我可以将 IEEE 浮点 wav 输入直接发送到 LameMP3FileWriter 但无论我使用什么输出格式 (44100,16,1), (22050,16,1), (11025,16, 1),...

当我尝试将 IEEE 浮点源转换为 PCM 或使用 WaveFormatConversion 对其进行上采样时,它会出错

AcmNotPossible 调用 acmStreamOpen

如果我在 IEEE 浮点源上使用 Wave32to16Stream,它不会出错但没有音频。这条链不适合我:

    byte[] bytes = (Byte[])dt.Rows[0]["AudioContent"];//this is the dataTable from the database query containing the WAV audio

    var ms = new MemoryStream(bytes);
    var OLDfmt = WaveFormat.CreateIeeeFloatWaveFormat(16000,1);
    var NEWfmt = new WaveFormat(16000, 16, 1);//tried many
    var readr = new RawSourceWaveStream(ms,OLDfmt);

    //the following line errors on 'AcmNotPossible calling acmStreamOpen' 
    //var wav16 = new WaveFormatConversionStream(NEWfmt, readr);

    //the following does not error but no mp3 streams out at the end
    var wav16 = new Wave32To16Stream(readr);

    var outptMP3 = new MemoryStream();
    var writr = new LameMP3FileWriter(outptMP3, NEWfmt, LAMEPreset.STANDARD);
    wav16.CopyTo(writr);
    HttpContext.Current.Response.BufferOutput = true;
    HttpContext.Current.Response.AddHeader("Content-Type", "audio/mpeg");
    HttpContext.Current.Response.BinaryWrite(outptMP3.ToArray());

如果我只是执行 ms MemoryStream 的 BinaryWrite,原始音频在 Chrome 中播放良好(作为 WAV 流),所以我认为 IEEE 浮点源数据是有效的。

如果有错误请纠正我,但该错误 (AcmNotPossible) 似乎意味着我的机器上没有适用于 IEEE 浮点格式的 ACM 编解码器?我查询我的机器,似乎没有 32 位 ACM 编解码器,这就是我尝试 Wave32To16Stream 转换的原因。

Lame MP3 管道是否有从 IEEE 浮点 32 位到 mp3 的中间步骤?

【问题讨论】:

    标签: wcf audio mp3 naudio


    【解决方案1】:

    抱歉,关于将 IEEE 浮点 32 位波转码为 mp3 流的主要问题有很多子问题,但我至少可以告诉你我是如何使用 ACM 编解码器(我认为)让它工作的我的简单 WCF 服务:

    1. 将服务的返回类型更改为流
    2. 在返回之前将 MemoryStream 位置设置为 0

    否则上面的链实际上对我有用。为了完整起见,我将给出完整的代码以及所有无关的 SQL 内容,因为我在一个不相关的 SO 问题中找到了答案:

    public Stream playWAVEFileFromDB() {
            //if using the file output method, I change the return type to string and return text instead of streams
            try
            {
                SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString);
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                cmd.CommandText = "SELECT theWAVEColumn FROM myTable WHERE allThoseAudiosAreStored";
                SqlDataAdapter sda = new SqlDataAdapter();
                DataTable dt = new DataTable();
    
                conn.Open();
                sda.SelectCommand = cmd;
                sda.Fill(dt);
    
                //read the raw audio from database into a byte array
                byte[] bytes = (Byte[])dt.Rows[0]["colName"];
                var ms = new MemoryStream(bytes);
                var NEWfmt = new WaveFormat(16000, 16, 1);
                var OLDfmt = WaveFormat.CreateIeeeFloatWaveFormat(16000,1);//how its stored
                var readr = new RawSourceWaveStream(ms,OLDfmt);
                var wav16 = new Wave32To16Stream(readr);
                var outptMP3 = new MemoryStream();    
                var writr = new LameMP3FileWriter(outptMP3, NEWfmt, LAMEPreset.STANDARD);
                wav16.CopyTo(writr);
                outptMP3.Position = 0;
    
                HttpContext.Current.Response.BufferOutput = true;
                HttpContext.Current.Response.AddHeader("Content-Type", "audio/mpeg");
    
                conn.Close();
                conn.Dispose();
                sda.Dispose();
    
                return outptMP3;
            }
                catch (Exception e)
            {
                //do the error logging stuff
                return Stream.Null;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2011-08-12
      • 1970-01-01
      • 2013-10-25
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多