winform制作简易音乐播放器

一.功能说明

1. 程序应能够读取MP3,ogg文件,并播放其中的音频。

2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。

3. 程序应具有良好的用户界面,方便用户进行操作。

4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行


二.winform窗体控件设计

通过button控件我们设计“播放ogg文件”“选择歌曲”“停止播放”和“下一首”这四个功能模块,listbox模块的右侧由一个竖着的进度条来控制音量,listbox用于显示我们的音乐播放列表,open file dialog1用于获取音乐文件,同时利用Windows自带的控件axWindowsMediaPlayer控件来实现音乐的播放功能,同时它也具有音乐播放器基本的暂停播放音量调节的作用。


三.代码实现

using NAudio;
using NAudio.Wave;
using NAudio.Vorbis;
using NVorbis.Contracts;

这些 using 声明导入了 NAudio 库中所需的命名空间,以便在代码中直接使用 NAudio 提供的类和接口。

 private void button1_Click(object sender, EventArgs e)
 {
     openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav";
     openFileDialog1.Multiselect = true;

     if (openFileDialog1.ShowDialog() == DialogResult.OK)
     {
         localmusicList.Clear();
         listBox1.Items.Clear();//清理控件

         if (files != null)
         {
             Array.Clear(files, 0, files.Length);
         }//清理文件

         files = openFileDialog1.FileNames;
         string[] arry = files;
         foreach (string x in arry)
         {
             listBox1.Items.Add(x);
             localmusicList.Add(x);
         }
     }
 }

这段代码实现的功能是当用户点击按钮1时,会弹出一个文件选择对话框,用户可以选择一个或多个音频文件。选择完成后,选中的文件会被添加到一个列表框中,并且它们的路径会被存储在 localmusicList 列表中。同时,之前选择的文件列表和路径数组都会被清空,以便存储新的选择。

 private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
 {
     if (localmusicList.Count > 0)
     {
         int selectedIndex = listBox1.SelectedIndex;
         if (selectedIndex >= 0)
         {
             string selectedFile = localmusicList[selectedIndex];
             if (!selectedFile.EndsWith(".ogg"))
             {
                 axWindowsMediaPlayer1.URL = selectedFile;
                 musicplay(axWindowsMediaPlayer1.URL);
                 label1.Text = Path.GetFileNameWithoutExtension(selectedFile);
             }
         }
     }
 }

这段代码是一个事件处理方法,当列表框中的选项被选中时触发。它的功能是根据用户在列表框中选择的音乐文件,自动播放选中的音乐,并在标签中显示当前播放的音乐文件名(不包括扩展名)。

private void trackBar1_Scroll(object sender, EventArgs e)
{
    axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
}

这个方法是当用户滚动滑动条时触发的事件处理方法。它的作用是将滑动条的当前值设置为 Windows Media Player 控件 axWindowsMediaPlayer1 的音量值。

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;
    }
}

这个方法是当用户点击按钮3时触发的事件处理方法。它的功能是播放列表中的下一首音乐。

具体地说,该方法首先检查当前播放列表中是否有音乐文件(即 localmusicList.Count > 0)。如果有音乐文件,则执行以下操作:

  1. 计算下一首音乐的索引:通过 listBox1.SelectedIndex + 1 获取当前选中音乐的下一个索引位置。

  2. 检查下一首音乐的索引是否超出了列表的范围:如果 index 大于等于 localmusicList 的长度,说明已经到达了列表的末尾,因此将 index 设置为 0,即播放列表的第一首音乐。

  3. 将下一首音乐的路径赋给 Windows Media Player 控件 axWindowsMediaPlayer1URL 属性,以播放该音乐。

  4. 调用 musicplay 方法,将下一首音乐的路径作为参数传递给它,以实现音乐的播放功能。

  5. 更新标签 label1,将当前播放的音乐文件名(不包括扩展名)显示在标签上。

  6. 将列表框中的选中项设置为下一首音乐的索引,以确保列表框中显示正确的当前播放音乐。

这样,用户点击按钮3时,就可以顺序播放列表中的音乐文件,并在界面上显示当前播放的音乐文件名。

 private void button5_Click(object sender, EventArgs e)
 {
     OpenFileDialog openFiledialog = new OpenFileDialog();
     openFiledialog.Filter = "打开音频|*.ogg";
     string oggFilePath = "";

     if (openFiledialog.ShowDialog() == DialogResult.OK)
     {
         oggFilePath = openFiledialog.FileName;
         listBox1.Items.Add(oggFilePath); // 将选择的ogg文件路径添加到列表框
         localmusicList.Add(oggFilePath); // 将选择的ogg文件路径添加到列表
         Task.Run(() =>
         {
             using (var vorbis = new VorbisWaveReader(oggFilePath))
             {
                 using (var outputDevice = new WaveOutEvent())
                 {
                     outputDevice.Init(vorbis);
                     outputDevice.Play();

                     // 等待播放结束,而不是使用Thread.Sleep进行轮询  
                     while (outputDevice.PlaybackState == PlaybackState.Playing)
                     {
                         Thread.Sleep(100); // 减少轮询频率以降低CPU使用率  
                     }
                 }
             }
         });
     }
 }

这个方法是当用户点击按钮5时触发的事件处理方法。它的功能是打开一个文件选择对话框,让用户选择一个 .ogg 格式的音频文件,并播放该音频文件。

具体的实现步骤如下:

  1. 创建一个 OpenFileDialog 对象 openFiledialog,用于打开文件选择对话框。

  2. 设置文件选择对话框的过滤器,只显示 .ogg 格式的音频文件。

  3. 声明一个字符串变量 oggFilePath,用于存储选中的 .ogg 文件的路径。

  4. 使用 ShowDialog() 方法显示文件选择对话框,并等待用户选择文件。如果用户点击了对话框中的 "确定" 按钮,则 ShowDialog() 方法返回 DialogResult.OK,执行以下操作;否则,方法直接返回,不执行后续操作。

  5. 获取用户选择的 .ogg 文件的完整路径,并将其赋值给 oggFilePath 变量。

  6. 将选中的 .ogg 文件路径添加到列表框 listBox1 中,以便用户可以在列表框中看到选中的音频文件。

  7. 将选中的 .ogg 文件路径添加到 localmusicList 列表中,以便在后续的播放列表中使用。

  8. 使用 Task.Run() 创建一个异步任务,用于在后台播放选中的 .ogg 音频文件。在异步任务中,首先使用 VorbisWaveReader 类读取选中的 .ogg 文件,然后使用 WaveOutEvent 类初始化音频输出设备,并开始播放音频文件。

  9. 使用 while 循环等待音频播放结束,而不是使用 Thread.Sleep 进行轮询。在循环中,不断检查音频输出设备的播放状态,直到播放状态变为非播放状态时退出循环。

总的来说,这个方法实现了打开文件选择对话框,选择并播放 .ogg 格式的音频文件,并将选中的文件路径添加到列表框和播放列表中的功能


完整代码

using NAudio;
using NAudio.Wave;
using NAudio.Vorbis;
using NVorbis.Contracts;


namespace 音乐播放
{
    public partial class Form1 : Form
    {

        string[] files;

        List<string> localmusicList = new List<string> { };
        public Form1()
        {
            InitializeComponent();
        }
        private void musicplay(string filename)
        {
            axWindowsMediaPlayer1.URL = filename;
            string extention = Path.GetExtension(filename);

            if (extention == ".ogg")
            {
                Console.WriteLine("这是ogg文件");
                listBox1.Items.Add(filename); // 将选中的ogg文件路径添加到列表框
                localmusicList.Add(filename);
            }
            else
            {
                axWindowsMediaPlayer1.Ctlcontrols.play();
            }

        }
        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav";
            openFileDialog1.Multiselect = true;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                localmusicList.Clear();
                listBox1.Items.Clear();//清理控件

                if (files != null)
                {
                    Array.Clear(files, 0, files.Length);
                }//清理文件

                files = openFileDialog1.FileNames;
                string[] arry = files;
                foreach (string x in arry)
                {
                    listBox1.Items.Add(x);
                    localmusicList.Add(x);
                }
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (localmusicList.Count > 0)
            {
                int selectedIndex = listBox1.SelectedIndex;
                if (selectedIndex >= 0)
                {
                    string selectedFile = localmusicList[selectedIndex];
                    if (!selectedFile.EndsWith(".ogg"))
                    {
                        axWindowsMediaPlayer1.URL = selectedFile;
                        musicplay(axWindowsMediaPlayer1.URL);
                        label1.Text = Path.GetFileNameWithoutExtension(selectedFile);
                    }
                }
            }
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
        }

        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 button5_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFiledialog = new OpenFileDialog();
            openFiledialog.Filter = "打开音频|*.ogg";
            string oggFilePath = "";

            if (openFiledialog.ShowDialog() == DialogResult.OK)
            {
                oggFilePath = openFiledialog.FileName;
                listBox1.Items.Add(oggFilePath); // 将选择的ogg文件路径添加到列表框
                localmusicList.Add(oggFilePath); // 将选择的ogg文件路径添加到列表
                Task.Run(() =>
                {
                    using (var vorbis = new VorbisWaveReader(oggFilePath))
                    {
                        using (var outputDevice = new WaveOutEvent())
                        {
                            outputDevice.Init(vorbis);
                            outputDevice.Play();

                            // 等待播放结束,而不是使用Thread.Sleep进行轮询  
                            while (outputDevice.PlaybackState == PlaybackState.Playing)
                            {
                                Thread.Sleep(100); // 减少轮询频率以降低CPU使用率  
                            }
                        }
                    }
                });
            }
        }


    }
}

四,代码分析

这段代码实现了一个简单的音乐播放器应用程序。其中的难点在于以下几个方面:

  1. 多线程处理音频播放: 在按钮5的点击事件处理方法中,使用了 Task.Run() 方法创建了一个异步任务,用于播放 .ogg 格式的音频文件。这涉及到多线程编程,需要确保在异步任务中正确地初始化音频播放设备,并且需要处理音频播放的状态。

  2. 文件格式处理:musicplay 方法中,针对不同的音频文件格式(如 .ogg)做了不同的处理。这需要对不同的音频文件格式有一定的了解,以便正确地调用相应的播放方法或处理方法。

  3. 用户界面交互: 对话框的使用、列表框的更新、滑动条的操作等涉及用户界面的交互操作,需要确保界面的响应性和用户体验。

  4. 异常处理: 对异常情况的处理,如文件打开失败、音频播放失败等,需要进行合适的处理以保证程序的稳定性和可靠性。

  5. 异步编程理解: 对于 Task.Run() 方法创建的异步任务,以及异步播放音频时的状态处理,可能需要对异步编程有一定的理解。


  6. gitee的clone地址:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值