这可能不是最好的解决方案,但我会做的是将播放列表连接到一个 mp3 文件中,然后播放该 mp3 文件。当一个接一个地播放一首歌曲时,会有一个毫秒的暂停,因为下一首歌曲正在加载。
首先,创建一个名为LoopStream.cs 的新类文件并将此代码放入其中:
public class LoopStream : WaveStream
{
WaveStream sourceStream;
/// <summary>
/// Creates a new Loop stream
/// </summary>
/// <param name="sourceStream">The stream to read from. Note: the Read method of this stream should return 0 when it reaches the end
/// or else we will not loop to the start again.</param>
public LoopStream(WaveStream sourceStream)
{
this.sourceStream = sourceStream;
this.EnableLooping = true;
}
/// <summary>
/// Use this to turn looping on or off
/// </summary>
public bool EnableLooping { get; set; }
/// <summary>
/// Return source stream's wave format
/// </summary>
public override WaveFormat WaveFormat
{
get { return sourceStream.WaveFormat; }
}
/// <summary>
/// LoopStream simply returns
/// </summary>
public override long Length
{
get { return sourceStream.Length; }
}
/// <summary>
/// LoopStream simply passes on positioning to source stream
/// </summary>
public override long Position
{
get { return sourceStream.Position; }
set { sourceStream.Position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
int totalBytesRead = 0;
while (totalBytesRead < count)
{
int bytesRead = sourceStream.Read(buffer, offset + totalBytesRead, count - totalBytesRead);
if (bytesRead == 0)
{
if (sourceStream.Position == 0 || !EnableLooping)
{
// something wrong with the source stream
break;
}
// loop
sourceStream.Position = 0;
}
totalBytesRead += bytesRead;
}
return totalBytesRead;
}
}
那么这是你的主Program.cs,循环播放mp3文件,我们将使用LoopStream类循环播放mp3文件:
static void Main(string[] args)
{
var playlist = new List<string>{ @"c:\Users\User\Music\sound1.mp3",
@"c:\Users\User\Music\sound2.mp3" };
var mp3OutputFile = File.Create(@"c:\Users\User\Music\soundnew3.mp3");
Concatenate(playlist, mp3OutputFile);
mp3OutputFile.Close();
var combinedList = new List<string> { @"c:\Users\User\Music\soundnew3.mp3" };
var playr = new playr(combinedList);
playr.PlaySong();
Console.WriteLine("Playing your songs..");
Console.ReadLine();
}
public static void Concatenate(List<string> mp3FileNames, Stream output)
{
foreach (string file in mp3FileNames)
{
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);
}
}
}
public class playr
{
private Queue<string> playlist;
private IWavePlayer player;
private WaveStream fileWaveStream;
public playr(List<string> startingPlaylist)
{
playlist = new Queue<string>(startingPlaylist);
}
public void PlaySong()
{
if (fileWaveStream != null)
{
fileWaveStream.Dispose();
}
if (playlist.Count < 1)
{
return;
}
if (player != null && player.PlaybackState != PlaybackState.Stopped)
{
player.Stop();
}
if (player != null)
{
player.Dispose();
player = null;
}
player = new WaveOutEvent();
fileWaveStream = new AudioFileReader(playlist.Dequeue());
LoopStream loop = new LoopStream(fileWaveStream);
player.Init(loop);
player.PlaybackStopped += (sender, evn) => { PlaySong(); };
player.Play();
}
}
如果你想合并 WAV 文件,你可以这样做:
public static void Concatenate(List<string> sourceFiles)
{
byte[] buffer = new byte[1024];
WaveFileWriter waveFileWriter = null;
string outputFile = @"c:\Users\User\Music\soundnew3.wav";
try
{
foreach (string sourceFile in sourceFiles)
{
using (WaveFileReader reader = new WaveFileReader(sourceFile))
{
if (waveFileWriter == null)
{
// first time in create new Writer
waveFileWriter = new WaveFileWriter(outputFile, reader.WaveFormat);
}
else
{
if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat))
{
throw new InvalidOperationException("Can't concatenate WAV Files that don't share the same format");
}
}
int read;
while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
{
waveFileWriter.WriteData(buffer, 0, read);
}
}
}
}
finally
{
if (waveFileWriter != null)
{
waveFileWriter.Dispose();
}
}
}