c#基于winform制作音乐播放器
程序员文章站
2022-03-06 11:04:44
前言:项目是c#的winform 写的,使用的播放器是基于axwindowsmediaplayer。axwindowsmediaplayer的方法1 首先新建一个页面 如图所示: 图片左侧是列表 使用...
前言:项目是c#的winform 写的,使用的播放器是基于axwindowsmediaplayer。
axwindowsmediaplayer的方法
1 首先新建一个页面 如图所示: 图片左侧是列表 使用listview 右侧是背景图片。图片框框的地方是后面可以实现的,+和-按钮分别代表添加文件和删除文件 还有就是控制播放的顺序。下面的分别是修改歌词的字体 和展示/隐藏
2 新建一个透明的歌词页面[窗体]
3 新建一个半透明的页面[窗体]
4 业务代码
using system; using system.collections.generic; using system.componentmodel; using system.data; using system.drawing; using system.text; using system.windows.forms; using wmplib; using system.media; using system.io; using system.text.regularexpressions; using axwmplib; using system.drawing.drawing2d; using ccwin; namespace kenmusicplayer { public partial class musicplayer : skin_devexpress { public int index = 1; public int listindex; private bool first_in = true; //是否第一次进入歌词区域 private bool showlrc = true;//默认显示歌词 private int imageind = 0;//播放的图片下标 private list<string> imagelist;//播放的图片 private point closepoint;//关闭按钮的位置 private size dfsize;//最初的位置 //声音 soundplayer player = new soundplayer(); dictionary<string, string> dic = new dictionary<string, string>(); //播放列表 dictionary<string, iwmpmedia> playlistdict = new dictionary<string, iwmpmedia>(); list<string> al = new list<string>(); //当前歌词时间表 iwmpmedia media; /* *下面这一大段api调用,主要是用来设置歌词窗口的滚动条的 *但其实后面,我并没有怎么用到,只是在将滚动条滚动到底部时,用了一下 */ private const int wm_vscroll = 0x115; private const int sb_horz = 0; private const int sb_vert = 1; private const int sb_ctl = 2; private const int sb_both = 3; private const int sb_lineup = 0; private const int sb_lineleft = 0; private const int sb_linedown = 1; private const int sb_lineright = 1; private const int sb_pageup = 2; private const int sb_pageleft = 2; private const int sb_pagedown = 3; private const int sb_pageright = 3; private const int sb_thumbposition = 4; private const int sb_thumbtrack = 5; private const int sb_top = 6; private const int sb_left = 6; private const int sb_bottom = 7; private const int sb_right = 7; private const int sb_endscroll = 8; private const int wm_paint = 0x000f; [system.runtime.interopservices.dllimport("user32.dll")] public static extern bool scrollwindow(intptr hwnd, int xamount, int yamount, ref rectangle lprect, ref rectangle lpcliprect); [system.runtime.interopservices.dllimport("user32.dll")] public static extern int setscrollpos(intptr hwnd, int nbar, int npos, bool bredraw); [system.runtime.interopservices.dllimport("user32.dll")] public static extern int setscrollpos(int nbar, int npos, bool bredraw); [system.runtime.interopservices.dllimport("user32.dll")] public static extern int getscrollpos(intptr hwnd, int nbar); [system.runtime.interopservices.dllimport("user32.dll")] public static extern bool updatewindow(intptr hwnd); [system.runtime.interopservices.dllimport("user32.dll")] public static extern int sendmessage(intptr hwnd, int wmsg, int wparam, int lparam); public void setword() { } public musicplayer() { this.startposition = formstartposition.centerscreen;//窗口居中显示 initializecomponent(); } private void musicplayer_load(object sender, eventargs e) { initload(); } /// <summary> /// 初始化 加载播放列表 如歌词 背景图 定时器等等 /// </summary> private void initload() { try { bool flag = false; string folder = path.combine(appdomain.currentdomain.basedirectory, "bgimages"); directoryinfo root = new directoryinfo(folder); fileinfo[] files = root.getfiles(); string filename; for (int i = 0; i < files.length; i++) { filename = files[i].name.tolower(); if (filename.endswith(".png") || filename.endswith(".jpeg") || filename.endswith(".jpg")) { if (!flag) { imagelist = new list<string>(); this.picturebox1.image = image.fromfile(files[i].fullname); } imagelist.add(files[i].fullname); flag = true; } } playertype.text = playertype.items[0].tostring();//默认第一个 closepoint = this.skinbuttonclose.location; dfsize = this.size; richtextbox1.backcolor = this.transparencykey; skincomboboxfontname.text = skincomboboxfontname.items[0].tostring();//默认第一个 skincomboboxfontsize.text = skincomboboxfontsize.items[0].tostring();//默认第一个 comboboxskinselect.text = comboboxskinselect.items[0].tostring();//默认第一个 //this.backpalace = image.fromfile(comboboxskinselect.items[0].tostring());//默认第一个 lvdetail.allowdrop = true; lvdetail.view = view.details; lvdetail.dragenter += files_dragenter;//对象拖拽事件 lvdetail.dragdrop += files_dragdrop;//拖拽操作完成事件 //wmp.openstatechange += wmp_openstatechange; wmp.playstatechange += wmp_playstatechange; timerimgs.start(); } catch (exception ex) { console.writeline("错误:" + ex.message); } } /// <summary> /// 提供给透明歌词窗口的定时器调用的 /// </summary> /// <param name="s"></param> public void showtmform(bool s) { if (s) { this.btmform.show(); if (this.first_in) { this.lrcform.topmost = true; point point = this.location; point.y = point.y + this.height; this.lrcform.location = point; this.btmform.location = point; this.lrcform.width = this.width; this.btmform.width = this.width; this.first_in = false; } } else { this.first_in = true; this.btmform.hide(); } } /// <summary> /// 播放时会进入这个事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void wmp_playstatechange(object sender, _wmpocxevents_playstatechangeevent e) { loadlrc(); } /// <summary> /// 拖拽操作完成事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void files_dragdrop(object sender, drageventargs e) { try { string filename, fileextension, filesize, temp; fileinfo fi = null; listviewitem lvi = null; array array = (array)e.data.getdata(dataformats.filedrop); regex regex = new regex("(\\.mp3|\\.wav|\\.wma)"); string filepath; for (int i = 0; i < array.length; i++) { filepath = array.getvalue(i).tostring(); //属于音乐文件 且列表中不存在 if (regex.ismatch(filepath) && !dic.containskey(filepath)) { wmp.ctlcontrols.stop(); insertplaylist(out filename, out fileextension, out filesize, out temp, out fi, out lvi, filepath); } } } catch (exception ex) { messagebox.show(ex.message, "错误", messageboxbuttons.ok, messageboxicon.error); } } /// <summary> /// 插入播放列表 和字典集 /// </summary> /// <param name="filename"></param> /// <param name="fileextension"></param> /// <param name="filesize"></param> /// <param name="temp"></param> /// <param name="fi"></param> /// <param name="lvi"></param> /// <param name="filepath"></param> private void insertplaylist(out string filename, out string fileextension, out string filesize, out string temp, out fileinfo fileinfo, out listviewitem listviewitem, string filepath) { fileinfo = new fileinfo(filepath); temp = filepath.remove(filepath.lastindexof('.')); filename = path.getfilenamewithoutextension(filepath); fileextension = path.getextension(filepath); filesize = (fileinfo.length / 1024).tostring() + "kb"; listviewitem = new listviewitem(); listviewitem.text = index++.tostring(); listviewitem.subitems.addrange(new string[] { filename, fileextension, filesize, filepath }); lvdetail.items.add(listviewitem); //添加到播放列表 media = wmp.newmedia(filepath); //listindex++, //wmp.currentplaylist.insertitem(media); wmp.currentplaylist.appenditem(media); playlistdict.add(filepath, media); //杜绝重复项 dic.add(filepath, filename); } /// <summary> /// 文件拖拽进入 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void files_dragenter(object sender, drageventargs e) { if (e.data.getdatapresent(dataformats.filedrop)) { e.effect = dragdropeffects.link; } else { e.effect = dragdropeffects.none; } } /// <summary> /// 导入文件 /// </summary> private void tsmiloading_click(object sender, eventargs e) { string filename, fileextension, filesize, temp; fileinfo fi = null; listviewitem lvi = null; openfiledialog1.multiselect = true; openfiledialog1.filter = "mp3文件(*.mp3)|*.mp3|wav文件(*.wav)|*.wav|wma文件(*.wma)|*.wma"; if (openfiledialog1.showdialog() == dialogresult.ok) { //顺序播放 wmp.settings.setmode("shuffle", false); foreach (string filepath in openfiledialog1.filenames) { if (!dic.containskey(filepath)) { insertplaylist(out filename, out fileextension, out filesize, out temp, out fi, out lvi, filepath); } } } } /// <summary> /// 清除列表 /// </summary> private void listviewclear_click(object sender, eventargs e) { lvdetail.items.clear(); } /// <summary> /// 播放 /// </summary> private void tsmiplayer_click(object sender, eventargs e) { wmp.ctlcontrols.play(); } /// <summary> /// 暂停 /// </summary> private void tsmiwaiting_click(object sender, eventargs e) { wmp.ctlcontrols.pause(); } /// <summary> /// 停止 /// </summary> private void tsmistop_click(object sender, eventargs e) { wmp.ctlcontrols.stop(); } /// <summary> /// 退出 /// </summary> private void tsmiexit_click(object sender, eventargs e) { application.exit(); } /// <summary> /// 双击某项播放 /// </summary> private void lvdetail_doubleclick(object sender, eventargs e) { if (lvdetail.selecteditems.count > 0) { wmp.currentmedia = wmp.currentplaylist.item[int.parse(lvdetail.selecteditems[0].text) - 1]; } } /// <summary> /// 循环播放 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tsmixunhuan_click(object sender, eventargs e) { //点击项 toolstripmenuitem currentitem = (toolstripmenuitem)sender; toolstripitemcollection items = this.tsmiset.dropdownitems; toolstripmenuitem item; for (int i = 0; i < items.count; i++) { item = (toolstripmenuitem)items[i]; item.checked = false; if (item.name == currentitem.name) { item.checked = true; } } wmp.settings.setmode("loop", true); } //顺序 private void tsmidanqu_click(object sender, eventargs e) { iwmpmedia currentmedia = wmp.currentmedia; //点击项 toolstripmenuitem currentitem = (toolstripmenuitem)sender; toolstripitemcollection items = this.tsmiset.dropdownitems; toolstripmenuitem item; for (int i = 0; i < items.count; i++) { item = (toolstripmenuitem)items[i]; item.checked = false; if (item.name == currentitem.name) { item.checked = true; } } //顺序播放 wmp.settings.setmode("shuffle", false); } /// <summary> /// 图片宽高设置 /// </summary> /// <param name="imgtoresize"></param> /// <param name="size"></param> /// <returns></returns> public static image resizeimage(image imgtoresize, size size) { //获取图片宽度 int sourcewidth = imgtoresize.width; //获取图片高度 int sourceheight = imgtoresize.height; float npercent = 0; float npercentw = 0; float npercenth = 0; //计算宽度的缩放比例 npercentw = ((float)size.width / (float)sourcewidth); //计算高度的缩放比例 npercenth = ((float)size.height / (float)sourceheight); if (npercenth < npercentw) npercent = npercenth; else npercent = npercentw; //期望的宽度 int destwidth = (int)(sourcewidth * npercent); //期望的高度 int destheight = (int)(sourceheight * npercent); bitmap b = new bitmap(destwidth, destheight); graphics g = graphics.fromimage((system.drawing.image)b); g.interpolationmode = interpolationmode.highqualitybicubic; //绘制图像 g.drawimage(imgtoresize, 0, 0, destwidth, destheight); g.dispose(); return (system.drawing.image)b; } private void playertype_selectedindexchanged(object sender, eventargs e) { if (playertype.text == "顺序播放") { //顺序播放 wmp.settings.setmode("shuffle", false); } else if (playertype.text == "循环播放") { wmp.settings.setmode("loop", true); } else if (playertype.text == "随机播放") { //顺序播放 wmp.settings.setmode("shuffle", true); } } /// <summary> /// 定时器执行的方法,每隔1秒执行一次 歌词逐行显示 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void showlinelrc(object sender, eventargs e) { this.label1.text = this.wmp.ctlcontrols.currentpositionstring; if (this.lrcform == null) { this.lrcform = new tmform(); point pos = this.location; pos.y = lrcform.location.y + lrcform.height; this.location = pos; this.btmform = new btmform(); musicplayer mainform = (musicplayer)this.owner; btmform.location = pos; this.lrcform.owner = this; this.btmform.owner = this; this.btmform.hide(); this.lrcform.show(); } if (this.wmp.currentmedia == null) { this.richtextbox1.text = ""; return; } string durationstring = this.wmp.currentmedia.durationstring; int trackbarvalue = convert.toint32(this.wmp.ctlcontrols.currentposition); //this.trackbar1.maximum = convert.toint32(this.wmp.currentmedia.duration); //this.trackbar1.value = convert.toint32(this.wmp.ctlcontrols.currentposition); if (this.richtextbox1.text != "歌词文件不存在" && this.richtextbox1.text != "歌词文件内容为空") { int pos = al.indexof(trackbarvalue.tostring()); bool isar = this.richtextbox1.text.contains("歌手:"); bool isti = this.richtextbox1.text.contains("歌名:"); if (pos >= 0) { int n = isar ? 1 : 0; int m = isti ? 1 : 0; int height = 28 * (this.al.count + m + n); int max = height - this.richtextbox1.height; this.richtextbox1.selectall(); this.richtextbox1.selectioncolor = color.black; this.richtextbox1.selectionlength = 0;/**/ int l = this.richtextbox1.lines[pos + m + n].length; this.richtextbox1.select(this.richtextbox1.getfirstcharindexfromline(pos + m + n), l); this.richtextbox1.selectioncolor = color.orangered; this.richtextbox1.selectionlength = 0; //this.text = getscrollpos(this.richtextbox1.handle, sb_vert).tostring() + "-" + al.count + "-" + this.richtextbox1.height; if ((pos + m + n) * 28 <= max) { int start = this.richtextbox1.getfirstcharindexfromline(pos + m + n); this.richtextbox1.selectionstart = start; this.richtextbox1.scrolltocaret(); } else { //this.richtextbox1.focus(); sendmessage(this.richtextbox1.handle, wm_vscroll, sb_bottom, 0); updatewindow(this.richtextbox1.handle); //this.richtextbox1.selectionstart = this.richtextbox1.text.length; //this.richtextbox1.scrolltocaret(); } if (this.lrcform != null) { string l1 = this.richtextbox1.lines[pos + m + n]; string l2; if ((pos + m + n) < this.richtextbox1.lines.length - 1) { l2 = this.richtextbox1.lines[pos + m + n + 1]; } else { l2 = "。。。。。"; } this.lrcform.setlrc(l1, l2, pos); //this.lrcform.setlrc(arraylist al,); } } } //this.text = this.trackbar1.value.tostring(); /*if (trackbarvalue >= (this.trackbar1.maximum - 2)) { this.playmodechange(); }*/ } /// <summary> /// 载入歌词 /// </summary> /// <param name="lrc_filename">歌词路径名</param> public void loadlrc() { if (this.wmp.playstate == wmpplaystate.wmppsplaying) { iwmpmedia currentmedia = wmp.currentmedia; string fullpath = currentmedia.sourceurl; string gecipath = path.combine(path.getdirectoryname(fullpath), path.getfilenamewithoutextension(fullpath) + ".lrc"); //播放哪个资源 列表需选中 listview.listviewitemcollection listviewitems = lvdetail.items; lvdetail.fullrowselect = true; for (int i = 0; i < listviewitems.count; i++) { listviewitems[i].checked = false; listviewitems[i].selected = false; listviewitems[i].backcolor = color.white; if (listviewitems[i].subitems[4].text == fullpath) { listviewitems[i].checked = true; listviewitems[i].selected = true; listviewitems[i].backcolor = color.lightblue; } } if (!file.exists(gecipath)) { this.richtextbox1.text = "歌词文件内容为空"; return; } using (streamreader sr = new streamreader(new filestream(gecipath, filemode.open), encoding.default)) { string templrc = ""; while (!sr.endofstream) { templrc = sr.readtoend(); } if (templrc.trim() == "") { this.richtextbox1.text = "歌词文件内容为空"; return; } templrc = templrc.trim(); regex rg = new regex("\r*\n*\\[ver:(.*)\\]\r*\n*"); templrc = rg.replace(templrc, ""); rg = new regex("\r*\n*\\[al:(.*)\\]\r*\n*"); templrc = rg.replace(templrc, ""); rg = new regex("\r*\n*\\[by:(.*)\\]\r*\n*"); templrc = rg.replace(templrc, ""); rg = new regex("\r*\n*\\[offset:(.*)\\]\r*\n*"); templrc = rg.replace(templrc, ""); rg = new regex("\r*\n*\\[ar:(.*)\\]\r*\n*"); match mtch; mtch = rg.match(templrc); templrc = rg.replace(templrc, "\n歌手:" + mtch.groups[1].value + "\n"); rg = new regex("\r*\n*\\[ti:(.+?)\\]\r*\n*"); //这里注意贪婪匹配问题.+? mtch = rg.match(templrc); templrc = rg.replace(templrc, "\n歌名:" + mtch.groups[1].value + "\n"); rg = new regex("\r*\n*\\[[0-9][0-9]:[0-9][0-9].[0-9][0-9]\\]"); matchcollection mc = rg.matches(templrc); al.clear(); foreach (match m in mc) { string temp = m.groups[0].value; //this.text += temp + "+"; string mi = temp.substring(temp.indexof('[') + 1, 2); string se = temp.substring(temp.indexof(':') + 1, 2); string ms = temp.substring(temp.indexof('.') + 1, 2); //这是毫秒,其实我只精确到秒,毫秒后面并没有用 //this.text += mi + ":" + se + "+"; string time = convert.toint32(mi) * 60 + convert.toint32(se) + ""; //这里并没有添加毫秒 al.add(time); } templrc = rg.replace(templrc, "\n"); char[] remove = { '\r', '\n', ' ' }; this.richtextbox1.text = templrc.trimstart(remove); this.timer1.interval = 1000; this.timer1.tick += showlinelrc; this.timer1.start(); } } } private void wmp_enter(object sender, eventargs e) { loadlrc();//点击播放 } /// <summary> /// 删除选中的文件 并停止播放 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void skinbutton2_click(object sender, eventargs e) { try { listview.selectedindexcollection indexes = this.lvdetail.selectedindices; if (indexes.count > 0) { int index = indexes[0]; string path = this.lvdetail.items[index].subitems[4].text; iwmpplaylist iwmpplaylist = wmp.currentplaylist; //先移除播放列表 再移除listview列表 wmp.currentplaylist.removeitem(playlistdict[path]); playlistdict.remove(path); this.lvdetail.items[index].remove(); dic.remove(path); wmp.ctlcontrols.stop(); } } catch (exception ex) { messagebox.show("操作失败!\n" + ex.message, "提示", messageboxbuttons.ok, messageboxicon.exclamation, messageboxdefaultbutton.button1); } } /// <summary> /// 列表鼠标双击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void lvdetail_mousedoubleclick(object sender, mouseeventargs e) { try { listview.selectedindexcollection indexes = this.lvdetail.selectedindices; if (indexes.count > 0) { int index = indexes[0]; string path = this.lvdetail.items[index].subitems[4].text; wmp.ctlcontrols.playitem(playlistdict[path]); //wmp.url = path;//这种方式会失去播放列表【不是肉眼可见的listview列表】 wmp.ctlcontrols.stop(); wmp.ctlcontrols.play(); } } catch (exception ex) { messagebox.show("操作失败!\n" + ex.message, "提示", messageboxbuttons.ok, messageboxicon.exclamation, messageboxdefaultbutton.button1); } } /// <summary> /// 字体改变 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void skincomboboxfontname_selectedindexchanged(object sender, eventargs e) { if (this.lrcform != null) { this.lrcform.changelabelfont(this.skincomboboxfontname.selecteditem.tostring(), this.skincomboboxfontsize.selecteditem.tostring()); } } /// <summary> /// 字体大小改变 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void skincombobox1_selectedindexchanged(object sender, eventargs e) { if (this.lrcform != null) { this.lrcform.changelabelfont(this.skincomboboxfontname.selecteditem.tostring(), this.skincomboboxfontsize.selecteditem.tostring()); } } /// <summary> /// 歌词是否显示 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void skinbutton5_click(object sender, eventargs e) { if (this.lrcform == null) { return; } this.showlrc = !this.showlrc; this.skinbutton5.text = this.showlrc ? "关闭" : "显示"; if (this.showlrc) { this.btmform.show(); this.lrcform.show(); } else { this.btmform.hide(); this.lrcform.hide(); } } /// <summary> /// 背景图片切换 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timerimgs_tick(object sender, eventargs e) { if (imageind <= imagelist.count - 2) { imageind++; this.picturebox1.image.dispose(); this.picturebox1.image = image.fromfile(imagelist[imageind]); } else { imageind=0; } } /// <summary> /// 粘贴音乐到播放列表 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void lvdetail_keydown(object sender, keyeventargs e) { system.collections.specialized.stringcollection stringcollection = clipboard.getfiledroplist(); if (stringcollection != null) { string filename, fileextension, filesize, temp; fileinfo fi = null; listviewitem lvi = null; foreach (var item in stringcollection) { if ((item.tolower().endswith(".mp3") || item.tolower().endswith(".wav") || item.tolower().endswith(".wma")) && !dic.containskey(item) ) { insertplaylist(out filename, out fileextension, out filesize, out temp, out fi, out lvi, item); } } } } //选择皮肤 private void comboboxskinselect_selectedindexchanged(object sender, eventargs e) { string bgcolor = comboboxskinselect.selecteditem.tostring(); if (!string.isnullorempty(comboboxskinselect.selecteditem.tostring())) { switch (bgcolor) { case "渐变黑": this.borderpalace = kenmusicplayer.properties.resources.bg_black; break; case "天蓝色": this.borderpalace = kenmusicplayer.properties.resources.bg_light_blue; break; case "墨绿色": this.borderpalace = kenmusicplayer.properties.resources.bg_green; break; case "蓝色": this.borderpalace = kenmusicplayer.properties.resources.bg_s_blue; break; case "浅灰色": this.borderpalace = kenmusicplayer.properties.resources.bg_grey; break; case "亮色": this.borderpalace = kenmusicplayer.properties.resources.bg_light; break; default: this.borderpalace = kenmusicplayer.properties.resources.bg_black; break; } /*this.updatestyles(); this.update();*/ //this.backpalace = image.fromfile(comboboxskinselect.selecteditem.tostring()); } } /// <summary> /// 退出 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void skinbuttonclose_click(object sender, eventargs e) { //this.close(); application.exit(); } private void musicplayer_resize(object sender, eventargs e) { try { size size = this.size; int x = (size.width - dfsize.width) + closepoint.x; int y = closepoint.y;//(size.height - dfsize.height) + closepoint.y; point point = new point(x, y); this.skinbuttonclose.location = point; } catch (exception ex) { console.writeline("异常:" + ex.message); } } /// <summary> /// 改方法也是提供给透明歌词窗口用的,用来修改半透明窗体的位置,是透明歌词窗口和半透明窗体始终重合 /// </summary> /// <param name="pos"></param> public void movetmform(point pos) { this.btmform.location = pos; } } }
源码地址:...
以上就是c#基于winform制作音乐播放器的详细内容,更多关于c# 音乐播放器的资料请关注其它相关文章!
上一篇: java实现简单的猜数字小游戏