一、功能需求
- 播放
mp3
文件:可播放mp3文件 - 播放
ogg
文件:可播放ogg文件 - 用户界面:一个简单的窗口,包含播放和暂停按钮及文件选择功能
- 异常处理:程序能处理可能处理可能出现的异常,如文件不存在、文件读取错误等
- 兼容性:确保代码能在多个c#版本上运行
二、设计思路分析
架构选择
考虑到需求中的界面友好和跨版本兼容性,我们可以选择选择
windows forms
作为开发平台,windows forms
提供了一个简单而强大的方法来创建桌面应用程序,并且与c#高度兼容,在开发过程,我们选择.netframework 4.8.0进行程序设计。设计思路
界面设计: 使用
windows forms
工具箱中的控件如按钮、标签和文件对话框构建用户界面。功能编码: 使用
openfiledialog
允许用户选择音频文件。 根据文件扩展名调用相应的播放器对象进行播放。 播放控制,包括开始、暂停和停止。异常处理: 捕获并响应各种可能的运行时错误,如文件读取失败、文件格式不支持等,为用户提供清晰的错误信息。
难点分析
文件格式支持: 处理多种音频格式(
mp3
,ogg
等)要求使用不同的库,这可能导致代码复杂度增加。异常处理: 音频文件的播放中可能遇到多种异常情况,如文件损坏、编解码器不支持等。
三、窗体设计
按照需求设计窗体,并进行一定的美化
- label:展示当前播放的歌曲
- listbox:展示歌曲列表
- axwindowsmediaplayer:播放常规音乐
- button:选择歌曲文件、停止播放、下一曲
- tracebarl:用于音量控制
四、代码实现
头文件引入
using axwmplib; using naudio.vorbis; using naudio.wave; using system; using system.collections.generic; using system.io; using system.linq; using system.reflection.emit; using system.text; using system.threading; using system.threading.tasks; using system.windows.forms; using static system.windows.forms.visualstyles.visualstyleelement;
类成员变量定义
list<string> localmusiclist = new list<string> { }; private waveoutevent waveout = new waveoutevent(); private vorbiswavereader currentvorbisreader;
在类中,
localmusiclist
在音乐播放时用来追踪和管理用户加载的音乐文件集合,waveout
用于播放ogg
文件,currentvorbisreader
为当前播放ogg
文件的状态
按钮控件
歌曲文件选择
private void button1_click(object sender, eventargs e) { string[] files = { }; openfiledialog1.filter = "选择音频|*.mp3;*.flac;*.wav;*.ogg"; //同时打开多个文件 openfiledialog1.multiselect = true; 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) { string extension = path.getextension(file).tolower(); if (extension == ".mp3" || extension == ".flac" || extension == ".wav" || extension == ".ogg") { listbox1.items.add(file); localmusiclist.add(file); } else { messagebox.show($"不支持的文件格式:{file}", "文件错误", messageboxbuttons.ok, messageboxicon.warning); } } } }
这里我们通过
filter
方法来限制用户选择的音乐文件,防止后续播放功能报错,并在选择文件之后将选择的音乐列表放置到listbox
中,同时逻辑判断删除已有的列表,并将歌曲播放列表放入localmusiclist
中,再通过openfiledialog来判断文件是否读取成功。
暂停播放按钮
private void button2_click(object sender, eventargs e) { if (waveout.playbackstate == playbackstate.playing) { waveout.pause(); // 暂停播放ogg } axwindowsmediaplayer1.ctlcontrols.stop(); // 停止其他格式的播放 }
用
if
条件判断,如果在播放ogg就停止播放ogg,如果播放的是普通文件就停止普通播放器就行
播放下一首按钮
private void button3_click(object sender, eventargs e) { if (localmusiclist.count > 0) { int index = (listbox1.selectedindex + 1); if (index >= localmusiclist.count()) { index = 0; } axwindowsmediaplayer1.url = localmusiclist[index]; musicplay(axwindowsmediaplayer1.url); label1.text = path.getfilenamewithoutextension(localmusiclist[index]); listbox1.selectedindex = index; } }
判断
count
是否大于0,以此来判断是否能执行下一首播放的逻辑,如果index
大于localmusiclist
的长度,就将index
置0,以此来循环播放列表,在播放时调用musicplay
函数来播放音乐,同时用label
来显示当前播放音乐的信息。
音乐选择控件
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]); } }
当listbox1中的音乐选择发生改变时,会触发该事件函数,若localmusiclist.count > 0,就用musicplay播放选择中的音乐,并更新label1的值
音乐播放函数
private void musicplay(string filename) { string extension = path.getextension(filename).tolower(); try { if (extension == ".ogg") { if (currentvorbisreader != null) { // 确保先停止当前播放再释放资源 if (waveout.playbackstate != playbackstate.stopped) { waveout.stop(); } currentvorbisreader.dispose(); } currentvorbisreader = new vorbiswavereader(filename); waveout.init(currentvorbisreader); waveout.play(); } else { if (currentvorbisreader != null) { // 确保先停止当前播放再释放资源 if (waveout.playbackstate != playbackstate.stopped) { waveout.stop(); } currentvorbisreader.dispose(); } axwindowsmediaplayer1.url = filename; axwindowsmediaplayer1.ctlcontrols.play(); } } catch (exception ex) { messagebox.show($"无法播放文件:{filename}\n\n错误信息:{ex.message}", "播放错误", messageboxbuttons.ok, messageboxicon.error); } }
首先获取文件后缀名,然后判断后缀名是否为ogg,若为普通文件,则用c#自带的内置播放器即可完成播放,否则则需要下载安装naudio的第三方库中的vorbis和wave类来实现播放音乐,在播放时要检查是否正在播放ogg音乐,若是则停止播放当前音乐再播放其他音乐,同时这里使用try捕获播放错误来防止读取文件产生的错误导致程序卡死。
音量控制组件
private void trackbar1_scroll(object sender, eventargs e) { axwindowsmediaplayer1.settings.volume = trackbar1.value; }
这里将axwindowsmediaplayer1的按钮联动到tracebar1上,实现用tracebar1来控制音量。
五、完整代码
```c# using axwmplib; using naudio.vorbis; using naudio.wave; using system; using system.collections.generic; using system.io; using system.linq; using system.reflection.emit; using system.text; using system.threading; using system.threading.tasks; using system.windows.forms; using static system.windows.forms.visualstyles.visualstyleelement; namespace _4._23上课code { public partial class form1 : form { list<string> localmusiclist = new list<string> { }; private waveoutevent waveout = new waveoutevent(); private vorbiswavereader currentvorbisreader; public form1() { initializecomponent(); } private void musicplay(string filename) { string extension = path.getextension(filename).tolower(); try { if (extension == ".ogg") { if (currentvorbisreader != null) { // 确保先停止当前播放再释放资源 if (waveout.playbackstate != playbackstate.stopped) { waveout.stop(); } currentvorbisreader.dispose(); } currentvorbisreader = new vorbiswavereader(filename); waveout.init(currentvorbisreader); waveout.play(); } else { if (currentvorbisreader != null) { // 确保先停止当前播放再释放资源 if (waveout.playbackstate != playbackstate.stopped) { waveout.stop(); } currentvorbisreader.dispose(); } axwindowsmediaplayer1.url = filename; axwindowsmediaplayer1.ctlcontrols.play(); } } catch (exception ex) { messagebox.show($"无法播放文件:{filename}\n\n错误信息:{ex.message}", "播放错误", messageboxbuttons.ok, messageboxicon.error); } } private void axwindowsmediaplayer1_enter(object sender, eventargs e) { } private void button1_click(object sender, eventargs e) { string[] files = { }; openfiledialog1.filter = "选择音频|*.mp3;*.flac;*.wav;*.ogg"; //同时打开多个文件 openfiledialog1.multiselect = true; 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) { string extension = path.getextension(file).tolower(); if (extension == ".mp3" || extension == ".flac" || extension == ".wav" || extension == ".ogg") { listbox1.items.add(file); localmusiclist.add(file); } else { messagebox.show($"不支持的文件格式:{file}", "文件错误", messageboxbuttons.ok, messageboxicon.warning); } } } } 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]); } } private void trackbar1_scroll(object sender, eventargs e) { axwindowsmediaplayer1.settings.volume = trackbar1.value; } private void button2_click(object sender, eventargs e) { if (waveout.playbackstate == playbackstate.playing) { waveout.pause(); // 暂停播放ogg } axwindowsmediaplayer1.ctlcontrols.stop(); // 停止其他格式的播放 } private void button3_click(object sender, eventargs e) { if (localmusiclist.count > 0) { int index = (listbox1.selectedindex + 1); if (index >= localmusiclist.count()) { index = 0; } axwindowsmediaplayer1.url = localmusiclist[index]; musicplay(axwindowsmediaplayer1.url); label1.text = path.getfilenamewithoutextension(localmusiclist[index]); listbox1.selectedindex = index; } } private void form1_load(object sender, eventargs e) { } } } ```
六、总结
以上就是基于c#实现简单的音乐播放器的详细内容,更多关于c#音乐播放器的资料请关注代码网其它相关文章!
发表评论