欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-17 08:39:28
本文所述为一个由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#程序开发能够起到一定的借鉴价值。