【C#】实现基本音乐播放功能——音乐播放器/Windows程序设计作业2

本文详细描述了一个C#程序,实现对MP3和OGG音乐文件的播放,包括异常处理、用户界面设计、音乐列表展示、音量调节以及播放控制功能,同时介绍了如何使用NAudio库和axWindowsMediaPlayer控件。
摘要由CSDN通过智能技术生成

前言

实现.mp3、.ogg类型音乐文件的播放。


一、功能说明

请编写一个C#程序,实现音乐文件的播放功能,要求如下:

  • 程序应能够读取MP3文件和OGG文件,并播放其中的音频。
  • 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
  • 程序应具有良好的用户界面,方便用户进行操作。
  • 程序应具有良好的兼容性,能在不同版本的C#中正常运行。

二、窗体设计

音乐播放功能应该包含音乐文件获取、显示音乐列表、显示当前音乐、开始播放、停止播放、切换到下一首、调节音量等功能。

根据上述功能,按照个人喜好完成窗体设计。

如上图

button1改为“选择歌曲”,用于播放mp3音乐文件。

button2修改为“停止播放”,用于停止音乐文件。

button3修改为“下一曲”,用于切换到下一个音乐文件。

button4修改为“播放ogg”,用于播放ogg音乐文件。

listBox1用于显示音乐播放列表。

label1用于显示当前播放音乐名称。

openFileDialog1用于获取音乐文件。

为了使音乐播放器的界面更加接近现有的播放器,可以在解决方案资源管理器中,添加axWindowsMediaPlayer控件,实现音乐的播放、暂停、音量调节等操作。

添加axWindowsMediaPlayer控件步骤如下:

  • 在“工具”中,选择“选择工具箱项” 
  • 在“选择工具箱项”窗口中,选择“COM组件”
  • 在列表中找到“Windows Media Player”并打勾,点击确认
  • 工具箱中出现“Windows Media Player”控件,即可使用

axWindowsMediaPlayer控件中已经有音量调节功能,但调节界面太小,可以新引入一个trackBar控件来调节音量。

由于trackBar控件默认样式为水平方向上左右调节,音量调节一般为上下调节,因此可以将属性页面中调节外观的Orientation属性由"Horizontal'改为"Vertical",即可调整为上下调节。


三、代码实现

1、代码分步讲解

(1)添加依赖项NAudio包和NAudio.Vorbis包

NAudio库和NAudio.Vorbis库提供了丰富的音频处理功能,NAudio.Vorbis库中的VorbisWaveReader类能够帮助实现.ogg音频文件的播放。

添加NAudio包和NAudio.Vorbis包步骤如下:

  • 在“解决方案资源管理器”中,右键点击项目名称,选择“管理NuGet程序包”
  • 在“NuGet包管理器”中搜索“NAudio”
  • 点击“NAudio”后显示详细信息,点击“安装”
  • 在“预览更改”中点击应用,等待下载即可
  • “NAudio.Vorbis”下载方法相同

下载完成后即可在程序中使用:

using NAudio;
using NAudio.Wave;
using NAudio.Vorbis;

(2)定义音频名称和音频列表

首先定义一个字符串,用于储存音频名称。

要想音乐播放器能够实现选取多个音乐文件,需要一个列表localmusiclist,来储存选择的多个文件。

定义一个字符串列表,用于存储多个音频文件。

代码如下:

string[] files;

List<string> localmusiclist = new List<string> { };

(3).mp3音乐播放方法

播放音乐首先要接收需要播放的音乐文件,因此需要出入参数filename。

音乐播放需要用到Windows Media Player控件,则要将这个控件的URL属性设置为这个传入的filename参数。(URL属性用于指定要播放的音频文件的本地路径或网络位置)

URL属性设置完成后,Windows Media Player控件已经准备播放传入的音乐文件。

    axWindowsMediaPlayer1.URL = filename;

接下来则需要判断传入文件的类型,是否是正确的音频文件,判断是MP3音乐文件还是OGG音乐文件。  

判断文件类型需要将文件的扩展名单独提取出来,通过判断扩展名格式,来区分文件类型。

    string extension = Path.GetExtension(filename);

如果是.ogg文件,那么需要别的音乐播放方法来处理这个文件;

如果是,mp3文件,那么开始播放这个音乐文件,调用Windows Media Player控件的Ctlcontrols来播放这个音乐文件:axWindowsMediaPlayer1.Ctlcontrols.play(); 

否则无法播放。

这里使用WriteLine,在标准的Windows Forms应用程序中不会显示任何内容,能够拒绝播放。

    if (extension == ".ogg") 
    { 
        Console.WriteLine("这是.ogg文件"); 
    }
    else if (extension == ".mp3") 
    {
        axWindowsMediaPlayer1.Ctlcontrols.play(); 
    }
    else
    {
        Console.WriteLine("无法识别的文件格式");
    }

 至此,.mp3音乐文件播放方法已经完成,以下是完整代码:

private void musicplay(string filename)
{
    axWindowsMediaPlayer1.URL = filename;
    string extension = Path.GetExtension(filename);

    if (extension == ".ogg") 
    { 
        Console.WriteLine("这是.ogg文件"); 
    }
    else if (extension == ".mp3") 
    {
        axWindowsMediaPlayer1.Ctlcontrols.play(); 
    }
    else
    {
        Console.WriteLine("无法识别的文件格式");
    }
}

(4)button1:选择MP3音乐文件 

在窗口设计中双击button1,实现选择音乐功能。

这个控件用来选择.mp3音乐文件,因此首先要过滤其余文件,只能选择.mp3文件。

用openFileDialog1.Filter设置openFileDialog1的过滤器,只显示.mp3文件,并且在对话框中显示“选择音频”,代码如下:

openFileDialog1.Filter = "选择音频|*.mp3";

 选择音乐文件时的对话框如下:

 此时会完全过滤除了.mp3文件以外的所有类型文件(文件夹不会被过滤掉),并且会显示“选择音频”的文字。

如果需要播放的不仅是.mp3类型的音乐文件,还能播放.flac和.wav等类型的音乐文件,还能接着往后添加各种类型的过滤条件。修改代码如下:

openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav";

修改之后即可显示.mp3  .flac  .wav这三个类型的音乐文件 

在选择文件的时候,我们需要选择多个文件,因此需要代码如下:

openFileDialog1.Multiselect = true;

选择音频文件之后,如果用户点击“确认”按钮,则继续进行下一步,获取音频列表。

想要获取用户选择的音频文件,首先就要清除原来的旧列表。

listBox1中的所有项目和localmusiclist中的所有字符串都需要清除,代码如下:

 listBox1.Items.Clear();
 localmusiclist.Clear();

不仅需要清除listBox1和localmusiclist中的项目,还需要检查files中是否为空,不为空则要完全清除,否则不能将音频文件传输给files变量。

if (files != null)
{
    Array.Clear(files, 0, files.Length);//把array里面的所有元素设置为默认,并清空
}

将files清空之后,我们可以将选取的多个音频文件传给files变量,为了避免foreach循环会直接修改files,创建一个新的数组array,用于存放多个音频文件,代码如下:

files = openFileDialog1.FileNames;
string[] array = files;

再用foreach来遍历数组中的所有元素,并分别存入listBox1的列表和localmusiclist列表中,代码如下:

foreach (string x in array)
{
    listBox1.Items.Add(x);
    localmusiclist.Add(x);//选择多个音乐文件,能以行显示
}

 button1的功能已经完成,完整代码如下:

private void button1_Click(object sender, EventArgs e)
{
    openFileDialog1.Filter = "选择音频|*.mp3";
    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 x in array)
        {
            listBox1.Items.Add(x);
            localmusiclist.Add(x);
        }
    }
}

 (5)listbox1:显示音频列表

如果选择的音频文件数量大于0,则根据当前listBox1中的索引来确定当前播放的音乐,然后将axWindowsMediaPlayer1控件的URL属性设置为当前播放的音乐文件,以便播放该音乐,代码如下:

 axWindowsMediaPlayer1.URL = localmusiclist[listBox1.SelectedIndex];

 设置好URL属性值之后,即可调用musicplay音频播放方法。

传递URL参数,实现音频播放,代码如下:

musicplay(axWindowsMediaPlayer1.URL);

开始播放音频之后,label1需要显示当前播放音频文件的名称。

此时可以根据当前正在播放的音频文件的文件路径,获取扩展名以外的音频文件名,赋值给label1的文本Text,则可以实现label1中显示这个除去扩展名以外的音频文件名,代码如下:

label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[listBox1.SelectedIndex]);

完整代码如下: 

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

label1和listBox1的显示效果如下:

(6)button2:音频停止播放

使用axWindowsMediaPlayer控件中的Ctlcontrols来停止播放。

 private void button2_Click(object sender, EventArgs e)
 {
     axWindowsMediaPlayer1.Ctlcontrols.stop();
 }

(7)button3:音频切换到下一曲

如果音频文件的数量大于0,那么先将文件列表的索引加1,获取下一个音频文件。

int index = listBox1.SelectedIndex + 1;

但这存在一个问题,如果已经使最后一个音频文件,那么索引加1后,没有音频文件。

按照我们的习惯,播放到最后一个音频文件之后,下一曲应该回到第一曲。因此当索引加1后超出音频文件的数量,则意味着已经到了最后一个音频,需要将索引置为0。代码如下:

if (index >= localmusiclist.Count())
{
    index = 0;
}

完成以上操作之后,则可以将新的索引对应的音频文件赋值给axWindowsMediaPlayer控件的URL,调用musicplay方法,实现播放下一曲。代码如下:

axWindowsMediaPlayer1.URL = localmusiclist[index];
musicplay(axWindowsMediaPlayer1.URL);

修改完当前播放的音频之后,还需要修改label1中显示的文本,并将listBox1的选取对象修改为当前播放的音乐。代码如下:

label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
listBox1.SelectedIndex = index;

button3的功能已经完成,完整代码如下: 

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

(8)trackBar1:实现音量调节

trackBar1控件设置为音量调节,代码如下:

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

由于我们习惯将音量大小范围设置为0~100,因此可以调整trackBar1控件的属性,使最大值为100,最小值为0,这样更加接近我们的使用习惯。

(9)button4:播放.ogg音频文件

和播放.mp3音频文件的步骤相同,首先获取音频文件地址。

创建一个新的OpenFileDialog实例,用openFileDialog.Filter过滤其余类型文件,在对话框中选取.ogg文件,用户点击“确认”之后将文件地址赋值给对应的变量oggFilePath。

OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "打开音频|*.ogg";
string oggFilePath = "";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
    oggFilePath = openFileDialog.FileName;
}

选择好文件之后,就可以播放文件了。使用VorbisWaveReader类来读取oggFilePath指定的 .ogg 音频文件。

再创建一个WaveOutEvent实例,用于播放音频。

初始化outputDevice,使用reader作为音频源,然后使用play函数来播放选取的音频源。

即可实现.ogg音频文件的播放,代码如下:

using (var reader = new VorbisWaveReader(oggFilePath))
{
    using (var outputDevice = new WaveOutEvent())
    {
        outputDevice.Init(reader);
        outputDevice.Play();
    }
}

 为了确认音频当前时刻是否还在播放,可以在播放音频文件之后,使用while循环来检查。

如果还在播放,则线程休眠100毫秒后再次检查。

while (outputDevice.PlaybackState == PlaybackState.Playing)
{
    System.Threading.Thread.Sleep(100);
}

之前赋值的outputDevice 和 reader不需要再次进行处理。因为它们被包含在 using 语句块中,因此音频播放完毕后,outputDevice 和 reader 对象会被自动释放 。

完整代码如下:

private void button4_Click(object sender, EventArgs e)
{
    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "打开音频|*.ogg";
    string oggFilePath = "";
    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
        oggFilePath = openFileDialog.FileName;
    }
    using (var reader = new VorbisWaveReader(oggFilePath))
    {
        using (var outputDevice = new WaveOutEvent())
        {
            outputDevice.Init(reader);
            outputDevice.Play();

            while (outputDevice.PlaybackState == PlaybackState.Playing)
            {
                System.Threading.Thread.Sleep(100);
            }
        }
    }

}

 2、完整代码

using System.Diagnostics.Eventing.Reader;
using System.Threading;
using NAudio;
using NAudio.Wave;
using NAudio.Vorbis;
using System.Diagnostics;
namespace WinFormsApp4._23_1
{
    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 extension = Path.GetExtension(filename);

            if (extension == ".ogg") { Console.WriteLine("这是.ogg文件"); }
            else if (extension == ".mp3") 
            {
                axWindowsMediaPlayer1.Ctlcontrols.play();   
            }
            else
            {
                Console.WriteLine("无法识别的文件格式");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "选择音频|*.mp3";//;*.flac;*.wav
            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 x in array)
                {
                    listBox1.Items.Add(x);
                    localmusiclist.Add(x);
                }
            }
        }

        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)
        {
            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];
                //axWindowsMediaPlayer1.Ctlcontrols.play();
                musicplay(axWindowsMediaPlayer1.URL);
                label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);

                listBox1.SelectedIndex = index;
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "打开音频|*.ogg";
            string oggFilePath = "";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                oggFilePath = openFileDialog.FileName;
            }
            using (var reader = new VorbisWaveReader(oggFilePath))
            {
                using (var outputDevice = new WaveOutEvent())
                {
                    outputDevice.Init(reader);
                    outputDevice.Play();
                    while (outputDevice.PlaybackState == PlaybackState.Playing)
                    {
                        System.Threading.Thread.Sleep(100);
                    }
                }
            }

        }
    }
}

四、代码分析

1、基本思路

首先确定功能需求,本次实验需要播放.mp3和.ogg文件,并且需要实现基本音乐播放器的功能,包括选择音频文件、停止播放、调整音量、切换下一首等功能。

确定有哪些功能之后即可开始进行窗体设计,界面干净整洁便于用户使用。

设计完成后,将每个控件的功能进行实现即可。

2、难点分析

  • 下一曲循环播放:下一曲不能仅仅只是索引加1,还需要考虑到现实生活中,列表的循环播放。
  • ogg音频转换:.ogg音频文件播放需要借助NAudio库来播放,需要额外下载并安装第三方库。
  • 选取多个音频文件:需要借助list列表来存储多个音频文件,以此来实现多个音频文件的选取,并利用索引来确定当前播放的音乐文件。

下面是gitee的clone地址: 

https://gitee.com/chen-wennuo/basic-audio-player.git

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值