使用Lame混合波流到mp3

时间:2013-08-10 14:31:08

标签: c#-4.0 naudio lame

.......
.......

var mixer = new WaveMixerStream32();
mixer.AutoStop = true;

var messageOffset = background.TotalTime;
var messageOffsetted = new WaveOffsetStream(message, 
                                         TimeSpan.FromSeconds(10), 
                                         TimeSpan.Zero,message.TotalTime.Subtract(TimeSpan.FromSeconds(10)));             

var background32 = new WaveChannel32(background);
background32.PadWithZeroes = false;
background32.Volume = 0.6f;               
mixer.AddInputStream(background32);

var message32 = new WaveChannel32(messageOffsetted);
message32.PadWithZeroes = false;
message32.Volume = 0.3f;
mixer.AddInputStream(message32);

var ws = new Wave32To16Stream(mixer);

我们正试图混合多个mp3和wave文件,最终创建一个MP3。

示例:5个源文件(3个mp3,2个波形文件)

我们将每个流的输入提供给WaveMixerStream32,最后使用它进行转换 Wave32To16Stream

我们需要将此最终流转换为MP3。为此,我们使用LAME并将流传递给 EncodeMixedStreamAsMp3,它返回错误“文件格式无效”。

经过研究,我们发现混合波流中缺少RIFF标题。

如何将RIFF添加到基于多个源(MP3和WAVE)生成的混合波流中?

1 个答案:

答案 0 :(得分:1)

NAudio WaveStream是具有指定格式的样本数据流,而不是LAME所期望的RIFF WAV文件。要将其转换为RIFF WAV文件,您需要添加RIFF标题等。 NAudio.Wave.WaveFileWriter类就是这样做的。

如果您正在使用不会破坏记忆的小型输出文件,您可以做一些简单的事情(假设是Yeti的LAME包装或类似的):

(代码更新于2013年8月19日):

public byte[] EncodeMP3(IWaveProvider ws, uint bitrate = 128)
{
    // Setup encoder configuration
    WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(ws.WaveFormat.SampleRate, ws.WaveFormat.BitsPerSample, ws.WaveFormat.Channels);
    Yeti.Lame.BE_CONFIG beconf = new Yeti.Lame.BE_CONFIG(fmt, bitrate);

    // Encode WAV to MP3
    int blen = ws.WaveFormat.AverageBytesPerSecond;
    byte[] buffer = new byte[blen];
    byte[] mp3data = null;

    using (MemoryStream mp3strm = new MemoryStream())
    using (Mp3Writer mp3wri = new Mp3Writer(mp3strm, fmt, beconf))
    {
        int rc;
        while ((rc = ws.Read(buffer, 0, blen)) > 0)
            mp3wri.Write(buffer, 0, rc);
        mp3data = mp3strm.ToArray();
    }
    return mp3data;
}

- 更新:设置MP3编码参数

使用Yeti LAME包装器,您可以通过传递BE_CONFIG结构来指定MP3编码参数:

WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(ws.WaveFormat.SampleRate, ws.WaveFormat.BitsPerSample, ws.WaveFormat.Channels);

Yeti.Lame.BE_CONFIG beconf = new Yeti.Lame.BE_CONFIG(fmt, 64);
using (MemoryStream mp3strm = new MemoryStream())
using (Mp3Writer mp3wri = new Mp3Writer(mp3strm, fmt, beconf))
{
...
}

BE_CONFIG构造函数采用WaveLib.WaveFormat和可选的CBR比特率(Kb / s)。如果未指定比特率,则默认为128Kb / s输出。如果您未向Mp3Writer提供配置,则会从WaveFormat创建默认配置。

上面的代码创建了一个BE_CONFIG,输出速率设置为64Kb / s。如果您想要不同的比特率,只需将其指定为64中的new Yeti.Lame.BE_CONFIG(fmt, 64);

BE_CONFIG包含许多其他选项,其中大部分都是您永远不会使用的。查看(略显粗略)文档here