Bootstrap

c#WindowsForm开发,实现多种格式(MP3、OGG等)音乐文件播放——windows程序设计作业2

实现MP3文件和OGG文件音乐播放的WinForm程序

1.作业要求

1.1 要求1:

  1. 程序应能够读取MP3文件,并播放其中的音频。
  2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
  3. 程序应具有良好的用户界面,方便用户进行操作。
  4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
    提示:此功能可以使用WindowsMediaPlayer控件

1.2 要求2:

  1. 程序应能够播放ogg文件。
  2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
  3. 程序应具有良好的用户界面,方便用户进行操作。
  4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
    提示:此功能可以使用Nuget程序包中的Naudi.Vorbis控件

2.效果展示

20240510-173654

3.UI界面设计

  设计思路:通过listbox控件显示导入的歌曲列表,并可以通过点击选择歌曲进行播放;后通过添加三个button控件,分别实现导入歌曲、暂停与播放、下一首功能;再添加trackbar控件,以实现对系统音量的控制;在下方以WIndows Media Player的进度条实现对音乐播放进度的展示。

在这里插入图片描述

4.难点分析

4.1 文件格式:

对于MP3和OGG文件,需要调用不同的解码器和库进行不同功能的实现

4.2.异常处理:

对于运行过程中诸多异常问题,如文件读取失败、播放格式不支持等异常进行异常处理。

5核心功能实现

5.1 准备工作:

通过Nuget程序包安装NAudio和NAudio.Vorbis库以对ogg文件进行处理

在这里插入图片描述在这里插入图片描述

5.2 变量定义

private WaveOutEvent waveOut;//实例化WaveOutEvent类,后用于播放、暂停音乐和获取音乐播放状态
private VorbisWaveReader reader;//实例化VorbisWaveReader类,用于读取OGG格式文件
int num = 1;//定义一个计数器,用于技术播放列表中载入的音乐
private MMDeviceEnumerator deviceEnumerator;
private MMDevice defaultDevice;//定义两个类用于对设备音量调节
string[] files;//定义一个string数组,用于存储歌曲文件的地址
List<string> localmuscallist = new List<string> { };//定义listbox控件用用于显示播放列表的list

5.3 音频文件导入

  下代码允许用户从文件系统中选择一组音频文件,清除当前选择,然后将新选择的文件添加到listBox1控件中显示,同时管理一个音频文件路径的列表。如果在这个过程中有任何错误发生,程序会通知用户具体的错误信息。

 private void button2_Click(object sender, EventArgs e)
 {
	try
	{
    	openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav;*.ogg";//定义文件格式筛选器
    	openFileDialog1.Multiselect = true;//支持一次选入多个文件
    	if (openFileDialog1.ShowDialog() == DialogResult.OK)
    	{
        	localmuscallist.Clear();
        	listBox1.Items.Clear();
        	if (files != null)
        	{
            	Array.Clear(files, 0, files.Length);
        	}
        	//清空一系列变量
        	files = openFileDialog1.FileNames;
        	string[] array = files;
        	foreach (string x in array)
        	{
            	listBox1.Items.Add(num + "、" + Path.GetFileNameWithoutExtension(x));//通过GetFileNameWithoutExtension()函数获取没有扩展名的歌曲的文件名
            	localmuscallist.Add(x);
            	num++;
        	}
    	}
	}
	catch (Exception ex)
	{
    	MessageBox.Show($"Error playing file: {ex.Message}");//异常处理,抛出异常信息
	}
}

5.4 滑块音量调节

  以下代码允许用户通过滑动 trackBar1来调整系统的主音量,并将滑动条的初始位置设置为反映当前系统音量级别的位置。这样用户就能通过图形界面控件来直观地调整声音。

 private void trackBar1_Scroll(object sender, EventArgs e)
 {
     // 设置系统音量为滑动条的当前值
     if (defaultDevice != null)
     {
         defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar = trackBar1.Value / 100f;
     }
 }
deviceEnumerator = new MMDeviceEnumerator();
defaultDevice = deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);

trackBar1.ValueChanged += trackBar1_Scroll;

// 将滑动条当前值设定为系统音量的当前水平
trackBar1.Value = (int)(defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100);

5.5 音乐的播放与暂停

  以下代码分别实现对listbox列表的歌名进行点击播放和通过button1对正在播放的音乐进行暂停播放于继续播放功能

5.5.1 listbox列表点击播放

 首先定义ogg播放函数用于处理ogg格式音乐文件,再定义一个总的音乐播放函数,用于音乐播放时文件调用

private void oggplay(string oggFileName)//ogg播放函数
{

    if (waveOut.PlaybackState == PlaybackState.Playing || waveOut.PlaybackState == PlaybackState.Paused)
    {
        waveOut.Stop();  // 停止播放
        waveOut.Dispose();  // 释放所有资源
        waveOut = new WaveOutEvent();  // 创建一个新的WaveOut实例
    }

    try
    {
        // 初始化你的reader
        reader = new VorbisWaveReader(oggFileName);
        waveOut.Init(reader);
        waveOut.Play();
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Error re-initializing audio device: {ex.Message}");//抛出异常信息
    }
}

private void musicplay(string filename)//音乐播放函数
{
    axWindowsMediaPlayer1.URL = filename;
    string extension = Path.GetExtension(filename);
    if (extension == ".ogg") { oggplay(filename); }
    else
    {
        axWindowsMediaPlayer1.Ctlcontrols.play();//对于非ogg格式音频文件,直接调用Windows Media player控件进行播放
    }
}	
5.5.2 播放/暂停按钮

 因为是通过不同解码器进行播放ogg文件,所以当ogg歌曲播放时点击播放其他格式文件,ogg歌曲不会停止所以需要写一个函数主动停止播放ogg文件并释放资源,再进行下一个歌曲的播放

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if (localmuscallist.Count > 0)
    {
        string filename = localmuscallist[listBox1.SelectedIndex];
        if (waveOut.PlaybackState == PlaybackState.Playing)
        {
            waveOut.Stop();
            waveOut.Dispose();
 
        }
        musicplay(filename);
    }
}

 通过对不同播放类的播放状态的判断,确定播放音频文件类型,以调用不同播放类的音频播放、暂停功能。并在按钮为播放时点击后,播放音乐并将按钮文本置为暂停。;在按钮为暂停时点击后,暂停音乐并将按钮文本置为播放

private void button1_Click(object sender, EventArgs e)
{
    if (waveOut.PlaybackState == PlaybackState.Playing)
    {
        // 如果正在播放,则停止
        waveOut.Pause();
        button1.Text = "播放";
    }
    else if (waveOut.PlaybackState == PlaybackState.Paused)
    {
        waveOut.Play();
        button1.Text = "暂停";
    }
    else if (axWindowsMediaPlayer1.playState == WMPPlayState.wmppsPlaying)
    {
        axWindowsMediaPlayer1.Ctlcontrols.pause();
        button1.Text = "播放";
    }
    else
    {
        axWindowsMediaPlayer1.Ctlcontrols.play();
        button1.Text = "暂停";
    }
}

5.6 下一首

  以下代码使按钮具备了控制音乐播放列表播放下一首歌曲的功能,并能在列表播放到最后一首时自动回到列表开始进行循环播放。

private void button3_Click(object sender, EventArgs e)
{
    if (localmuscallist.Count > 0)
    {
        if (waveOut.PlaybackState == PlaybackState.Playing)
        {
            waveOut.Stop();
            waveOut.Dispose();
        }//检查播放状态,暂停并释放资源
        int index = listBox1.SelectedIndex + 1;
        if (index >= localmuscallist.Count()) { index = 0; }//当在播放最后列表一首音乐时点击下一首按钮,将转跳到列表首

        string filename = localmuscallist[index];
        musicplay(filename);
        listBox1.SelectedIndex = index;
    }
}

6.Gitee仓库克隆地址

https://gitee.com/qk1xcn/windows.git

7.总结

  此项目程序基于Windows Forms,主要功能是播放各种音频格式,特别注重对Ogg Vorbis(.ogg)格式的支持。应用程序利用了NAudio库的功能,可以解码并播放Ogg Vorbis音频文件,同时还保持了对其他常见音频格式(如MP3、WAV等)的兼容性。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;