C# 4.0 使用Lame将混合波流转换为mp3
我们正在尝试混合多个mp3和wave文件,最终创建一个mp3 示例:5个源文件(3个mp3,2个wave文件) 我们将每个流的输入提供给WaveMixerStream32,最后使用 波32到16流 我们需要将最后一个流转换为MP3。为此,我们使用LAME并将流传递给 EncodeMixedStreamAsMp3返回错误“无效文件格式” 经过研究,我们发现混合波流中缺少RIFF头C# 4.0 使用Lame将混合波流转换为mp3,c#-4.0,naudio,lame,C# 4.0,Naudio,Lame,我们正在尝试混合多个mp3和wave文件,最终创建一个mp3 示例:5个源文件(3个mp3,2个wave文件) 我们将每个流的输入提供给WaveMixerStream32,最后使用 波32到16流 我们需要将最后一个流转换为MP3。为此,我们使用LAME并将流传递给 EncodeMixedStreamAsMp3返回错误“无效文件格式” 经过研究,我们发现混合波流中缺少RIFF头 如何将RIFF添加到基于多个源(MP3和wave)生成的混合波流中?NAudio波流是具有指定格式的样本数据流,而不是
如何将RIFF添加到基于多个源(MP3和wave)生成的混合波流中?NAudio
波流是具有指定格式的样本数据流,而不是LAME预期的RIFF WAV文件。要将其转换为RIFF WAV文件,您需要添加RIFF头等等。NAudio.Wave.waveilewriter类执行此操作
如果您使用的是不会耗尽内存的小型输出文件,那么您可以做一些简单的事情,比如(假设Yeti的LAME wrapper或类似产品):
(代码于2013年8月19日更新):
--更新:设置MP3编码参数
使用Yeti
LAME包装器,您可以通过如下方式传递BE\u CONFIG
结构来指定MP3编码参数:
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;
}
BE\u CONFIG
构造函数采用WaveLib.WaveFormat
和可选的CBR比特率(以Kb/s为单位)。如果不指定比特率,则默认为128Kb/s输出。如果不向Mp3Writer
提供配置,它将从波形格式创建一个默认配置
上面的代码创建了一个BE_CONFIG
,输出速率设置为64Kb/s。如果您想要不同的比特率,只需在new Yeti.Lame.BE_CONFIG(fmt,64)中指定它来代替64
代码>
BE\u CONFIG
包含许多其他选项,其中大多数是您永远不会使用的。查看(略显粗略的)文档。Hi@Corey,我还有一个问题。我能够获得128 kbps比特率的mp3输出。现在我希望输出为64 kbps。有办法吗。我在谷歌上搜索了一下,但几乎找不到任何解决方案。你需要用正确的配置设置Mp3Writer。我将添加一些代码…非常感谢!!我明白了。嗨@Corey,你的代码在mp3和wave streams上运行得很好,但是当我在你的函数中使用了NVorbis.NAudioSupport.VorbisWaveReader的帮助下使用ogg stream时,我得到了声音输出,歌曲播放速度很慢,这一点也不清楚。请,纠正我的错误。我在WaveLib.WaveFormat中使用了每个样本16位,因为我的ogg给每个样本32位。@Sainatsagar在混合之前,您需要将所有输入转换为相同的格式,因此解码的ogg需要转换为16位VorbisWaveReader
是一种WaveStream
您可以使用NAudio.Wave.Wave32To16Stream
对其进行包装,为您提供一个16位WaveStream
进行编码。
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;
}
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))
{
...
}