基于C#實(shí)現(xiàn)簡(jiǎn)單的音樂(lè)播放器
一、功能需求
- 播放
MP3文件:可播放MP3文件 - 播放
OGG文件:可播放OGG文件 - 用戶界面:一個(gè)簡(jiǎn)單的窗口,包含播放和暫停按鈕及文件選擇功能
- 異常處理:程序能處理可能處理可能出現(xiàn)的異常,如文件不存在、文件讀取錯(cuò)誤等
- 兼容性:確保代碼能在多個(gè)c#版本上運(yùn)行
二、設(shè)計(jì)思路分析
架構(gòu)選擇
考慮到需求中的界面友好和跨版本兼容性,我們可以選擇選擇
Windows Forms作為開(kāi)發(fā)平臺(tái),Windows Forms提供了一個(gè)簡(jiǎn)單而強(qiáng)大的方法來(lái)創(chuàng)建桌面應(yīng)用程序,并且與C#高度兼容,在開(kāi)發(fā)過(guò)程,我們選擇.NETFramework 4.8.0進(jìn)行程序設(shè)計(jì)。設(shè)計(jì)思路
界面設(shè)計(jì): 使用
Windows Forms工具箱中的控件如按鈕、標(biāo)簽和文件對(duì)話框構(gòu)建用戶界面。功能編碼: 使用
OpenFileDialog允許用戶選擇音頻文件。 根據(jù)文件擴(kuò)展名調(diào)用相應(yīng)的播放器對(duì)象進(jìn)行播放。 播放控制,包括開(kāi)始、暫停和停止。異常處理: 捕獲并響應(yīng)各種可能的運(yùn)行時(shí)錯(cuò)誤,如文件讀取失敗、文件格式不支持等,為用戶提供清晰的錯(cuò)誤信息。
難點(diǎn)分析
文件格式支持: 處理多種音頻格式(
MP3,OGG等)要求使用不同的庫(kù),這可能導(dǎo)致代碼復(fù)雜度增加。異常處理: 音頻文件的播放中可能遇到多種異常情況,如文件損壞、編解碼器不支持等。
三、窗體設(shè)計(jì)
按照需求設(shè)計(jì)窗體,并進(jìn)行一定的美化

- Label:展示當(dāng)前播放的歌曲
- Listbox:展示歌曲列表
- AxWindowsMediaPlayer:播放常規(guī)音樂(lè)
- Button:選擇歌曲文件、停止播放、下一曲
- TraceBarl:用于音量控制
四、代碼實(shí)現(xiàn)
頭文件引入
using AxWMPLib; using NAudio.Vorbis; using NAudio.Wave; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using static System.Windows.Forms.VisualStyles.VisualStyleElement;
類成員變量定義
List<string> localmusiclist = new List<string> { };
private WaveOutEvent waveOut = new WaveOutEvent();
private VorbisWaveReader currentVorbisReader;
在類中,
localmusiclist在音樂(lè)播放時(shí)用來(lái)追蹤和管理用戶加載的音樂(lè)文件集合,waveOut用于播放ogg文件,currentVorbisReader為當(dāng)前播放ogg文件的狀態(tài)
按鈕控件
歌曲文件選擇
private void button1_Click(object sender, EventArgs e)
{
string[] files = { };
openFileDialog1.Filter = "選擇音頻|*.mp3;*.flac;*.wav;*.ogg";
//同時(shí)打開(kāi)多個(gè)文件
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 file in array)
{
string extension = Path.GetExtension(file).ToLower();
if (extension == ".mp3" || extension == ".flac" || extension == ".wav" || extension == ".ogg")
{
listBox1.Items.Add(file);
localmusiclist.Add(file);
}
else
{
MessageBox.Show($"不支持的文件格式:{file}", "文件錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
這里我們通過(guò)
Filter方法來(lái)限制用戶選擇的音樂(lè)文件,防止后續(xù)播放功能報(bào)錯(cuò),并在選擇文件之后將選擇的音樂(lè)列表放置到ListBox中,同時(shí)邏輯判斷刪除已有的列表,并將歌曲播放列表放入localmusiclist中,再通過(guò)openFileDialog來(lái)判斷文件是否讀取成功。
暫停播放按鈕
private void button2_Click(object sender, EventArgs e)
{
if (waveOut.PlaybackState == PlaybackState.Playing)
{
waveOut.Pause(); // 暫停播放OGG
}
axWindowsMediaPlayer1.Ctlcontrols.stop(); // 停止其他格式的播放
}
用
if條件判斷,如果在播放ogg就停止播放ogg,如果播放的是普通文件就停止普通播放器就行
播放下一首按鈕
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;
}
}
判斷
Count是否大于0,以此來(lái)判斷是否能執(zhí)行下一首播放的邏輯,如果index大于localmusiclist的長(zhǎng)度,就將index置0,以此來(lái)循環(huán)播放列表,在播放時(shí)調(diào)用musicplay函數(shù)來(lái)播放音樂(lè),同時(shí)用Label來(lái)顯示當(dāng)前播放音樂(lè)的信息。
音樂(lè)選擇控件
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]);
}
}
當(dāng)listBox1中的音樂(lè)選擇發(fā)生改變時(shí),會(huì)觸發(fā)該事件函數(shù),若localmusiclist.Count > 0,就用musicplay播放選擇中的音樂(lè),并更新label1的值
音樂(lè)播放函數(shù)
private void musicplay(string filename)
{
string extension = Path.GetExtension(filename).ToLower();
try
{
if (extension == ".ogg")
{
if (currentVorbisReader != null)
{
// 確保先停止當(dāng)前播放再釋放資源
if (waveOut.PlaybackState != PlaybackState.Stopped)
{
waveOut.Stop();
}
currentVorbisReader.Dispose();
}
currentVorbisReader = new VorbisWaveReader(filename);
waveOut.Init(currentVorbisReader);
waveOut.Play();
}
else
{
if (currentVorbisReader != null)
{
// 確保先停止當(dāng)前播放再釋放資源
if (waveOut.PlaybackState != PlaybackState.Stopped)
{
waveOut.Stop();
}
currentVorbisReader.Dispose();
}
axWindowsMediaPlayer1.URL = filename;
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
catch (Exception ex)
{
MessageBox.Show($"無(wú)法播放文件:{filename}\n\n錯(cuò)誤信息:{ex.Message}", "播放錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
首先獲取文件后綴名,然后判斷后綴名是否為ogg,若為普通文件,則用c#自帶的內(nèi)置播放器即可完成播放,否則則需要下載安裝NAudio的第三方庫(kù)中的Vorbis和Wave類來(lái)實(shí)現(xiàn)播放音樂(lè),在播放時(shí)要檢查是否正在播放ogg音樂(lè),若是則停止播放當(dāng)前音樂(lè)再播放其他音樂(lè),同時(shí)這里使用try捕獲播放錯(cuò)誤來(lái)防止讀取文件產(chǎn)生的錯(cuò)誤導(dǎo)致程序卡死。
音量控制組件
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
}
這里將axWindowsMediaPlayer1的按鈕聯(lián)動(dòng)到traceBar1上,實(shí)現(xiàn)用traceBar1來(lái)控制音量。
五、完整代碼
```c#
using AxWMPLib;
using NAudio.Vorbis;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace _4._23上課code
{
public partial class Form1 : Form
{
List<string> localmusiclist = new List<string> { };
private WaveOutEvent waveOut = new WaveOutEvent();
private VorbisWaveReader currentVorbisReader;
public Form1()
{
InitializeComponent();
}
private void musicplay(string filename)
{
string extension = Path.GetExtension(filename).ToLower();
try
{
if (extension == ".ogg")
{
if (currentVorbisReader != null)
{
// 確保先停止當(dāng)前播放再釋放資源
if (waveOut.PlaybackState != PlaybackState.Stopped)
{
waveOut.Stop();
}
currentVorbisReader.Dispose();
}
currentVorbisReader = new VorbisWaveReader(filename);
waveOut.Init(currentVorbisReader);
waveOut.Play();
}
else
{
if (currentVorbisReader != null)
{
// 確保先停止當(dāng)前播放再釋放資源
if (waveOut.PlaybackState != PlaybackState.Stopped)
{
waveOut.Stop();
}
currentVorbisReader.Dispose();
}
axWindowsMediaPlayer1.URL = filename;
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
catch (Exception ex)
{
MessageBox.Show($"無(wú)法播放文件:{filename}\n\n錯(cuò)誤信息:{ex.Message}", "播放錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void axWindowsMediaPlayer1_Enter(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string[] files = { };
openFileDialog1.Filter = "選擇音頻|*.mp3;*.flac;*.wav;*.ogg";
//同時(shí)打開(kāi)多個(gè)文件
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 file in array)
{
string extension = Path.GetExtension(file).ToLower();
if (extension == ".mp3" || extension == ".flac" || extension == ".wav" || extension == ".ogg")
{
listBox1.Items.Add(file);
localmusiclist.Add(file);
}
else
{
MessageBox.Show($"不支持的文件格式:{file}", "文件錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
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)
{
if (waveOut.PlaybackState == PlaybackState.Playing)
{
waveOut.Pause(); // 暫停播放OGG
}
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];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
listBox1.SelectedIndex = index;
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
```
六、總結(jié)
以上就是基于C#實(shí)現(xiàn)簡(jiǎn)單的音樂(lè)播放器的詳細(xì)內(nèi)容,更多關(guān)于C#音樂(lè)播放器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#實(shí)現(xiàn)萬(wàn)物皆可排序的隊(duì)列方法詳解
本文詳細(xì)講解了C#實(shí)現(xiàn)萬(wàn)物皆可排序隊(duì)列的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
C#的Socket實(shí)現(xiàn)UDP協(xié)議通信示例代碼
本篇文章主要介紹了C#的Socket實(shí)現(xiàn)UDP協(xié)議通信示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
Unity使用攝像機(jī)實(shí)現(xiàn)望遠(yuǎn)鏡效果
這篇文章主要為大家詳細(xì)介紹了Unity攝使用像機(jī)實(shí)現(xiàn)望遠(yuǎn)鏡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
c# winform異步不卡界面的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于c# winform異步不卡界面的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用c#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
解析C#網(wǎng)絡(luò)編程中的Http請(qǐng)求
這篇文章主要介紹了C#網(wǎng)絡(luò)編程中的Http請(qǐng)求,不過(guò)這次也使我對(duì)C#網(wǎng)絡(luò)編程了解的更多,算是一次學(xué)習(xí)經(jīng)歷吧,文章結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03
C#使用泛型隊(duì)列Queue實(shí)現(xiàn)生產(chǎn)消費(fèi)模式
這篇文章介紹了C#使用泛型隊(duì)列Queue實(shí)現(xiàn)生產(chǎn)消費(fèi)模式的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10

