c#音乐播放器续(联网下载)

音乐播放器

  • 0.前言
  • 1.关于本地音乐播放
  • 2.使用iTunes Search API进行联网下载歌曲
    • 2.1 控件
    • 2.2 函数实现
      • 2.2.1 控件2:搜索歌曲
      • 2.2.2 控件3:下载歌曲
    • 2.3 主界面
  • 3.拓展

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. 控件1:输入歌曲搜索关键词
  2. 控件2:根据歌曲搜索关键词进行搜索,并显示于listBox2
  3. 控件3:下载listBox2选择的歌曲到本地
  4. 控件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包含了众多的歌曲,并且可以在线免费播放
使用步骤:

  1. 注册并创建Spotify开发者账号
    访问 Spotify for Developers 并登录或注册一个Spotify账号。
  2. 创建Spotify应用程序
    • 登录后,点击“Create an App”按钮,填写应用的名称和描述,点击“Create”创建应用。
    • 创建应用后,你会获得 Client ID 和 Client Secret。这是你访问Spotify API的凭证。
  3. 获取访问令牌
    Spotify API需要OAuth认证来获取访问令牌。访问令牌有两种方式获取:
    • 客户端凭据流:适用于不需要用户数据的场景。
    • 授权码流:适用于需要访问用户数据的场景。
  4. 发送API请求

使用Spotify Web API相较于本项目可能需要进行一些前置设置的操作,但后续的操作与本项目相差不大。只要你掌握了基础知识,就能够轻松地适应这个API的使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/723886.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

系统架构——Spring Framework

目录 &#xff08;1&#xff09;基本介绍 &#xff08;2&#xff09;基本发展历史 &#xff08;3&#xff09;了解和学习 Spring 4.x 系列的系统架构 1、第一个模块&#xff1a;做核心容器&#xff08;Core Contaner&#xff09; 2、第二个模块&#xff1a;AOP与Aspects(这…

【千帆AppBuilder】你有一封邮件待查收|未来的我,你好吗?欢迎体验AI应用《未来信使》

我在百度智能云千帆AppBuilder开发了一款AI原生应用&#xff0c;快来使用吧&#xff01;「未来信使」&#xff1a;https://appbuilder.baidu.com/s/Q1VPg 目录 背景人工智能未来的信 未来信使功能介绍Prompt组件 千帆社区主要功能AppBuilderModelBuilder详细信息 推荐文章 未来…

SCI绘图【1】-不同颜色表示密度和差异--密度图

参考资料&#xff1a;密度图&#xff08;Density Plot&#xff09; - 数据可视化图表 - 数字孪生百科 密度图是快速观察变量数值分布的有效方法之一。通常情况下&#xff0c;会根据两个变量将平面绘图区域分为非常多的子区域&#xff0c;之后以不同颜色表示落在该区域上样本的…

VBA技术资料MF161:按需要显示特定工作表

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

ELISA Flex: Monkey IFN-γ (HRP)

ELISA Flex: Monkey IFN-γ (HRP)该ELISA试剂盒能够检测溶液样本比如细胞培养上清或者血清/血浆中猴子γ干扰素&#xff08;IFN-γ&#xff09;的含量。 产品组分&#xff1a; 捕获抗体&#xff1a;克隆号MT126L&#xff08;0.5mg/ml&#xff09; 检测抗体&#xff1a;克隆号7…

如何开发海外仓系统?开发和购买海外仓系统哪个性价比更高

每个海外仓都各自不同&#xff0c;具备的优势&#xff0c;面临的困境也完全不同。所以在对海外仓系统的讨论时&#xff0c;是自己开发还是购买&#xff0c;都要放到具体的海外仓环境上才能得出合理结论。 1、实现海外仓精细化管理&#xff0c;你有哪些选择&#xff1f; 选择成…

大小鼠足底机械刺痛仪——可移动手持随时刺随时记录

简单介绍&#xff1a; 大小鼠足底机械刺痛仪主要用来评估机械痛&#xff08;阈值&#xff09;&#xff0c; 可用来检测所有的感官阈痛测试。配置了探针。能准确检测并能记录痛阈的仪器。操作方便&#xff0c;设计紧凑。 实验简便&#xff1a;使用时&#xff0c;把探针接触实验…

细致解析跨境电商多平台搭建利器-179海关接口源码应用方法

介绍 跨境电商已成为当前电商行业的热门发展方向之一。为满足跨境电商的需求&#xff0c;各大平台纷纷推出了多平台搭建利器。其中&#xff0c;179海关接口源码是一款非常实用的工具&#xff0c;本文将对其应用方法进行细致解析。 了解179海关接口源码 179海关接口源码可以帮…

机器学习课程复习——ANN

Q&#xff1a;ANN&#xff1f; 基本架构 由输入层、隐藏层、输出层等构建前馈/反馈传播 工作原理 先加权求和&#xff1a;每个神经元的输出是输入加权和的激活再送入激活函数&#xff1a;激活函数的存在使得其能够拟合各类非线性任务 联想&#xff1a;像adaboosting的加权求…

数据结构——排序(期末总结)

1. 插入排序 1.1 直接插入排序 思想 假设第一个元素是已经排好序的元素&#xff0c;从第二个元素开始依次插入操作&#xff0c;大的放后面&#xff0c;小的放前面。 代码 void insert(int a[], int n) {int i, j, key;for (i 2; i < n; i){key a[i];j i - 1;while (j…

WPF Prism框架搭建

WPF Prism框架搭建 1.引入Prism框架 在Nuget包管理器中搜索Prism&#xff0c;并添加到项目中 2.在项目中使用prism框架 2.1 修改app.xaml 删除项目中自带的StartupUri 修改Application节点为prism:PrismApplication 引入prism命名空间 <prism:PrismApplication x:C…

VUE3实现个人网站模板源码

文章目录 1.设计来源1.1 网站首页页面1.2 个人工具页面1.3 个人日志页面1.4 个人相册页面1.5 给我留言页面 2.效果和源码2.1 动态效果2.2 目录结构 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1…

如何删除电脑自带的游戏

要删除电脑自带的游戏&#xff0c;如扫雷和纸牌&#xff0c;你可以按照以下步骤操作&#xff0c;这些步骤基于Windows操作系统&#xff1a; 对于Windows 7及其更早版本 打开控制面板选择“程序”打开或关闭Windows功能找到并取消勾选游戏 对于Windows 10及更高版本 打开“设…

dockerfile文件的中的命令

# 基础镜像 FROM registry.cn-beijing.aliyuncs.com/205erp/myopenjdk:8.6 # 设置工作目录 WORKDIR /opt # 拷贝jar包到工作目录 COPY target/*.jar app.jar RUN ls # 设置暴漏的端口 EXPOSE 8080 # 启动jar包 CMD java ${JAVA_TOOL_OPTIONS} -jar app.jar

统计页面学习时长——停留时间

思路 页面进入记录开始时间&#xff0c;开启定时器记录时长页面离开掉接口 页面返回 和 浏览器返回 都会执行 beforeDestroy&#xff0c;但是无法掉接口所以使用组件内路由守卫beforeRouteLeave&#xff0c;监听返回调取接口刷新页面不会执行beforeDestroy和beforeRouteLeave&…

Deflate内部实现(LZ77无损压缩算法)超详细图解算法版~

无损压缩算法 第一阶段&#xff1a;重复消除 — LZ77无损压缩算法算法介绍举例压缩算法思路图解压缩过程 第二阶段&#xff1a;位减少huffman位减少 概览 Gzip Deflate 编码&#xff08;LZ77哈夫曼&#xff09; Brotli LZ77哈夫曼二阶上下文建模 Deflate 分两个阶段压缩数据…

构建高效的大数据量延迟任务调度平台

目录 引言系统需求分析系统架构设计 总体架构任务调度模块任务存储模块任务执行模块 任务调度算法 时间轮算法优先级队列分布式锁 数据存储方案 关系型数据库NoSQL数据库混合存储方案 容错和高可用性 主从复制数据备份与恢复故障转移 性能优化 水平扩展缓存机制异步处理 监控与…

宏观必读:数智化、气候能源、多极化趋势并存,如何获得转型性增长?

关键词速读&#xff1a; 双转型——创新主导的 “新质生产力”正加速推动中国产业的数字化和绿色低碳“双转型”。 双引擎——企业借助“技术创新”和“生态创新”两大引擎&#xff0c;乘势而上&#xff0c;赢得未来机遇。 生成式 AI 与大模型爆发式发展正在引发计算、开发、交…

C语言——扫雷小游戏

扫雷小游戏&#xff1a; 游戏最终效果&#xff1a; 1.先写一下游戏开始的简单界面。 用一个函数来写一下 void menu() {printf(" ---------------------------- \n");printf("| 1.play |\n");printf("| 0.exit …