首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NAudio:在WCF中将IEEE浮点输入流转换为MP3输出流

NAudio:在WCF中将IEEE浮点输入流转换为MP3输出流
EN

Stack Overflow用户
提问于 2017-03-27 15:40:56
回答 1查看 1.1K关注 0票数 1

我有WAV数据在IEEE浮动在16000赫兹,32位,1通道格式的字节数组(从数据库)。我想动态地将其转换为mp3,并通过WCF服务的响应对象将其流出来。

使用NAudio包,到目前为止,我所做的工作是使用MediaFoundationEncoder.EncodetoMp3()写入文件。但是,一旦该文件被写入响应,它就没用了。我只想跳过文件写入步骤,然后输出到流或字节数组,然后将其写入响应对象。

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

或者,尝试使用写入流的LameMP3FileWriter,我可以将IEEE浮点数输入直接发送到LameMP3FileWriter,但结果mp3流听起来像是一个响亮的嘶嘶声,而不管我使用的输出格式是什么(44100,16,1),(220,16,1),(11025,16,1),.

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

AcmNotPossible调用acmStreamOpen

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

代码语言:javascript
运行
复制
    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());

原始音频在Chrome (作为WAV流)中可以很好地播放,如果我只是做一个ms MemoryStream的MemoryStream,所以我认为IEEE浮动源数据是有效的。

纠正我的错误,但这个错误(AcmNotPossible)似乎意味着我的机器上没有IEEE浮动格式的ACM编解码器?我查询我的机器,似乎没有32位ACM编解码器,这也是我尝试Wave32To16Stream转换的原因。

是否有从IEEE浮点数32位到mp3的瘸腿MP3管道的临时步骤?

EN

回答 1

Stack Overflow用户

发布于 2017-03-28 23:15:42

对不起,关于将IEEE浮点数32位波转换为mp3流的主要问题有这么多子问题,但我至少可以告诉您,我是如何在我的简单WCF服务上使用ACM编解码器(我认为)使它工作的:

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

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

代码语言:javascript
运行
复制
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;
        }
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43050753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档