音乐播放器
- 0.前言
- 1.关于本地音乐播放
- [2.使用iTunes Search API进行联网下载歌曲](#2.使用iTunes Search API进行联网下载歌曲)
-
- [2.1 控件](#2.1 控件)
- [2.2 函数实现](#2.2 函数实现)
-
- [2.2.1 控件2:搜索歌曲](#2.2.1 控件2:搜索歌曲)
- [2.2.2 控件3:下载歌曲](#2.2.2 控件3:下载歌曲)
- [2.3 主界面](#2.3 主界面)
- 3.拓展
0.前言
- 书接上文,我们已经实现了一个能够播放本地音乐的音乐播放器,能够播放众多音乐格式,包括
.ogg
,接下来,我们将为我们的音乐播放器添加一个令人激动的新功能------联网音乐下载和播放!这个功能将使我们能够通过网络获取音乐,并将其添加到我们的播放列表中。 - 为了实现这个功能,我们选择使用苹果音乐开放的API。尽管这个API只支持音乐的30秒预览,但它非常适合初学者上手。使用这个API不需要认证或密钥等额外操作,让我们能够更快地理解和实现联网音乐下载功能。
- 本项目旨在练习如何实现联网音乐下载,理解基础方法后,想要拓展很快就能上手。
1.关于本地音乐播放
详情可查看本人上篇博客~
在此只放框架:
csharp
public partial class Form1 : Form
{
VorbisWaveReader oggReader = null; //定义此对象,用于解析.ogg文件格式
WaveOutEvent outputDevice = null; //定义此对象,用于播放.ogg音频
List<string> localmusiclist = new List<string>(); //添加的所有音频文件
int index = -1; //当前播放的音频文件索引
public Form1()
{
InitializeComponent();
}
private void musicplay(string filename)
{
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
//获取filename的后缀名
string extension = Path.GetExtension(filename).ToLower();
//如果oggReader和outputDevice不为空,说明正在播放或播放过ogg文件,此时要再播放新选择的文件就要先释放旧的
if (oggReader != null && outputDevice != null)
{
oggReader.Dispose();
oggReader = null;
outputDevice.Dispose();
outputDevice = null;
}
axWindowsMediaPlayer1.Ctlcontrols.stop();
try
{
if (extension == ".ogg")
{
oggReader = new VorbisWaveReader(filename);
outputDevice = new WaveOutEvent();
outputDevice.Init(oggReader);
outputDevice.Play();
}
else
{
axWindowsMediaPlayer1.URL = filename;
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
catch (FileNotFoundException ex)
{
MessageBox.Show("File not found: " + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show("An error occurred: " + ex.Message);
}
}
//从本地添加歌曲
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav;*.ogg";
openFileDialog1.Multiselect = true;
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
string[] files = openFileDialog1.FileNames;
foreach(string x in files)
{
listBox1.Items.Add(x);
localmusiclist.Add(x);
}
}
}
//点击音乐歌单事件,切换选择的歌曲
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if(localmusiclist.Count > 0)
{
index = listBox1.SelectedIndex;
musicplay(localmusiclist[index]);
}
}
//音轨事件,用于响应调整声音
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
if(outputDevice != null)
outputDevice.Volume = trackBar1.Value;
}
//暂停
private void button2_Click(object sender, EventArgs e)
{
if(axWindowsMediaPlayer1 != null)
axWindowsMediaPlayer1.Ctlcontrols.stop();
if(outputDevice != null)
outputDevice.Stop();
}
//下一曲
private void button3_Click(object sender, EventArgs e)
{
if(localmusiclist.Count > 0)
{
index = (index+1)% localmusiclist.Count;
musicplay(localmusiclist[index]);
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
}
}
2.使用iTunes Search API进行联网下载歌曲
2.1 控件
- 控件1:输入歌曲搜索关键词
- 控件2:根据歌曲搜索关键词进行搜索,并显示于
listBox2
中 - 控件3:下载
listBox2
选择的歌曲到本地 - 控件4:用于显示歌曲搜索出来的信息,并可以选择某首歌进行下载
2.2 函数实现
首先定义一个类的成员变量,用于网络连接
csharp
private readonly HttpClient httpClient = new HttpClient();
2.2.1 控件2:搜索歌曲
csharp
private async Task<List<string>> SearchMusic(string keyword)
{
string apiUrl = $"https://itunes.apple.com/search?term={keyword}&media=music&limit=10";
try
{
HttpResponseMessage response = await httpClient.GetAsync(apiUrl);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(responseBody);
var results = json["results"];
List<string> musicLinks = new List<string>();
foreach (var result in results)
{
string trackName = result["trackName"].ToString();
string artistName = result["artistName"].ToString();
string previewUrl = result["previewUrl"].ToString();
musicLinks.Add($"{trackName} - {artistName} | {previewUrl}");
return musicLinks;
}
}
catch (HttpRequestException e)
{
MessageBox.Show(e.Message);
}
catch (Exception ex)
{
MessageBox.Show($"Unexpected error: {ex.Message}");
}
return null;
}
private async void button4_Click(object sender, EventArgs e)
{
string keyword = textBox1.Text.Trim();
if (string.IsNullOrEmpty(keyword))
{
MessageBox.Show("请输入搜索关键词");
return;
}
var results = await SearchMusic(keyword);
if (results == null)
return;
listBox2.Items.Clear();
foreach (var result in results)
{
listBox2.Items.Add(result);
}
}
在搜索歌曲的时候,一定要对结果判空,有可能什么也没搜到,这样会返回空
在操作控件时,对可能出错的步骤尽量使用异常处理的方法,这样即使出现错误也不会使主程序崩溃
2.2.2 控件3:下载歌曲
csharp
private async Task DownloadMusic(string musicUrl, string filePath)
{
HttpResponseMessage response = await httpClient.GetAsync(musicUrl);
response.EnsureSuccessStatusCode();
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
await response.Content.CopyToAsync(fileStream);
}
}
private async void button5_Click(object sender, EventArgs e)
{
if (listBox2.SelectedItem == null)
{
MessageBox.Show("请选择要下载的音乐");
return;
}
string selectedItem = listBox2.SelectedItem.ToString();
string[] parts = selectedItem.Split('|');
if (parts.Length < 2)
{
MessageBox.Show("无效的下载链接");
return;
}
string musicUrl = parts[1].Trim();
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.FileName = parts[0].Trim();
saveFileDialog.Filter = "MP3 文件|*.mp3";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = saveFileDialog.FileName;
await DownloadMusic(musicUrl, filePath);
MessageBox.Show("下载完成");
//将下载好的歌曲直接添加到播放列表
listBox1.Items.Add(filePath);
localmusiclist.Add(filePath);
}
}
2.3 主界面
3.拓展
本项目使用的iTunes Search API
肯定无法满足大家的需求
推荐一个比较好用的在线播放API:Spotify Web API
这个API包含了众多的歌曲,并且可以在线免费播放
使用步骤:
- 注册并创建Spotify开发者账号
访问 Spotify for Developers 并登录或注册一个Spotify账号。 - 创建Spotify应用程序
- 登录后,点击"Create an App"按钮,填写应用的名称和描述,点击"Create"创建应用。
- 创建应用后,你会获得 Client ID 和 Client Secret。这是你访问Spotify API的凭证。
- 获取访问令牌
Spotify API需要OAuth认证来获取访问令牌。访问令牌有两种方式获取:- 客户端凭据流:适用于不需要用户数据的场景。
- 授权码流:适用于需要访问用户数据的场景。
- 发送API请求
使用Spotify Web API相较于本项目可能需要进行一些前置设置的操作,但后续的操作与本项目相差不大。只要你掌握了基础知识,就能够轻松地适应这个API的使用。