使用c# 编写一个能够同时播放MP3和ogg文件的文件播放器

一、项目背景与准备

在开始编码之前,我们需要了解一些背景知识和准备工作。首先,为了播放MP3文件,我们将使用Windows Media Player(WMP)组件。而对于OGG格式,我们将借助NAudio库,它是一个开源的音频处理库,支持多种音频格式的解码和播放。

在开始之前,请确保你的开发环境中已经安装了必要的库和组件。对于NAudio,你可以通过NuGet包管理器来安装。

然后在工具箱里添加对应的工具

Label:显示当前播放。

Listbox:显示选择播放的音乐列表。

Trackbar:调节音量。

WindowsMediaPlayer:播放常规音乐格式(ogg格式无法用此播放)。

openFileDialog:用于选择音乐文件。

 button1:用于添加歌曲”

 button2:用于“停止播放”

 button3:用于“播放下一首”

 button4:用于“播放歌曲”

二、项目结构与初始化

我们的音乐播放器将基于Windows Forms来构建。在Visual Studio中创建一个新的Windows Forms应用程序项目,并添加必要的UI元素,如按钮、列表框和标签。

在项目的初始化部分,我们需要实例化Windows Media Player对象和NAudio的WaveOutEvent对象。这些对象将在后续的音乐播放过程中起到关键作用。

以下是我的代码和ui界面

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using NAudio.Vorbis;
using NAudio.Wave;
using WMPLib;


namespace 音乐播放器
{
    public partial class Form1 : Form
    {
        private WindowsMediaPlayer wmp; // Windows Media Player 实例  
        private WaveOutEvent waveOut; // NAudio 播放实例  
        private List<string> fileList;// 音乐文件列表  
        private int currentIndex = -1; // 当前播放文件的索引  

        public Form1()
        {
            InitializeComponent();
            InitializeMediaPlayer();
            fileList = new List<string>();
        }

        private void InitializeMediaPlayer()
        {
            wmp = new WindowsMediaPlayer();
            waveOut = new WaveOutEvent();
        }
        private void PlayCurrentSong()
        {
            if (currentIndex >= 0 && currentIndex < fileList.Count)
            {
                string filePath = fileList[currentIndex];
                string fileExt = Path.GetExtension(filePath).ToLower();
                if (fileExt == ".mp3")
                {
                    wmp.URL = filePath;
                    wmp.controls.play();
                }
                else if (fileExt == ".ogg")
                {
                    Task.Run(() => PlayOggFile(filePath));
                }
                label1.Text = "当前播放: " + Path.GetFileName(filePath);
            }
        }

        private void PlayOggFile(string filePath)
        {
            using (var vorbisReader = new VorbisWaveReader(filePath))
            {
                waveOut.Init(vorbisReader);
                waveOut.Play();

                while (waveOut.PlaybackState == PlaybackState.Playing)
                {
                    Thread.Sleep(1000); // 在后台线程中等待,不会阻塞UI线程    
                }
            }
        }


        // 添加歌曲按钮事件  
        private void button1_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "音频文件 (*.mp3, *.ogg)|*.mp3;*.ogg";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 假设我们每次只添加一个文件,而不是多选  
                    string filePath = openFileDialog.FileName;

                    // 将文件路径添加到歌曲列表  
                    AddSongToListBox(filePath);

                    // 更新当前播放索引(如果当前列表为空,则设置为0)  
                    if (fileList == null || fileList.Count == 0)
                    {
                        currentIndex = 0;
                    }
                }
            }

        }
        private void AddSongToListBox(string filePath)
        {
             fileList.Add(filePath); // 直接添加到List中  
             listBoxSongs.Items.Add(filePath); // 更新ListBox  
             listBoxSongs.SelectedIndex = listBoxSongs.Items.Count - 1; // 选中新添加的歌曲
        }

      







        private void button2_Click_1(object sender, EventArgs e)
        {
            if (wmp != null && wmp.playState == WMPPlayState.wmppsPlaying)
            {
                wmp.controls.pause(); // 暂停MP3文件的播放  
            }
            if (waveOut != null && waveOut.PlaybackState == PlaybackState.Playing)
            {
                waveOut.Stop(); // 对于OGG文件,我们只能停止播放  
                                // 如果您想要之后从停止的位置恢复播放,您需要自己记录停止的位置  
                                // 并在之后恢复播放时使用这个位置  
            }
            label1.Text = "当前播放: 已暂停/停止";
        }
        //播放歌曲事件
        private void button4_Click_1(object sender, EventArgs e)
        {
            PlayCurrentSong();
        }
        //播放下一首事件
        private void button3_Click_1(object sender, EventArgs e)
        {
            currentIndex++;
            if (currentIndex >= fileList.Count)
            {
                currentIndex = 0; // 如果已经是最后一首,则循环到第一首  
            }
            PlayCurrentSong();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
       
    
}

三、代码的重难点

  重难点一:媒体播放的兼容性

难点

  • 支持多种音频格式,如MP3和OGG,需要处理不同格式的解码和播放。

实现

  • 使用WindowsMediaPlayer来播放MP3文件,因为它内置了对MP3格式的支持。
  • 对于OGG格式,采用了NAudio库中的VorbisWaveReader来进行解码,并使用WaveOutEvent来进行播放。

  重难点二:多线程处理

难点

  • OGG文件的播放需要在一个单独的线程中进行,以避免阻塞UI线程。

实现

  • 使用Task.Run来启动一个新的后台任务,专门用于播放OGG文件。
  • 在播放OGG的后台任务中,使用一个循环来检查播放状态,并适当地暂停线程,以避免占用过多CPU资源。

  重难点三:UI与后台任务的交互

难点

  • 确保UI线程能够安全地更新,同时后台播放任务能够正常运行。

实现

  • 使用InvokeBeginInvoke来在UI线程上执行更新操作,如更新标签文本或列表框的选中项。
  • 避免在后台线程中直接操作UI元素,以防止线程冲突。

  重难点四:资源管理

难点

  • 确保音频文件播放完毕后,相关资源得到正确释放,避免内存泄漏。

实现

  • 使用using语句来确保VorbisWaveReader对象在使用完毕后被正确释放。
  • 对于WaveOutEvent对象,在播放完毕后调用StopDispose方法来释放资源。

四、用户交互与界面更新

除了播放功能外,我们的播放器还需要响应用户的操作,如添加歌曲、暂停/播放、切换到下一首歌曲等。这些操作都需要更新UI界面,并可能涉及到播放状态的改变。

例如,当用户点击“添加歌曲”按钮时,我们会弹出一个文件选择对话框,让用户选择要添加的歌曲。选中的歌曲路径将被添加到歌曲列表中,并显示在ListBox控件中。

五、总结与展望

通过这个项目,我们不仅学习了如何使用Windows Media Player和NAudio库来播放不同格式的音频文件,还实践了如何在Windows Forms应用程序中实现用户交互和界面更新。这个简单的音乐播放器可以作为一个起点,你可以根据自己的需求添加更多的功能,如歌词显示、均衡器调整等。

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值