我尝试使用下面的代码连接2个MP3文件。我有一个新文件,我可以播放上半部分(完成第一个文件),但下半部分是静音。新文件的长度是正确的。我做错了什么?
List<Byte[]> files = new List<byte[]>();
var tempfile = File.ReadAllBytes(Path.Combine(path, "1.mp3"));
files.Add(tempfile);
tempfile = File.ReadAllBytes(Path.Combine(path, "2.mp3"));
files.Add(tempfile);
Byte[] a=new Byte[files[0].Length+files[1].Length];
Array.Copy(files[0], a, files[0].Length);
Array.Copy(files[1], a, files[1].Length);
File.WriteAllBytes(Path.Combine(path, "3.mp3") , a);
答案 0 :(得分:11)
我愿意打赌你只听第二首歌。 (并且两个文件的长度相同或者第一个较短)
您正在复制第一首歌曲数据。并且MP3数据是流式的,因此您可以将文件相互附加而不必担心比特率(虽然它们可能会出现故障)比特率应该自动调整。
...试试这个......
Array.Copy(files[0], 0, a, 0, files[0].Length);
Array.Copy(files[1], 0, a, files[0].Length, files[1].Length);
......或者更好......
using (var fs = File.OpenWrite(Path.Combine(path, "3.mp3")))
{
var buffer = File.ReadAllBytes(Path.Combine(path, "1.mp3"));
fs.Write(buffer, 0, buffer.Length);
buffer = File.ReadAllBytes(Path.Combine(path, "2.mp3"));
fs.Write(buffer, 0, buffer.Length);
fs.Flush();
}
答案 1 :(得分:4)
简单:
public static void Combine(string[] mp3Files, string mp3OuputFile)
{
using (var w = new BinaryWriter(File.Create(mp3OuputFile)))
{
new List<string>(mp3Files).ForEach(f => w.Write(File.ReadAllBytes(f)));
}
}
答案 2 :(得分:3)
以下是使用NAudio连接MP3文件的方法:
public static void Combine(string[] inputFiles, Stream output)
{
foreach (string file in inputFiles)
{
Mp3FileReader reader = new Mp3FileReader(file);
if ((output.Position == 0) && (reader.Id3v2Tag != null))
{
output.Write(reader.Id3v2Tag.RawData,
0,
reader.Id3v2Tag.RawData.Length);
}
Mp3Frame frame;
while ((frame = reader.ReadNextFrame()) != null)
{
output.Write(frame.RawData, 0, frame.RawData.Length);
}
}
}
有关详细信息,请参阅here。
答案 3 :(得分:2)
每个MP3文件在包含歌曲元数据的文件开头都有一个标题。至少你必须在第二个文件中删除它。
这是以前的Stack Overflow问题,How do I merge/join MP3 files with C#?。
这是Read MP3 Tag Information (ID3v1 and ID3v2)的另一个链接,它可能会帮助您将其删除。
答案 4 :(得分:1)
here和here之前已经提出了这个问题。另请参阅reading MP3 Headers in C#,但不是读取标题,而只是想将其删除,连接其余部分,然后为连接文件生成新标题。
编辑:进一步阅读后,如果你只是在不剥离ID3标签的情况下连接文件就没有任何区别。但是首先剥离它们似乎仍然是一个好主意。
答案 5 :(得分:1)
众所周知,Mp3文件只是一些 frames ,你可以将这些流连接在一起:
public static void Concatenate(params string[] mp3filenames)
{
Stream w = File.OpenWrite("D:\\out.mp3");
foreach (string filename in mp3filenames)
File.OpenRead(filename).CopyTo(w);
w.Flush();
w.Close();
}
并听取用法:
Concatenate("D:\\1.mp3", "D:\\2.mp3");