維護一個 currentIndex 指向播放列表,播放結束事件中遞增並取模。
public class MusicPlayer {
private readonly List _playlist = new List();
private int _currentIndex = -1;
private IWavePlayer _waveOut; // NAudio
// 或 MediaPlayer _player = new MediaPlayer(); // WPF
public void AddSongs(IEnumerable files) {
_playlist.AddRange(files);
}
public void Play() {
if (_playlist.Count == 0) return;
_currentIndex = (_currentIndex + 1) % _playlist.Count;
PlayFile(_playlist[_currentIndex]);
}
public void PlayFile(string path) {
// NAudio 示例
_waveOut?.Dispose();
var reader = new AudioFileReader(path);
_waveOut = new WaveOutEvent();
_waveOut.Init(reader);
_waveOut.PlaybackStopped += (s, e) => Play(); // 循環關鍵:播放結束自動下一首
_waveOut.Play();
}
public void Next() => Play(); // 手動下一首同邏輯
public void Prev() {
_currentIndex = (_currentIndex - 1 + _playlist.Count) % _playlist.Count;
PlayFile(_playlist[_currentIndex]);
}
}
PlaybackStopped (NAudio) 或 MediaEnded (MediaPlayer) 自動觸發下一首。(index + 1) % count 實現無縫循環,無需判斷邊界。Dispose() 舊播放器,防止內存洩漏。PlayMode { Sequence, RepeatOne, Shuffle },在事件中根據模式計算新索引。_player.MediaEnded += (s, e) => {
_player.Position = TimeSpan.Zero; // 單曲循環
// 或 _currentIndex = (_currentIndex + 1) % _playlist.Count; _player.Open(new Uri(_playlist[_currentIndex])); _player.Play();
};
_player.MediaFailed += (s, e) => { /* 記錄錯誤,嘗試下一首 */ };