首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# WinForm 實現 KTV 點播核心功能:靜音、重唱、切歌架構設計

     編輯:程式設計綜合問答

核心需求拆解

功能技術要點建議實現
播放/暫停媒體控制MediaPlayer / NAudio / LibVLCSharp
靜音音量控制設定 Volume=0 或 IsMuted=true,保留當前音量值供恢復
重唱進度控制Position = TimeSpan.Zero 或 CurrentTime = 0
切歌播放列表管理維護 List<Song> + 當前索引,Next()/Prev() 切換來源
歌詞同步解析 .lrc / .krc背景執行緒解析時間軸,UI 執行緒高亮顯示
評分/音高檢測FFT/音頻分析NAudio 捕獲麥克風輸入,做頻譜比對 (進階)

推薦技術棧選型

  1. LibVLCSharp (首選):跨平台、格式支援最全、硬體解碼、穩定。NuGet: LibVLCSharp.WinForms + VideoLAN.LibVLC.Windows。
  2. NAudio:純 .NET、低延遲、適合音頻處理/錄音/波形圖,但視頻支援弱。
  3. MediaPlayerElement (UWP/WPF):WinForm 需用 WindowsFormsHost 裝載,較重。
  4. DirectShow / MediaFoundation (底層):複雜、不建議直接用。

核心類別設計 (以 LibVLCSharp 為例)

public class KtvPlayer {
    private readonly LibVLC _libVLC;
    private readonly MediaPlayer _mediaPlayer;
    private readonly List _playlist = new();
    private int _currentIndex = -1;
    private double _volumeBeforeMute = 1.0;

    public event Action PositionChanged;
    public event Action SongChanged;

    public KtvPlayer() {
        Core.Initialize();
        _libVLC = new LibVLC();
        _mediaPlayer = new MediaPlayer(_libVLC);
        _mediaPlayer.TimeChanged += (s, e) => PositionChanged?.Invoke(TimeSpan.FromMilliseconds(e.Time));
        _mediaPlayer.EndReached += (s, e) => PlayNext();
    }

    public void LoadPlaylist(IEnumerable songs) {
        _playlist.Clear();
        _playlist.AddRange(songs);
        _currentIndex = -1;
    }

    public void Play(int index) {
        if (index < 0 || index >= _playlist.Count) return;
        _currentIndex = index;
        var song = _playlist[index];
        var media = new Media(_libVLC, new Uri(song.MediaUrl));
        _mediaPlayer.Play(media);
        SongChanged?.Invoke(song);
    }

    public void PlayNext() => Play((_currentIndex + 1) % _playlist.Count);
    public void PlayPrev() => Play((_currentIndex - 1 + _playlist.Count) % _playlist.Count);
    public void Replay() => _mediaPlayer.Time = 0;

    public void ToggleMute() {
        if (_mediaPlayer.Mute) {
            _mediaPlayer.Mute = false;
            _mediaPlayer.Volume = (int)(_volumeBeforeMute * 100);
        } else {
            _volumeBeforeMute = _mediaPlayer.Volume / 100.0;
            _mediaPlayer.Mute = true;
        }
    }

    public void SetVolume(double vol) { // 0.0 ~ 1.0
        _mediaPlayer.Volume = (int)(vol * 100);
        if (vol > 0) _mediaPlayer.Mute = false;
    }
}

UI 綁定範例 (WinForms)

public partial class KtvForm : Form {
    private readonly KtvPlayer _player = new KtvPlayer();

    public KtvForm() {
        InitializeComponent();
        _player.PositionChanged += ts => lblPosition.Invoke(() => lblPosition.Text = ts.ToString(@"mm\:ss"));
        _player.SongChanged += s => {
            lblSongName.Invoke(() => lblSongName.Text = s.Title);
            // 載入歌詞...
        };
    }

    private void btnPlay_Click(object sender, EventArgs e) => _player.Play(0);
    private void btnNext_Click(object sender, EventArgs e) => _player.PlayNext();
    private void btnPrev_Click(object sender, EventArgs e) => _player.PlayPrev();
    private void btnReplay_Click(object sender, EventArgs e) => _player.Replay();
    private void btnMute_Click(object sender, EventArgs e) => _player.ToggleMute();
    private void trackVolume_Scroll(object sender, EventArgs e) => _player.SetVolume(trackVolume.Value / 100.0);
}

進階功能擴充

  • 歌詞同步:解析 LRC 為 SortedList<TimeSpan, string>,Timer 每 200ms 比對當前時間高亮行。
  • 麥克風混音:NAudio.WaveInEvent 捕獲麥克風 → WaveMixerStream32 與伴奏混音 → 輸出聲卡。
  • 評分系統:錄製演唱片段 → FFT 分析基頻 → 與標準旋律比對 (需數位信號處理知識)。
  • 網路點歌:SignalR / WebSocket 連接後台,實時接收點歌指令插入播放列表。

避坑指南

  1. LibVLC 需部署 libvlc.dll 等原生庫,**輸出目錄勾選「複製較新」**或用 NuGet 套件自動處理。
  2. UI 執行緒更新必須 Control.Invoke 或 async/await 配合 Task.Run。
  3. 切歌時釋放舊 Media 物件:media.Dispose() 避免記憶體洩漏。
  4. 全螢幕模式:_mediaPlayer.SetFullscreen(true) 或 WinForm FormBorderStyle=None, WindowState=Maximized。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved