目录
一、需求分析
1、音乐播放器要支持在线播放功能,满足用户实时听音乐的需求
2、音乐播放器要支持音乐下载功能,满足用户保存音乐的需求
二、技术实现
1、声明变量
Form1
类中声明了几个字段来存储音乐文件列表、当前播放的音频设备以及文件路径数组。
public partial class Form1 : Form
{
string[] files;
List<string> localmusiclist = new List<string> { };
//......
}
2、添加组件
2.1、button
该组件用来选择音频、打开音频、下载歌曲、播放歌曲。
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);//把array里面的所有元素设置为默认,并清空
}
files = openFileDialog1.FileNames;//这个选择多个文件,filename选择一个文件
string[] array = files;
foreach (string x in array)
{
listBox1.Items.Add(x);
localmusiclist.Add(x);//选择多个音乐文件,能以行显示
}
}
}
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);
}
}
}
}
private async void button5_Click(object sender, EventArgs e)
{
await DownloadAudioAsync(audioUrl);
}
2.2、listbox
该组件用来显示歌曲名称,即展示歌曲列表。
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (localmusiclist.Count > 0)
{
axWindowsMediaPlayer1.URL = localmusiclist[listBox1.SelectedIndex];
//axWindowsMediaPlayer1.Ctlcontrols.play();
musicplay(axWindowsMediaPlayer1.URL);
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[listBox1.SelectedIndex]);
}
}
2.3、musicplay
该组件可以在线播放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("无法识别的文件格式");
}
}
2.4、trackbar
该组件可以滑动滑块来调节歌曲音量。
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
}
2.5、GetFileName
该组件可以获取音乐文件名称。
private string GetFileName(HttpResponseMessage response)
{
// 从响应头或 URL 中获取文件名
string fileName = null;
if (!string.IsNullOrEmpty(response.Content.Headers.ContentDisposition?.FileName))
{
fileName = response.Content.Headers.ContentDisposition.FileName;
}
else
{
Uri.TryCreate(response.RequestMessage.RequestUri.ToString(), UriKind.Absolute, out Uri uri);
fileName = Path.GetFileName(uri.LocalPath);
}
return fileName;
}
2.6、axWindowsMediaPlayer
该组件使用多媒体player来实现播放音乐的效果。
private void axWindowsMediaPlayer1_Enter(object sender, EventArgs e)
{
}
3、连接网站
定义了一个常量字符串audioUrl,是下载音频文件的网址,表示一个在线音频网站。
private const string audioUrl = "http://tool.liumingye.cn/music/?page=homePage";
//在线音频文件
4、下载文件
异步方法DownloadAudioAsync用于异步下载在线音频文件。它接收一个网址参数,然后使用HttpClient发起GET请求获取响应。如果响应成功,它将从响应内容中读取音频数据,并将其保存到本地文件中。如果在下载过程中发生异常,将显示错误消息框。
private async Task DownloadAudioAsync(string url)
{
using (var httpClient = new HttpClient())
{
try
{
// 发起 GET 请求并获取响应
using (var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode(); // 确保响应成功
using (var stream = await response.Content.ReadAsStreamAsync())
{
// 获取文件名,如果服务器没有提供文件名,可以自行指定
var fileName = GetFileName(response);
// 指定保存文件的路径,这里保存在当前用户的下载目录下
var filePath = Path.Combine(@"D:\Desktop", fileName);
// 使用 FileStream 写入文件
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
await stream.CopyToAsync(fileStream);
}
MessageBox.Show("下载完成:" + filePath, "下载成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
catch (Exception ex)
{
MessageBox.Show($"下载失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
上述代码中:
httpClient是一个HttpClient对象,用于发送HTTP请求和接收HTTP响应。
response是一个HttpResponseMessage对象,表示HTTP响应。
stream是一个Stream对象,表示HTTP响应的内容流。
fileName是一个字符串变量,表示要保存的文件名。
filePath是一个字符串变量,表示要保存的文件路径。
fileStream是一个FileStream对象,用于将HTTP响应的内容流写入到本地文件中。
三、代码分析:
1、音频文件格式识别
对于没有扩展名或无法识别的文件格式,要根据文件扩展名判断音频文件格式,否则会出现问题导致无法成功获取音频。
2、音频播放控制
使用axWindowsMediaPlayer1控件播放音频,需要掌握其API使用方法,如URL属性设置音频文件路径,Ctlcontrols.play()方法播放音频等。
3、列表框与音频文件关联
通过listBox1显示已选择的音频文件列表,需要实现列表框中选中项与音频文件的关联,以便在播放时正确选择对应的音频文件。
4、异步下载
使用HttpClient异步下载在线音频文件,需要理解异步编程的概念,如async和await关键字的使用,以及Task类的使用。
5、异常处理
在下载过程中可能会遇到异常,如网络错误、文件写入错误等,需要对异常进行处理,避免程序崩溃。