0
.......
.......

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 和波形文件以最终创建一个 MP3。

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

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

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

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

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

4

1 回答 1

1

NAudioWaveStream是具有指定格式的样本数据流,而不是 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 编码参数

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

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 的。如果您想要不同的比特率,只需指定它来代替64innew Yeti.Lame.BE_CONFIG(fmt, 64);

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

于 2013-08-12T01:35:19.563 回答