0.前言
- 书接上文,我们已经实现了一个能够播放本地音乐的音乐播放器,能够播放众多音乐格式,包括
.ogg
,接下来,我们将为我们的音乐播放器添加一个令人激动的新功能——联网音乐下载和播放!这个功能将使我们能够通过网络获取音乐,并将其添加到我们的播放列表中。 - 为了实现这个功能,我们选择使用苹果音乐开放的API。尽管这个API只支持音乐的30秒预览,但它非常适合初学者上手。使用这个API不需要认证或密钥等额外操作,让我们能够更快地理解和实现联网音乐下载功能。
- 本项目旨在练习如何实现联网音乐下载,理解基础方法后,想要拓展很快就能上手。
1.关于本地音乐播放
详情可查看本人上篇博客~
在此只放框架:
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 函数实现
首先定义一个类的成员变量,用于网络连接
private readonly HttpClient httpClient = new HttpClient();
2.2.1 控件2:搜索歌曲
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:下载歌曲
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的使用。