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

news2025/1/13 2:32:02

音乐播放器

  • 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的使用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kubernetes 核心概念

1 kubernetes核心概念 1.1 Pod Pod是可以在Kubernetes中创建和管理的、最小的可部署的计算单元。 Pod就像豌豆荚一样&#xff0c;其中包含着一组&#xff08;一个或多个&#xff09;容器&#xff1b;这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod就像一台物理…

用c语言实现通讯录

目录 静态简易通讯录 代码&#xff1a; 功能模块展示&#xff1a; 设计思路&#xff1a; 动态简易通讯录&#xff08;本质顺序表&#xff09; 代码&#xff1a; 扩容模块展示&#xff1a; 设计思路&#xff1a; 文件版本通讯录 代码&#xff1a; 文件模块展示&#x…

运维篇-配置高级

黑马程序员Spring Boot2 文章目录 1、临时属性1.1 命令行中使用临属性1.2 开发环境设定临时属性 2、配置文件分类3、自定义配置文件 1、临时属性 1.1 命令行中使用临属性 使用jar命令启动Sprigboot工程师可以使用临时属性替换配置文件中的属性临时属性添加方式&#xff1a;ja…

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

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…

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

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

【Linux】—MySQL安装

文章目录 前言一、下载官方MySQL包二、下载完成后&#xff0c;通过xftp6上传到Linux服务器上三、解压MySQL安装包四、在安装目录下执行rpm安装&#xff0c;请按顺序依次执行。五、配置MySQL六、启动MySQL数据库七、退出&#xff0c;重新登录数据库 前言 本文主要介绍在Linux环境…

内网渗透什么意思,怎么做好安全防范?

在当前高度数字化的世界中&#xff0c;企业和组织使用内网&#xff08;即内部网络&#xff09;来处理各种敏感数据与关键业务活动。然而&#xff0c;内网同样面临各种网络安全威胁&#xff0c;内网渗透就是其中一种。了解内网渗透的具体含义&#xff0c;并采取相应的安全防范措…

新火种AI|实属罕见!四大AI顶流同台,有哪些关键信息值得关注?

作者&#xff1a;小岩 编辑&#xff1a;彩云 在有着“AI春晚”之称的2024年智源大会上&#xff0c;非常难得的一幕出现了&#xff1a;当下国内的四大AI顶流公司——月之暗面&#xff0c;百川智能&#xff0c;智谱AI&#xff0c;面壁智能齐聚一堂&#xff0c;十分罕见的同台了…

注塑件检测视觉检测中可能遇到的外观缺陷

机器视觉检测注塑件不良特征有哪些&#xff1f;按照检测需求一般分为两类&#xff1a;外观缺陷和尺寸缺陷。但由于注塑件的工艺特点及原材料特性&#xff0c;注塑件外观缺陷在生产过程中出现的概率于频率远远大于尺寸缺陷。 注塑件检测视觉检测中可能遇到的外观缺陷 1、色差&a…

【Linux】 yum学习

yum介绍 在Linux系统中&#xff0c;yum&#xff08;Yellowdog Updater, Modified&#xff09;是一个用于管理软件包的命令行工具&#xff0c;特别适用于基于RPM&#xff08;Red Hat Package Manager&#xff09;的系统&#xff0c;如CentOS、Fedora和Red Hat Enterprise Linux…

油猴hook+内存爆破

hook方式 说明&#xff1a;来回翻页发现只有请求体的token需要逆向&#xff0c;而这个请求体是在params里&#xff0c;拼接到url里&#xff0c;可以直接用油猴hook url里的关键字token。 正常步骤 hook代码 // UserScript // name hookparams // namespace htt…

【Pmac】PMAC QT联合开发中各种可能遇到的坑

目录 1. 错误 C2027 使用了未定义类型“PCOMMSERVERLib::DEVUPLOAD”2. 输入了正确的pmac的ip地址&#xff0c;没有显示可选的pmac设备3. Pmac DTC-28B无读数 使用QT编写PMAC上位机程序时&#xff0c;利用QT中的dump工具可以将pcommserver.exe转化为pcommserverlib.h和pcommser…

【面试实战】# 并发编程之线程池配置实战

1.先了解线程池的几个参数含义 corePoolSize (核心线程池大小): 作用: 指定了线程池维护的核心线程数量&#xff0c;即使这些线程处于空闲状态&#xff0c;它们也不会被回收。用途: 核心线程用于处理长期的任务&#xff0c;保持最低的线程数量&#xff0c;以减少线程的创建和…

科学技术创新杂志科学技术创新杂志社科学技术创新编辑部2024年第12期目录

科技创新 基于均质与细晶化的高性能限动芯棒生产工艺优化与实践 吕鹏昊;刘松; 1-4 大地电磁测深法在水文地质勘察中的应用研究 熊俊杰;毛卫东; 5-8 电石乙炔法制取聚氯乙烯生产工艺分析 龚志平; 9-12《科学技术创新》投稿&#xff1a;cnqikantg126.com 地面三维…

【LeetCode:394. 字符串解码 + 栈 | 递归】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

VUE3实现个人网站模板源码

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

头歌资源库(13)背包问题

一、 问题描述 二、算法思想 这是一个背包问题&#xff0c;可以使用动态规划算法来解决。具体思路如下&#xff1a; 定义一个二维数组dp&#xff0c;dp[i][j]表示前i个物品在背包容量为j时能获取的最大价值。初始化dp数组的第一行和第一列为0&#xff0c;表示当只有一个物品或…

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置 本文内容机器人介绍Bruce机器人Gazebo中仿真代码部署Bruce真机代码部署 本文内容 人形机器人Brcue相关介绍docker中安装Gazebo并使用Bruce机器人控制器更换环境配置 机器人介绍 公司&#xff1a;西木科技Westwood-R…

Microsoft AI Day:支持开放合作,普及技术应用,推进行业企业智慧化创新

微软在北京举办以“共创AI创新&#xff0c;智启无限可能”为主题的Microsoft AI Day活动&#xff0c;集中展示了在生成式智能技术加速发展普及的过程中&#xff0c;微软取得的最新技术突破与进展&#xff0c;并同步更新了在Microsoft Build 2024全球开发者大会上发布的一系列Az…

【MATLAB源码-第227期】基于matlab的北方苍鹰优化算法(NGO)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 鼠群优化算法&#xff08;Rat Swarm Optimization, RSO&#xff09; 简介 鼠群优化算法&#xff08;Rat Swarm Optimization, RSO&#xff09;是一种模仿鼠类群体觅食行为的优化算法。该算法属于群体智能算法&#xff0c;通…