1. 作業內容
????編寫一個C#程序,要求實現常見音樂文件的播放功能,具體要求如下:
????1). 播放MP3
文件: 程序應能夠讀取MP3
文件,并播放其中的音頻。
????2). 播放OGG
文件: 應能夠播放ogg
文件。
????3). 用戶界面: 一個簡單的窗口,包含播放和暫停按鈕以及文件選擇功能。
????4). 異常處理: 程序應能夠處理可能出現的異常,如文件不存在、文件讀取錯誤等。
????5). 兼容性: 確保代碼在多個C#版本上均可運行。
2. 設計思路分析與難點
2.1 架構選擇
????考慮到需求中的界面友好和跨版本兼容性,我們可以選擇選擇Windows Forms
作為開發平臺,Windows Forms
提供了一個簡單而強大的方法來創建桌面應用程序,并且與C#高度兼容,在開發過程,我們選擇.NETFramework 4.8.0
進行程序設計。
2.2 設計思路
????1). 界面設計: 使用Windows Forms
工具箱中的控件如按鈕、標簽和文件對話框構建用戶界面。
????2). 功能編碼: 使用OpenFileDialog
允許用戶選擇音頻文件。 根據文件擴展名調用相應的播放器對象進行播放。 播放控制,包括開始、暫停和停止。
????3). 異常處理: 捕獲并響應各種可能的運行時錯誤,如文件讀取失敗、文件格式不支持等,為用戶提供清晰的錯誤信息。
2.3 難點分析
????1). 文件格式支持: 處理多種音頻格式(MP3
,OGG
等)要求使用不同的庫,這可能導致代碼復雜度增加。
????2). 異常處理: 音頻文件的播放中可能遇到多種異常情況,如文件損壞、編解碼器不支持等。
3. 窗體設計
????按照需求和功能分析,實現窗體如下:
????其中,各控件實現功能如下:
????Label
:展示當前播放的歌曲。
????ListBox
:展示選擇的歌曲列表。
????AxWindowsMediaPlayer
:用于播放常規格式音樂(ogg
無法用此播放)。
????OpenFileDialog
:用于選擇音樂文件。
????Button
:用于選擇歌曲文件、停止播放、下一曲的功能實現。
????TrackBarl
:用于音量控制。
4. 代碼實現
4.0 類成員變量定義
List<string> localmusiclist = new List<string> { };
private WaveOutEvent waveOut = new WaveOutEvent();
private VorbisWaveReader currentVorbisReader;
????在類中,我們需要定義類成員變量,localmusiclist
在音樂播放應用中用來追蹤和管理用戶加載的音樂文件集合,waveOut
用于播放ogg
文件,currentVorbisReader
為當前使用的ogg
文件實例。
4.1 文件選擇功能
????函數定義:
private void button1_Click(object sender, EventArgs e)
{//功能實現見下方
}
????具體實現:
string[] files = { };openFileDialog1.Filter = "選擇音頻|*.mp3;*.flac;*.wav;*.ogg";
//同時打開多個文件
openFileDialog1.Multiselect = true;
????在這部分,我們采用button
和openFileDialog
控件來實現文件的選擇,Filter
用于篩選文件類型,使得用戶只能選擇音樂文件,不能選擇其他文件導致后續功能無法實現報錯,同時初始化一個files文件存放音樂文件的文件名。
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{//清空原有列表listBox1.Items.Clear();localmusiclist.Clear();if (files != null){Array.Clear(files, 0, files.Length);}files = openFileDialog1.FileNames;string[] array = files;foreach(string file in array){listBox1.Items.Add(file);localmusiclist.Add(file);}
}
????這里我們對選擇的文件進行處理,首先,將所有變量清空,防止有殘留影響后續程序執行,之后,將文件名添加到ListBox
中,顯示出來用于選擇音樂,同時,利用localmusiclist
變量存儲文件名,并且作為類成員變量進行傳輸,方便后續對音樂的操作。
openFileDialog1.ShowDialog() == DialogResult.OK
????其中,if
條件判斷openFileDialog
是否接收到文件,不然不執行后續程序。
4.2 列表顯示功能
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{if(localmusiclist.Count > 0){axWindowsMediaPlayer1.URL = localmusiclist[listBox1.SelectedIndex];musicplay(axWindowsMediaPlayer1.URL);label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[listBox1.SelectedIndex]);}
}
????在ListBox
控件中,存在一個事件監聽SelectedIndexChanged
,利用該事件,我們可以去獲取用戶切換列表,SelectedIndex
是獲取目前列表中選擇的序號,通過該序號和之前的localmusiclist
,我們可以獲取到音樂信息并且進行傳參調用函數,進行后續的音樂播放。
????同時,將Label
的內容設置為音樂文件的信息并展示。
4.3 音樂選擇功能
????函數定義:
private void musicplay(string filename)
{//功能實現見下方
}
????具體實現:
string extension = Path.GetExtension(filename).ToLower();
????首先,獲取當前文件名的后綴信息,判斷文件類型。
if (extension == ".ogg")
{if (currentVorbisReader != null){// 確保先停止當前播放再釋放資源if (waveOut.PlaybackState != PlaybackState.Stopped){waveOut.Stop();}currentVorbisReader.Dispose();}currentVorbisReader = new VorbisWaveReader(filename);waveOut.Init(currentVorbisReader);waveOut.Play();
}
????針對不同的文件類型,采用不同的處理方式:若是ogg
文件,調用NAudio
第三方庫總的Vorbis
和Wave
類來實現播放音樂。
????在播放新的音樂時,先檢測當前是否有正在進行播放或者是暫停播放的ogg
音樂,先進行處理再播放當前歌曲,可以防止同時初始化兩次WaveOut
產生播放異常。
else
{axWindowsMediaPlayer1.URL = filename;axWindowsMediaPlayer1.Ctlcontrols.play();
}
????若是其他類型的文件,使用C#原生庫中的WindowsMediaPlayer
控件實現播放。
4.4 暫停播放
private void button2_Click(object sender, EventArgs e)
{if (waveOut.PlaybackState == PlaybackState.Playing){waveOut.Pause(); // 暫停播放OGG}axWindowsMediaPlayer1.Ctlcontrols.stop(); // 停止其他格式的播放
}
????音樂暫停功能也需要先區分類型,如果waveOut
的播放狀態為正在播放,調用函數暫停音樂,否則就是調用WindowsMediaPlayer
的暫停函數。
4.5 播放下一首&&循環播放
????函數定義:
private void button3_Click(object sender, EventArgs e)
{//功能實現見下方
}
????具體實現:
if(localmusiclist.Count > 0)
{//記錄下一首音樂的索引int index = (listBox1.SelectedIndex + 1);axWindowsMediaPlayer1.URL = localmusiclist[index];musicplay(axWindowsMediaPlayer1.URL);label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);listBox1.SelectedIndex = index;
}
????這里采用索引來得到下一首音樂URL,再進行播放,同時更改Label
的信息顯示與SelectedIndex
的當前索引。
if (index >= localmusiclist.Count())
{index = 0;
}
????在索引大于當前音樂列表的時候,將Index
重置為零,從而實現循環播放功能。
4.6 音量控制
private void trackBar1_Scroll(object sender, EventArgs e)
{axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
}
????直接將WindowsMediaPlayer
的屬性和TrackBar
設置的值進行關聯即可實現音樂播放事的音樂控制了。
5. 完整代碼
????代碼倉庫:hmcy-zbx的windows課程設計作業
6. 總結&改進思路
????本次作業旨在通過導入第三方庫輔助自己的程序設計與學習更復雜的控件使用和控件之間的聯系,通過本次作業,我對于C#的控件使用掌握的更加深入了。
????盡管當前程序能實現較多的音樂文件格式播放,但是不能夠實現最新的音樂文件解析,例如:ape
文件與aac
文件。
????并且,缺少高級音頻功能的設置,例如增加音頻效果處理(如均衡器、聲音增強等)和支持音頻流的直接下載和播放。