当前位置: 移动技术网 > IT编程>开发语言>c# > 基于C#的音乐播放器主Form实现代码

基于C#的音乐播放器主Form实现代码

2019年07月18日  | 移动技术网IT编程  | 我要评论
本文所述为一个由c#编写的音乐播放器的主form代码,里面有一些小技巧还是不错的,现共享给大家参考一下。里面有播放器背景设置、线程定义、调用读取文件目录方法、播放时间计数器

本文所述为一个由c#编写的音乐播放器的主form代码,里面有一些小技巧还是不错的,现共享给大家参考一下。里面有播放器背景设置、线程定义、调用读取文件目录方法、播放时间计数器、设置lv背景、获取播放歌曲、播放按钮,切换播放or暂停、切换歌曲到下一首,调用切歌方法、显示播放列表、歌词局中、播放窗体最小化隐藏到托盘设置、进度条滚动模块、从歌曲列表中删除文件等等功能。且各个功能模板均备有较为详细的注释,便于大家阅读理解。

程序主要代码如下:

using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.windows.forms;
using system.io;
using system.drawing.imaging;
using system.threading;
namespace mymusicbox
{
  public partial class mainform : form
  {
    public mainform()
    {
      initializecomponent();
      setstyle(controlstyles.userpaint, true);
      setstyle(controlstyles.optimizeddoublebuffer, true);
      setstyle(controlstyles.allpaintinginwmpaint, true);
      setstyle(controlstyles.doublebuffer, true); 
     
    }
    song mysong = null;//播放的歌曲对象
    listviewitem itemlrc;//打开歌词路径项
    bitmap bm ;//用于动态设置lv背景
    public savinginfo sa = null;//持久化信息类
    thread thread;//后台线程
 
    #region 加载事件
    private void mainform_load(object sender, eventargs e)
    {
        //调用读取配置文件方法
        path.readpath();
        //窗体背景设置为配置文件中的图片
        this.backgroundimage = image.fromfile(path.bgpath);
        //调用读取文件目录方法
        path.readsong();
        //读取播放列表
        sa = new savinginfo();
        sa.loadplaylist();
        //绑定lv
        bindalllv();
        bindplaylv();
        setlv();
        setlrcbg();
        timer1.enabled = path.playing;
        //显示时间
        lbltime.text = system.datetime.now.tostring();
        //两个lbl用来根据歌曲总长和播放长度显示进度,设置位置重叠
        lblruning.location = lbllong.location;
        //启动线程
        thread = new thread(renovate);
        thread.isbackground = true;
        thread.start();
      
    }
    #endregion
    #region 后台刷新
    /// <summary>
    /// 时间计数状态等刷新
    /// </summary>
    private void renovate()
    {
      //while (true)
      //{
      //  //计数
      //  count();
      //  //获取当前时间
      //  lbltime.text = system.datetime.now.tostring();
      //  //无歌曲提示,如果播放列表为空且当前播放列表为显示状态
      //  if (lvplay.items.count == 0 && lvplay.visible)
      //    lblts.visible = true;
      //  else
      //    lblts.visible = false;
      //  thread.sleep(1000);
      //}
    }
    #endregion
    #region 设置lv背景
    /// <summary>
    /// 设置lv背景
    /// </summary>
    public void setlv()
    {
      bm = new bitmap(this.backgroundimage, this.width, this.height);
      //绘制矩形,定义起始位置和宽高
      rectangle r = new rectangle(lvplay.location.x, lvplay.location.y, lvplay.width, lvsong.height);
      //按矩形尺寸和起始位置截取bm的一部分
      bm= bm.clone(r,bm.pixelformat);
      //把截取到的图片设置为lv背景,达到与主窗体背景完美契合的效果
      lvsong.beginupdate();
      lvsong.backgroundimage = (image)bm;
      lvsong.endupdate();
      lvplay.beginupdate();
      lvplay.backgroundimage = (image)bm;
      lvplay.endupdate();
    }
    #endregion
    
    #region 获取歌曲
    /// <summary>
    /// 获取播放歌曲
    /// </summary>
    private void getsong()
    {
      //接收播放歌曲方法,获得一个歌曲对象
      this.mysong = playlist.play();
      //如果歌曲对象不为空
      if (mysong != null)
      {
        //播放器路径设置为该歌曲路径
        wmp.url = mysong.filename;
        //调用方法,显示歌曲名、歌手
        lblname.text = playlist.getname();
        lblsinger.text = playlist.getsinger();
        mysong.songstate = songplaystate.played;//修改播放状态
        //播放按钮图片修改为暂停图片
        btnplay.image = image.fromfile("images\\stop.png"); 
        try
        {
          
          //读取歌词路径
          path.readlrc();
          addlrc();
          //启动一个定时器,此定时器只控制歌词轮播
          timer2.start();
        }
        catch (exception)
        {
          lrcnull();
          itemlrc = new listviewitem();
          itemlrc.subitems.add("找不到该歌曲歌词文件!");
          itemlrc.forecolor = color.blue;
          itemlrc.font = new font("微软雅黑", 14.25f, ((fontstyle)((fontstyle.bold | fontstyle.underline))), graphicsunit.point, ((byte)(134)));
          lvlrc.items.add(itemlrc);
        }
      }
    }
    #endregion
    #region 主定时器
    //定时器1
    private void timer1_tick(object sender, eventargs e)
    {
      if (path.songpath == "")
      {
        timer1.enabled = false;
        return;
      }
      
      //如果当前无播放歌曲,调用获取歌曲的方法
      if (this.mysong == null)
      {
        getsong();
      }
      //自动下一首,如果当前播放完毕
      if (this.wmp.playstate == wmplib.wmpplaystate.wmppsstopped)
      {
        this.mysong = null; // 将歌曲设为空
        path.lrcpath = "";
        path.diclrc.clear();
        playmodel();
        playlist.playnext();
        thread.sleep(1000);
      }
      // 切歌,当前有播放歌曲且播放状态为cut
      if (this.mysong != null && this.mysong.songstate == songplaystate.cut)
      {
        this.wmp.url = "";//置空
        timer2.stop();
        path.diclrc.clear();
        path.lrcpath = "";
        this.mysong = null;
      }
      //如果当前有播放歌曲,需要获取的一些属性
      if (wmp.url!="")
      {
        //设置当前播放歌曲颜色
        songcolor();
        //获取音量控件显示值,根据控制刻度数量计算
        this.trackbar1.value = wmp.settings.volume / 10;
        //歌曲时间显示,一个是总长度,一个是已播放长度,字符串类型
        lblall.text = wmp.currentmedia.durationstring;
        lblrun.text = wmp.ctlcontrols.currentpositionstring;
        //进度条,使用了两个lbl控件,歌曲长度/已播放长度=lbl1的宽/lbl2的宽
        //乘1000为防止数据过小出现错误
        double temp = (wmp.currentmedia.duration*1000) / (wmp.ctlcontrols.currentposition*1000);
        double width = lbllong.width;
        double avg = width / temp;
        //判断>1为了防止avg数值小于int界限
        if(avg>1)
          lblruning.width = convert.toint32(avg);
        picrun.left = lblruning.right;
        //托盘显示播放歌曲
        this.notifyicon1.text =lblname.text + lblsinger.text;
      }
    }
    #endregion
    #region 播放按钮
    /// <summary>
    /// 播放按钮,切换播放or暂停
    /// </summary>
    private void btnplay_click(object sender, eventargs e)
    {
      if(!timer1.enabled)
        timer1.start();
      //如果当前为正在播放
      if (wmp.playstate == wmplib.wmpplaystate.wmppsplaying)
      {
        //暂停播放
        wmp.ctlcontrols.pause();
        //按钮图片修改为播放
        btnplay.image = image.fromfile("images\\play.png");
        //停止控制歌词滚动的定时器
        if (timer2.enabled)
          timer2.stop();
      }
      else if (wmp.playstate == wmplib.wmpplaystate.wmppspaused)
      {
        //开始播放
        wmp.ctlcontrols.play();
        //按钮图片修改为暂停
        btnplay.image = image.fromfile("images\\stop.png");
        //启动歌词滚动
        if (!timer2.enabled&&path.diclrc.count>0)
          timer2.start();
      }
    }
    #endregion
    #region 切歌
    //切换下一首,调用切歌方法
    private void btnright_click(object sender, eventargs e)
    {
      playlist.cut(false);
    }
    //上一首,调用切歌方法
    private void btnleft_click(object sender, eventargs e)
    {
      playlist.cut(true);
    }
    #endregion
    #region 音量
    //静音,静音!=音量为0
    private void btnmodel_click(object sender, eventargs e)
    {
      //如果播放器非静音状态,前景文字显示红叉,状态改为静音
      if (wmp.settings.mute == false)
      {
        btnsound.text = "×";
        wmp.settings.mute = true;
      }
      else//反之,已是静音状态,清空红叉,设置非静音状态
      {
        btnsound.text = "";
        wmp.settings.mute = false;
      }
    }
    //设置音量,此事件为控制刻度值变化时
    private void trackbar1_scroll(object sender, eventargs e)
    {
      //音量设置为控制刻度*10(因为初始化的时候是/10)
      wmp.settings.volume = this.trackbar1.value * 10;
    }
    #endregion
    #region 歌曲列表操作
    /// <summary>
    /// 绑定所有歌曲lv数据
    /// </summary>
    private void bindalllv()
    {
      //如果所有歌曲集合为空,结束
      if (playlist.song == null)
        return;
      lvsong.items.clear();
      //遍历集合绑定到所有歌曲lv
      foreach (song s in playlist.song)
      {
        listviewitem item = new listviewitem(s.name);
        item.tag = s;
        item.subitems.add(s.singer);
        lvsong.items.add(item);
      }
    }
    //点击显示所有歌曲
    private void tslblall_click(object sender, eventargs e)
    {
      //隐藏播放列表
      lvplay.visible = false;
      //两个lv位置重叠
      lvsong.location = lvplay.location;
      //点击后改变背景色
      tslblall.backcolor = color.silver;
      tslblplay.backcolor = color.transparent;
      //显示所有歌曲lv
      lvsong.visible = true;
    }
    //点击显示播放列表
    private void tslblplay_click(object sender, eventargs e)
    {
      //调用绑定播放lv数据
      bindplaylv();
      //背景色改变
      tslblplay.backcolor = color.silver;
      tslblall.backcolor = color.transparent;
      //隐藏所有歌曲lv
      lvsong.visible = false;
      //显示播放lv
      lvplay.visible = true;
    }
    /// <summary>
    /// 绑定播放列表
    /// </summary>
    private void bindplaylv()
    {
      //如果播放集合不为空
      if (playlist.play!=null)
      {
        lvplay.items.clear();
        //遍历集合绑定播放lv
        foreach (song s in playlist.play)
        {
          int id = lvplay.items.count + 1;
          s.id = id;
          listviewitem item = new listviewitem(id.tostring());
          item.subitems.add(s.name);
          item.tag = s;
          lvplay.items.add(item);
        } 
      }
    }
    /// <summary>
    /// 歌曲计数
    /// </summary>
    private void count()
    {
      //if (lvsong.visible)
      //  lblcount.text = "已选" + lvsong.checkeditems.count + "\\总" + lvsong.items.count;
      //if (lvplay.visible)
      //  lblcount.text = "总" + lvplay.items.count;
    }
    #endregion
    #region 歌词操作
    /// <summary>
    /// 设置歌词背景
    /// </summary>
    public void setlrcbg()
    {
      bm = new bitmap(this.backgroundimage, this.width, this.height);
      //绘制矩形,定义起始位置和宽高
      rectangle r = new rectangle(lvlrc.location.x, lvlrc.location.y, lvlrc.width, lvlrc.height);
      //按矩形尺寸和起始位置截取bm的一部分
      bm = bm.clone(r, pixelformat.undefined);
      //把截取到的图片设置为lv背景,达到与主窗体背景完美契合的效果
      lvlrc.beginupdate();
      lvlrc.backgroundimage = (image)bm;
      lvlrc.endupdate();
    }
    int nullcount;//记录空行位置
    /// <summary>
    /// 设置空行,使歌词局中
    /// </summary>
    private void lrcnull()
    {
      lvlrc.items.clear();
      nullcount = (int)math.ceiling(convert.todouble(lvlrc.height / 30 / 2));
      for (int i = 0; i <= nullcount; i++)
      {
        lvlrc.items.add("");
      }
    }
    /// <summary>
    /// 添加歌词
    /// </summary>
    private void addlrc()
    {
      lrcnull();
      foreach (string key in path.diclrc.keys)
      {
        listviewitem item = new listviewitem();
        item.subitems.add(path.diclrc[key]);
        item.tag = key;
        lvlrc.items.add(item);
      }
    }
    //只控制歌词轮播
    private void timer2_tick(object sender, eventargs e)
    {
      //调用显示歌词的方法
      showlrc();
    }
    /// <summary>
    /// 显示歌词
    /// </summary>
    private void showlrc()
    {
      foreach (listviewitem item in lvlrc.items)
      {
        if (item.tag == null)
          continue;
        if (item.tag.tostring() == lblrun.text )
        {
          item.forecolor = color.darkorange;
          item.font = new font("华文琥珀", 16f, fontstyle.regular, graphicsunit.point, ((byte)(134)));
          lvlrc.items[item.index -1].forecolor = color.silver;
          lvlrc.items[item.index - 1].font = new font("微软雅黑", 12f, fontstyle.regular, graphicsunit.point, ((byte)(134)));
          if (item.index + 1<lvlrc.items.count)
            lvlrc.items[item.index+1].ensurevisible();       
        }
      }
    }
    #endregion
    #region 窗体隐藏到托盘设置
    //最小化到托盘
    private void btnmix_click(object sender, eventargs e)
    {
      this.hide();
    }
    //主窗体大小状态变化时
    private void mainform_sizechanged(object sender, eventargs e)
    {
      if (this.windowstate == formwindowstate.minimized)
      {
        //启动一个控件,该控制可以让程序在右下角显示图标,需要提前设置该控制显示的图标图片
        this.notifyicon1.visible = true;
      }
    }
    //托盘显示,双击显示窗体
    private void notifyicon1_mousedoubleclick(object sender, mouseeventargs e)
    {
      showmain();
    }
    /// <summary>
    /// 显示主窗体
    /// </summary>
    public void showmain()
    {
      if (!this.visible)
      {
        this.topmost = true;
        this.show();
        this.topmost = false;
      }
      else
      {
        this.topmost = true;
        this.topmost = false;
      }
    }
    //托盘打开窗体
    private void tsmishow_click(object sender, eventargs e)
    {
      showmain();
    }
    //托盘退出
    private void tsmiexit_click(object sender, eventargs e)
    {
      application.exit();
    }
    #endregion
    #region 窗体位移
    point mouseoff;//鼠标移动位置变量
    bool leftflag;//标记是否为左键
    private void pnlmain_mousedown(object sender, mouseeventargs e)
    {
      if (e.button == mousebuttons.left)
      {
        mouseoff = new point(-e.x, -e.y); //得到变量的值
        leftflag = true; //点击左键按下时标注为true;
      }
    }
    private void pnlmain_mousemove(object sender, mouseeventargs e)
    {
      if (leftflag)
      {
        point mouseset = control.mouseposition;
        mouseset.offset(mouseoff.x, mouseoff.y); //设置移动后的位置
        location = mouseset;
      }
    }
    private void pnlmain_mouseup(object sender, mouseeventargs e)
    {
      if (leftflag)
      {
        leftflag = false;//释放鼠标后标注为false;
      }
    }
  #endregion
    #region 进度条滚动块移动
    int runx;//记录滚动块初始位置
    private void picrun_mousedown(object sender, mouseeventargs e)
    {
      runx = e.x;
    }
    //释放鼠标位移,进度前进
    private void picrun_mouseup(object sender, mouseeventargs e)
    {
      picrun.left += e.x - runx - picrun.width / 2;
      if (picrun.left > lbllong.right)
        picrun.left = lbllong.right;
      if(picrun.left<lbllong.left)
        picrun.left = lbllong.left;
      if (mysong != null)
      {
        lblruning.width = picrun.right- lblruning.left;
        double temp = (lbllong.width*1000.0 )/ (lblruning.width*1000.0);
        wmp.ctlcontrols.currentposition = wmp.currentmedia.duration / temp;
      }
    }
    #endregion
    #region 歌曲增删操作
    //添加歌曲到播放列表
    private void tsmiadd_click(object sender, eventargs e)
    {
      if (lvsong.checkeditems.count > 0)
      {
        foreach (listviewitem item in lvsong.checkeditems)
        {
           // 遍历播放集合,如果存在不添加
           foreach (song s in playlist.play)
           {
             if (s.name == item.text)
             {
               playlist.play.remove(s);
               break;
             }
           }
           playlist.play.add(item.tag as song);
        }
      }
    }
    //所有歌曲:删除选中歌曲
    private void tsmidel_click(object sender, eventargs e)
    {
      foreach (listviewitem item in lvsong.items)
      {
        if (item.checked)
        {
          playlist.song.remove(item.tag as song);
        } 
      }
      bindalllv();
    }
    //全选歌曲
    private void tsmicheck_click(object sender, eventargs e)
    {
      foreach (listviewitem item in lvsong.items)
      {
        if (tsmicheck.text == "全部选中")
        {
          item.checked = true;
          if(item.index+1==lvsong.items.count)
            tsmicheck.text = "取消选中";
        }
        else
        {
          item.checked = false;
          if (item.index + 1 == lvsong.items.count)
            tsmicheck.text = "全部选中";
        }
      }
    }
    //选中项的同时选中复选框
    private void lvsong_mousedown(object sender, mouseeventargs e)
    {
      if (lvsong.selecteditems.count > 0 && e.button == mousebuttons.left)
      {
        lvsong.selecteditems[0].checked = true;
      }
    }
    //播放列表删除事件
    private void tsmiplaydel_click(object sender, eventargs e)
    {
      foreach (listviewitem item in lvplay.items)
      {
        if (item.selected)
        {
          //playlist.id = (lvplay.items[item.index+1].tag as song).id;
          //this.song = null;
          playlist.play.remove(item.tag as song);
        }
      }
      bindplaylv();
    }
    //清空播放列表
    private void tsmiplayclear_click(object sender, eventargs e)
    {
      playlist.play.clear();
      this.mysong = null;
      bindplaylv();
    }
    //从播放列表删除文件
    private void tsmiplaydelfile_click(object sender, eventargs e)
    {
      if (lvplay.selecteditems.count > 0)
      {
        delfile(lvplay.selecteditems[0]);
      }
    }
    /// <summary>
    /// 删除某项对应文件
    /// </summary>
    /// <param name="item"></param>
    private void delfile(listviewitem item)
    {
      try
      {
        string path = (item.tag as song).filename;
        file.delete(path);
        bindalllv();
        bindplaylv();
      }
      catch (exception)
      {
        messagebox.show("该文件为只读文件或用户权限不够,无法删除!");
      }
    }
    //从所有歌曲中删除文件
    private void tsmidelfile_click(object sender, eventargs e)
    {
      if (lvsong.selecteditems.count > 0)
      {
        delfile(lvsong.selecteditems[0]);
      }
    }
    //双击列表项播放歌曲
    private void lvplay_doubleclick(object sender, eventargs e)
    {
      if (!timer1.enabled)
      {
        playlist.id = (lvplay.selecteditems[0].tag as song).id;
        timer1.start();
      }
      if (lvplay.selecteditems.count > 0)
      {
        playlist.id = (lvplay.selecteditems[0].tag as song).id;
        this.mysong = null;
      }
    }
    #endregion
    #region 设置
    //跳转设置窗体
    private void btnset_click(object sender, eventargs e)
    {
      setform set = new setform();
      set.parent = this;//把主窗体传过去
      set.show(this);
    }
    #endregion
    #region 回滚
    /// <summary>
    /// 路径重置后
    /// </summary>
    public void back()
    {
      bindalllv();
      playlist.update();
      timer1.start();
    }
    #endregion
    #region 退出
    //关闭时保存列表
    private void mainform_formclosing(object sender, formclosingeventargs e)
    {
      if (path.savelist)
        sa.saveplaylist();
    }
    //面板退出
    private void btnexit_click(object sender, eventargs e)
    {
      if (path.exit)
      {
        application.exit();
      }
      else
      {
        this.hide();
      }
    }
 
    #endregion
    #region 背景颜色等变换控制
    private void btnleft_mouseenter(object sender, eventargs e)
    {
      ((button)sender).backgroundimage = image.fromfile("images//allbtn_highlight.png");
    }
    private void btnleft_mouseleave(object sender, eventargs e)
    {
      ((button)sender).backgroundimage = null;
    }
    private void tslblplay_mouseenter(object sender, eventargs e)
    {
      ((toolstriplabel)sender).backgroundimage = image.fromfile("images//album_bkg_wubian.png");
    }
    private void tslblplay_mouseleave(object sender, eventargs e)
    {
      ((toolstriplabel)sender).backgroundimage = null;
    }
    //选中改变颜色
    private void lvsong_itemchecked(object sender, itemcheckedeventargs e)
    {
      foreach (listviewitem item in lvsong.items)
      {
        if (item.checked)
        {
          item.forecolor = color.darkorange;
        }
        else
        {
          item.forecolor = color.dimgray;
        }
      }
    }
    /// <summary>
    /// 当前播放歌曲改变颜色
    /// </summary>
    private void songcolor()
    {
      foreach (listviewitem item in lvplay.items)
      {
        if (item.subitems[1].text == lblname.text)
        {
          item.forecolor = color.deepskyblue;
        }
        else
        {
          item.forecolor = color.white;
        }
      }
    }
    #endregion
    #region 选择歌词
    private void lvlrc_mousedown(object sender, mouseeventargs e)
    {
      if (lvlrc.selecteditems.count>0&&lvlrc.selecteditems[0] == itemlrc)
      {
        if (path.openlrc())
        {
          addlrc();
          //启动一个定时器,此定时器只控制歌词轮播
          timer2.start();
        }
      }
    }
    #endregion
    #region 窗体最大化设置
    size now;//原始尺寸
    point pn;//原始位置
    //最大化
    private void btnmax_click(object sender, eventargs e)
    {
      size max = new size(screen.primaryscreen.workingarea.width - 10, screen.primaryscreen.workingarea.height - 20);
      if (this.size != max)
      {
        pn = this.location;
        now= this.size;
        this.size = max;
        this.left = 5;
        this.top = 5;
        btnmax.image = image.fromfile("images//max1.png")
;
      }
      else
      {
        this.location = pn;
        this.size = now;
        btnmax.image = image.fromfile("images//max.png");
      }
      setlv();
      setlrcbg();
    }
    #endregion
    #region 歌词、mv切换
    private void tsmilrc_click(object sender, eventargs e)
    {
      lvlrc.visible = true;
      wmp.visible = false;
      tsmilrc.backcolor = color.lawngreen;
      tsmimv.backcolor = color.transparent;
    }
    private void tsmimv_click(object sender, eventargs e)
    {
      wmp.location = lvlrc.location;
      wmp.size = lvlrc.size;
      lvlrc.visible = false;
      wmp.visible = true;
      tsmilrc.backcolor = color.transparent;
      tsmimv.backcolor = color.lawngreen;
    }
    #endregion
    #region 播放模式切换
    /// <summary>
    /// 播放模式
    /// </summary>
    private void playmodel()
    {
      if (tsmione.checked)
      {
        playlist.playone();
      }
      else if (tsmisj.checked)
      {
        playlist.playrandom();
      }
    }
    private void tsmixh_click(object sender, eventargs e)
    {
      toolstripmenuitem ts=((toolstripmenuitem)sender);
      foreach(toolstripmenuitem item in tsmimodel.dropdownitems)
      {
        if (ts.checked && ts == item)
        {
          continue;
        }
        else
        {
          item.checked = false;
        }
      }
    }
    #endregion
    
  }
}

希望本文所述示例对大家的c#程序开发能够起到一定的借鉴价值。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网