一、引言
本文将介绍在Visual Studio 2022环境中用C#创建一个多格式支持的音乐播放器,并集成音乐文件的下载功能。这个播放器不仅能够播放常见的MP3、OGG格式的音乐文件。
二、基础框架搭建
1、在COM组件中安装Windows Media Player
2、在NuGet包中安装NAudio.Voribis,NAduio
三、设计用户界面
使用的控件有:
button(用于操作)
listBox(显示列表)
trackbar(调节音量)
label
textbox(输入下载地址)
四、实现音乐播放功能
1.音乐播放(定义musicplay函数)
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 { axWindowsMediaPlayer1.Ctlcontrols.play();}
}
2.button4 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;
}
}
private void button4_Click(object sender, EventArgs e)
{
string oggFilePath="";
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "播放音频|*.ogg";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath = openFileDialog.FileName;
}
using (var vorbisReader = new VorbisWaveReader(oggFilePath))
{
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(vorbisReader);
outputDevice.Play();
// 等待播放完成,或者你可以添加其他逻辑,如用户输入来停止播放等。
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
3.button1 选择歌曲
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[] array = files;
foreach (string x in array)
{
listBox1.Items.Add(x);
localmusiclist.Add(x);
}
}
}
4.listbox
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]);
}
}
5.trackbar 音量调节
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume=trackBar1.Value;
}
6.button2 停止播放
private void button2_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
7.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;
}
}
五、实现音乐文件下载功能
1.定义文件下载类
using System;
using System.Collections.Generic;
using System.Text;
namespace Gac
{
public class DownloadProgressListener : IDownloadProgressListener
{
private long presize=0;
DownMsg downMsg = null;
public DownloadProgressListener(DownMsg downmsg)
{
this.downMsg = downmsg;
//this.id = id;
//this.Length = Length;
}
public delegate void dlgSendMsg(DownMsg msg);
public dlgSendMsg doSendMsg = null;
public void OnDownloadSize(long size)
{
if (downMsg==null)
{
DownMsg downMsg = new DownMsg();
}
//下载速度
if (downMsg.Size == 0)
{
downMsg.Speed = size;
}
else
{
downMsg.Speed = (float)(size - downMsg.Size);
}
if (downMsg.Speed == 0)
{
downMsg.Surplus = -1;
downMsg.SurplusInfo = "未知";
}
else
{
downMsg.Surplus = ((downMsg.Length - downMsg.Size) / downMsg.Speed);
}
downMsg.Size = size; //下载总量
if (size == downMsg.Length)
{
//下载完成
downMsg.Tag = DownStatus.End;
downMsg.SpeedInfo = "0 K";
downMsg.SurplusInfo = "已完成";
}
else
{
//下载中
downMsg.Tag = DownStatus.DownLoad;
}
if (doSendMsg != null) doSendMsg(downMsg);//通知具体调用者下载进度
}
}
public enum DownStatus
{
Start,
GetLength,
DownLoad,
End,
Error
}
public class DownMsg
{
private int _Length = 0;
private string _LengthInfo = "";
private int _Id = 0;
private DownStatus _Tag = 0;
private long _Size = 0;
private string _SizeInfo = "";
private float _Speed = 0;
private float _Surplus = 0;
private string _SurplusInfo ="";
private string _ErrMessage = "";
private string _SpeedInfo = "";
private double _Progress = 0;
public int Length
{
get
{
return _Length;
}
set
{
_Length = value;
LengthInfo = GetFileSize(value);
}
}
public int Id
{
get
{
return _Id;
}
set
{
_Id = value;
}
}
/// </summary>
public DownStatus Tag
{
get
{
return _Tag;
}
set
{
_Tag = value;
}
}
public long Size
{
get
{
return _Size;
}
set
{
_Size = value;
SizeInfo = GetFileSize(value);
if (Length >= value)
{
Progress = Math.Round((double)value / Length * 100, 2);
}
else
{
Progress = -1;
}
}
}
public float Speed
{
get
{
return _Speed;
}
set
{
_Speed = value;
SpeedInfo = GetFileSize(value);
}
}
public string SpeedInfo
{
get
{
return _SpeedInfo;
}
set
{
_SpeedInfo = value;
}
}
public float Surplus
{
get
{
return _Surplus;
}
set
{
_Surplus = value;
if (value>0)
{
SurplusInfo = GetDateName((int)Math.Round(value, 0));
}
}
}
public string ErrMessage
{
get
{
return _ErrMessage;
}
set
{
_ErrMessage = value;
}
}
public string SizeInfo
{
get
{
return _SizeInfo;
}
set
{
_SizeInfo = value;
}
}
public string LengthInfo
{
get
{
return _LengthInfo;
}
set
{
_LengthInfo = value;
}
}
public double Progress
{
get
{
return _Progress;
}
set
{
_Progress = value;
}
}
public string SurplusInfo
{
get
{
return _SurplusInfo;
}
set
{
_SurplusInfo = value;
}
}
private string GetFileSize(float Len)
{
float temp = Len;
string[] sizes = { "B", "KB", "MB", "GB" };
int order = 0;
while (temp >= 1024 && order + 1 < sizes.Length)
{
order++;
temp = temp / 1024;
}
return String.Format("{0:0.##} {1}", temp, sizes[order]);
}
private string GetDateName(int Second)
{
float temp = Second;
string suf = "秒";
if (Second>60)
{
suf = "分钟";
temp = temp / 60;
if (Second > 60)
{
suf = "小时";
temp = temp / 60;
if (Second > 24)
{
suf = "天";
temp = temp / 24;
if (Second > 30)
{
suf = "月";
temp = temp / 30;
if (Second > 12)
{
suf = "年";
temp = temp / 12;
}
}
}
}
}
return String.Format("{0:0} {1}", temp, suf);
}
}
}
2.button5 下载
private void button5_Click(object sender, EventArgs e)
{
try
{
//从txetbox获取用户输入的文本链接
string downloadUrl = textBox1.Text;
//对下载链接进行URI编码
string path = Uri.EscapeUriString(downloadUrl);
//检查下载链接是否为空
if (string.IsNullOrEmpty(downloadUrl))
{
MessageBox.Show("请输入有效的下载链接。", "下载错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//从下载链接中自动获取文件名
string filename = Path.GetFileName(path);
//自定义文件保存的位置
string dir = @"D:\windows程序设计";
//向 ListView 中添加新的下载项,显示初始状态信息
ListViewItem item = listView1.Items.Add(new ListViewItem(new string[] { (listView1.Items.Count + 1).ToString(), filename, "0", "0", "0%", "0", "0", DateTime.Now.ToString(), "等待中", downloadUrl }));
//获取当前下载项在ListView中的索引
int id = item.Index;
//调用下载管理器的方法,添加下载任务
dlf.AddDown(path, dir, id, id.ToString());
//启动下载管理器开始下载任务
dlf.StartDown();
}
catch (Exception ex)
{
MessageBox.Show($"下载过程中发生错误: {ex.Message}", "下载错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
六、总结
本程序通过WinForm 实现了一个音乐播放器,用户可以通过简约的界面播放 MP3 、FLAC、WAV和 OGG 文件,且支持通过网络链接进行音乐文件的下载。