当前位置: 首页 > news >正文

C#实现简单音乐文件解析播放——Windows程序设计作业2

1. 作业内容

    编写一个C#程序,要求实现常见音乐文件的播放功能,具体要求如下:
    1). 播放MP3文件: 程序应能够读取MP3文件,并播放其中的音频。
    2). 播放OGG文件: 应能够播放ogg文件。
    3). 用户界面: 一个简单的窗口,包含播放和暂停按钮以及文件选择功能。
    4). 异常处理: 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
    5). 兼容性: 确保代码在多个C#版本上均可运行。

2. 设计思路分析与难点

2.1 架构选择

    考虑到需求中的界面友好和跨版本兼容性,我们可以选择选择Windows Forms作为开发平台,Windows Forms提供了一个简单而强大的方法来创建桌面应用程序,并且与C#高度兼容,在开发过程,我们选择.NETFramework 4.8.0进行程序设计。

2.2 设计思路

    1). 界面设计: 使用Windows Forms工具箱中的控件如按钮、标签和文件对话框构建用户界面。
    2). 功能编码: 使用OpenFileDialog允许用户选择音频文件。 根据文件扩展名调用相应的播放器对象进行播放。 播放控制,包括开始、暂停和停止。
    3). 异常处理: 捕获并响应各种可能的运行时错误,如文件读取失败、文件格式不支持等,为用户提供清晰的错误信息。

2.3 难点分析

    1). 文件格式支持: 处理多种音频格式(MP3,OGG等)要求使用不同的库,这可能导致代码复杂度增加。
    2). 异常处理: 音频文件的播放中可能遇到多种异常情况,如文件损坏、编解码器不支持等。

3. 窗体设计

    按照需求和功能分析,实现窗体如下:
窗体设计
    其中,各控件实现功能如下:
    Label:展示当前播放的歌曲。
    ListBox:展示选择的歌曲列表。
    AxWindowsMediaPlayer:用于播放常规格式音乐(ogg无法用此播放)。
    OpenFileDialog:用于选择音乐文件。
    Button:用于选择歌曲文件、停止播放、下一曲的功能实现。
    TrackBarl:用于音量控制。

4. 代码实现

4.0 类成员变量定义

List<string> localmusiclist = new List<string> { };
private WaveOutEvent waveOut = new WaveOutEvent();
private VorbisWaveReader currentVorbisReader;

    在类中,我们需要定义类成员变量,localmusiclist在音乐播放应用中用来追踪和管理用户加载的音乐文件集合,waveOut用于播放ogg文件,currentVorbisReader为当前使用的ogg文件实例。

4.1 文件选择功能

    函数定义:

private void button1_Click(object sender, EventArgs e)
{//功能实现见下方
}

    具体实现:

string[] files = { };openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav;*.ogg";
//同时打开多个文件
openFileDialog1.Multiselect = true;

    在这部分,我们采用buttonopenFileDialog控件来实现文件的选择,Filter用于筛选文件类型,使得用户只能选择音乐文件,不能选择其他文件导致后续功能无法实现报错,同时初始化一个files文件存放音乐文件的文件名。

if(openFileDialog1.ShowDialog() == DialogResult.OK)
{//清空原有列表listBox1.Items.Clear();localmusiclist.Clear();if (files !=  null){Array.Clear(files, 0, files.Length);}files = openFileDialog1.FileNames;string[] array = files;foreach(string file in array){listBox1.Items.Add(file);localmusiclist.Add(file);}
}

    这里我们对选择的文件进行处理,首先,将所有变量清空,防止有残留影响后续程序执行,之后,将文件名添加到ListBox中,显示出来用于选择音乐,同时,利用localmusiclist变量存储文件名,并且作为类成员变量进行传输,方便后续对音乐的操作。

openFileDialog1.ShowDialog() == DialogResult.OK

    其中,if条件判断openFileDialog是否接收到文件,不然不执行后续程序。

4.2 音乐选择功能

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{if(localmusiclist.Count > 0){axWindowsMediaPlayer1.URL = localmusiclist[listBox1.SelectedIndex];musicplay(axWindowsMediaPlayer1.URL);label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[listBox1.SelectedIndex]);}
}

    在ListBox控件中,存在一个事件监听SelectedIndexChanged,利用该事件,我们可以去获取用户切换列表,SelectedIndex是获取目前列表中选择的序号,通过该序号和之前的localmusiclist,我们可以获取到音乐信息并且进行传参调用函数,进行后续的音乐播放。
ListBox中的列表信息
    同时,将Label的内容设置为音乐文件的信息并展示。
Label信息展示

4.3 音乐选择功能

    函数定义:

private void musicplay(string filename)
{//功能实现见下方
}

    具体实现:

string extension = Path.GetExtension(filename).ToLower();

    首先,获取当前文件名的后缀信息,判断文件类型。

if (extension == ".ogg")
{if (currentVorbisReader != null){// 确保先停止当前播放再释放资源if (waveOut.PlaybackState != PlaybackState.Stopped){waveOut.Stop();}currentVorbisReader.Dispose();}currentVorbisReader = new VorbisWaveReader(filename);waveOut.Init(currentVorbisReader);waveOut.Play();
}

    针对不同的文件类型,采用不同的处理方式:若是ogg文件,调用NAudio第三方库总的VorbisWave类来实现播放音乐。
    在播放新的音乐时,先检测当前是否有正在进行播放或者是暂停播放的ogg音乐,先进行处理再播放当前歌曲,可以防止同时初始化两次WaveOut产生播放异常。

else
{axWindowsMediaPlayer1.URL = filename;axWindowsMediaPlayer1.Ctlcontrols.play();
}

    若是其他类型的文件,使用C#原生库中的WindowsMediaPlayer控件实现播放。

4.4 暂停播放

private void button2_Click(object sender, EventArgs e)
{if (waveOut.PlaybackState == PlaybackState.Playing){waveOut.Pause(); // 暂停播放OGG}axWindowsMediaPlayer1.Ctlcontrols.stop(); // 停止其他格式的播放
}

    音乐暂停功能也需要先区分类型,如果waveOut的播放状态为正在播放,调用函数暂停音乐,否则就是调用WindowsMediaPlayer的暂停函数。

4.5 播放下一首&&循环播放

    函数定义:

private void button3_Click(object sender, EventArgs e)
{//功能实现见下方
}

    具体实现:

if(localmusiclist.Count > 0)
{//记录下一首音乐的索引int index = (listBox1.SelectedIndex + 1);axWindowsMediaPlayer1.URL = localmusiclist[index];musicplay(axWindowsMediaPlayer1.URL);label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);listBox1.SelectedIndex = index;
}

    这里采用索引来得到下一首音乐URL,再进行播放,同时更改Label的信息显示与SelectedIndex的当前索引。

if (index >= localmusiclist.Count())
{index = 0;
}

    在索引大于当前音乐列表的时候,将Index重置为零,从而实现循环播放功能。

4.6 音量控制

private void trackBar1_Scroll(object sender, EventArgs e)
{axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
}

    直接将WindowsMediaPlayer的属性和TrackBar设置的值进行关联即可实现音乐播放事的音乐控制了。

5. 完整代码

    代码仓库:hmcy-zbx的windows课程设计作业

6. 总结&改进思路

    本次作业旨在通过导入第三方库辅助自己的程序设计与学习更复杂的控件使用和控件之间的联系,通过本次作业,我对于C#的控件使用掌握的更加深入了。
    尽管当前程序能实现较多的音乐文件格式播放,但是不能够实现最新的音乐文件解析,例如:ape文件与aac文件。
    并且,缺少高级音频功能的设置,例如增加音频效果处理(如均衡器、声音增强等)和支持音频流的直接下载和播放。

相关文章:

C#实现简单音乐文件解析播放——Windows程序设计作业2

1. 作业内容 编写一个C#程序&#xff0c;要求实现常见音乐文件的播放功能&#xff0c;具体要求如下&#xff1a;     1). 播放MP3文件&#xff1a; 程序应能够读取MP3文件&#xff0c;并播放其中的音频。     2). 播放OGG文件&#xff1a; 应能够播放ogg文件。     …...

Python数据爬取超简单入门

## 什么是网络爬虫&#xff1f; 网络爬虫是一种自动浏览器程序&#xff0c;能够自动地从互联网获取数据。爬虫的主要任务是访问网页&#xff0c;分析网页内容&#xff0c;然后提取所需的信息。爬虫广泛应用于数据收集、数据分析、网页内容监控等领域。 ## 爬虫的基本步骤 1.…...

Dreamweaver 2021 for Mac 激活版:网页设计工具

在追求卓越的网页设计道路上&#xff0c;Dreamweaver 2021 for Mac无疑是您的梦幻之选。这款专为Mac用户打造的网页设计工具&#xff0c;集强大的功能与出色的用户体验于一身。 Dreamweaver 2021支持多种网页标准和技术&#xff0c;让您能够轻松创建符合现代网页设计的作品。其…...

【Git】Git学习-15:分支简介和基本操作

学习视频链接&#xff1a;【GeekHour】一小时Git教程_哔哩哔哩_bilibili​编辑https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780 git bran…...

浏览器提示网站“不安全”原因及解决方法

是否经常会遇到访问的网站被浏览器提示访问不安全&#xff1f;那么&#xff0c;浏览器提示网站不安全通常有哪些原因又该如何处理这种不安全提醒&#xff0c;以下总结了几个原因及相应的处理办法&#xff1a; 一、网站管理者原因排查及处理办法&#xff1a; 1、网站没有部署S…...

Jmeter详细学习思路和教程

目录 1、JMeter环境准备 1.1、介绍 1.2、与LoadRunner比较 1.3、前提条件 1.4、安装配置 2、JMeter脚本 2.1、测试计划 2.2、线程组 2.3、Sampler 2.4、HTTP请求 2.5、查看结果树 2.6、HTTP Cookie管理器 2.7、HTTP信息头管理器 2.8、响应断言 2.9、参数化 3、JM…...

钉钉开放平台创建企业内部H5微应用或者小程序

前言&#xff1a; 在当今企业数字化转型的浪潮中&#xff0c;创建企业内部H5微应用或小程序已成为提升工作效率和促进内部沟通的重要举措。发话不多说本文将介绍如何利用钉钉平台快速创建这些应用&#xff0c;让企业内部的工作更加便捷高效。 步骤 1.在浏览器打开链接…...

Linux中每当执行‘mount’命令(或其他命令)时,自动激活执行脚本:输入密码,才可以执行mount

要实现这个功能&#xff0c;可以通过创建一个自定义的mount命令的包装器&#xff08;wrapper&#xff09;来完成。这个包装器脚本会首先提示用户输入密码&#xff0c;如果密码正确&#xff0c;则执行实际的mount命令。以下是创建这样一个包装器的步骤&#xff1a; 创建一个名为…...

【网络协议】----IPv6协议报文、地址分类

【网络协议】----IPv6协议简介 【网络协议】----IPv6协议简介IPv6特点IPv4 和 IPv6报文结构IPv6报文格式-拓展报头 IPv6地址分类IPv6地址表示IPv6单播地址可聚合全球单播地址链路本地地址唯一本地地址特殊地址补充 接口标识&#xff08;主机位&#xff09;生成方法通过EUI-64规…...

Llama改进之——SwiGLU激活函数

引言 今天介绍LLAMA模型引入的关于激活函数的改进——SwiGLU1&#xff0c;该激活函数取得了不错的效果&#xff0c;得到了广泛地应用。 SwiGLU是GLU的一种变体&#xff0c;其中包含了GLU和Swish激活函数。 GLU GLU(Gated Linear Units,门控线性单元)2引入了两个不同的线性层…...

在数据分析中所需要运用到的概率论知识

数据分析 前言一、总体二、样本三、统计抽样抽取的基本准则 四、随机抽样抽签法随机数法 五、分层抽样六、整群抽样七、系统抽样八、统计参数常用的分布函数参数 九、样本统计量十、样本均值和样本方差十一、描述样本集中位置的统计量样本均值样本中位数样本众数 十二、描述样本…...

韩顺平0基础学Java——第6天

p87-p109 运算符&#xff08;第四章&#xff09; 四种进制 二进制用0b或0B开头 十进制略 八进制用0开头 十六进制0x或0X开头&#xff0c;其中的A—F不区分大小写 10转2&#xff1a;将这个数不断除以2&#xff0c;直到商为0&#xff0c;然后把每步得到的余数倒过来&#…...

react18子组件设置接收默认值和值类型验证

父组件传值 import ChildCom from ./components/ChildCom export default function Person {return(<div><ChildCom name"alan-ben" age{18} score{[98, 97, 100]} /></div>) } 子组件接收并验证类型 import React from react import PropTypes…...

Java 高级面试问题及答案(二)

Java高级面试问题及答案 1. 在Java中&#xff0c;什么是强引用、软引用、弱引用和虚引用&#xff0c;它们有什么区别&#xff1f; 答案&#xff1a; 在Java中&#xff0c;引用类型决定了对象的生命周期&#xff0c;主要有以下四种&#xff1a; 强引用&#xff1a;最常见的引…...

数据统计:词频统计、词表生成、排序及计数、词云图生成

文章目录 &#x1f4da;输入及输出&#x1f4da;代码实现 &#x1f4da;输入及输出 输入&#xff1a;读取一个input.txt&#xff0c;其中包含单词及其对应的TED打卡号。 输出 output.txt&#xff1a;包含按频率降序排列的每个单词及其计数&#xff08;这里直接用于后续的词云…...

W801学习笔记二十四:NES模拟器游戏

之前已经实现了NES模拟器玩游戏。W801学习笔记九&#xff1a;HLK-W801制作学习机/NES游戏机(模拟器) 现在要在新版本掌机中移植过来。 1、把NES文件都拷贝到SD卡中。 这回不会受内存大小限制了。我这里拷贝了4个&#xff0c;还可以拷贝更多。 2、应用初始化中&#xff0c;加载…...

ECMAScript 6简介

ECMAScript 6简介 发布日期目标ECMAScript 和 JavaScript 的关系ES6 与 ECMAScript 2015 的关系 ESx标准 命名规则 ECMAScript 的历史 1. ECMAScript 6简介 1.1. 发布日期 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已…...

第1个数据库:编号,文本,时间,

写一个数据库 编号 文本 时间1 第一个文本 有100万条数据 -- 创建一个名为texts的表格来存储数据 CREATE TABLE texts ( id INTEGER PRIMARY KEY, text TEXT, time TIMESTAMP DEFAULT CURRENT_TIMESTAMP);-- 插入数据INSERT INTO texts (text) VALUES (第一个文…...

线性数据结构-手写链表-LinkList

为什么需要手写实现数据结构&#xff1f; 其实技术的本身就是基础的积累和搭建的过程&#xff0c;基础扎实 地基平稳 万丈高楼才会久战不衰&#xff0c;做技术能一通百&#xff0c;百通千就不怕有再难得技术了。 一&#xff1a;链表的分类 主要有单向&#xff0c;双向和循环链表…...

快手客户端一二面+美团前端一面+腾讯企业微信开发客户端一面

快手一面结志 1、自我介绍 2、对称加密非对称加密 3、TCP/UDP 4、在学校有什么课程是强项&#xff0c;说了过去几次面试中面到的C的语言基础知识 5、问C、Java中兴趣在哪里 6、问到项目&#xff0c;自己做的还是跟着学校老师做的&#xff0c;同样问到兴趣在哪里 7、LRU …...

探索数据结构

什么是数据结构 数据结构是由&#xff1a;“数据”与“结构”两部分组成 数据与结构 数据&#xff1a;如我们所看见的广告、图片、视频等&#xff0c;常见的数值&#xff0c;教务系统里的&#xff08;姓名、性别、学号、学历等等&#xff09;&#xff1b; 结构&#xff1a;当…...

VMware虚拟机中ubuntu使用记录(6)—— 如何标定单目相机的内参(张正友标定法)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、张正友相机标定法1. 工具的准备2. 标定的步骤(1) 启动相机(2) 启动标定程序(3) 标定过程的操作(5)可能的报错 3. 标定文件内容解析 前言 张正友相机标定法…...

每日OJ题_记忆化搜索②_力扣62. 不同路径(三种解法)

目录 力扣62. 不同路径 解析代码1_暴搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 解析代码3_动态规划 力扣62. 不同路径 62. 不同路径 难度 中等 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器…...

【微信小程序开发】微信小程序、大前端之flex布局方式详细解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

代码随想录算法训练营第二十天:二叉树成长

代码随想录算法训练营第二十天&#xff1a;二叉树成长 110.平衡二叉树 力扣题目链接(opens new window) 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a;一个二叉树每个节点 的左右两个子树的高度差的绝…...

Opensbi初始化分析:设备初始化-warmboot

Opensbi初始化分析:设备初始化-warmboot 设备初始化sbi_init函数init_warmboot函数coolboot & warmbootwait_for_coldboot函数domain && scratch(coldboot所特有)console初始化及print相关工作(coldboot所特有)系统调用的相关初始化(coldboot所特有)综上设备…...

软考 系统架构设计师系列知识点之软件可靠性基础知识(13)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之软件可靠性基础知识&#xff08;12&#xff09; 所属章节&#xff1a; 第9章. 软件可靠性基础知识 第3节 软件可靠性管理 为了进一步提高软件可靠性&#xff0c;人们又提出了软件可靠性管理的概念&#xff0c;把软件可…...

将ESP工作为AP路由模式并当成服务器

将ESP8266模块通过usb转串口接入电脑 ATCWMODE3 //1.配置成双模ATCIPMUX1 //2.使能多链接ATCIPSERVER1 //3.建立TCPServerATCIPSEND0,4 //4.发送4个字节在链接0通道上 >ATCIPCLOSE0 //5.断开连接通过wifi找到安信可的wifi信号并连接 连接后查看自己的ip地址变为192.168.4.…...

Python深度学习基于Tensorflow(6)神经网络基础

文章目录 使用Tensorflow解决XOR问题激活函数正向传播和反向传播解决过拟合权重正则化Dropout正则化批量正则化 BatchNormal权重初始化残差连接 选择优化算法传统梯度更新算法动量算法NAG算法AdaGrad算法RMSProp算法Adam算法如何选择优化算法 使用tf.keras构建神经网络使用Sequ…...

力扣HOT100 - 35. 搜索插入位置

解题思路&#xff1a; 二分法模板 class Solution {public int searchInsert(int[] nums, int target) {int left 0;int right nums.length - 1;while (left < right) {int mid left ((right - left) >> 1);if (nums[mid] target)return mid;else if (nums[mid…...

国内著名平面设计师的个人网站/seo薪资seo

前言我于2020年开始接触、使用Vercel(ZEIT)的&#xff0c;要是我能早点知道的话&#xff0c;我也不会煞费苦心去优化Github上的个人博客的加载速度问题&#xff0c;当然国内也有类似Github的代码托管网站&#xff0c;如Gitee(码云)&#xff0c;Coding(被腾讯收购&#xff0c;还…...

国外网站 工信部备案/免费源码下载网站

问题&#xff1a;想要自己构建爬虫和自动化表格&#xff0c;进行数据收集和分析&#xff0c;有哪些好的渠道学习&#xff1f;1.很多人一上来就要爬虫&#xff0c;其实没有弄明白要用爬虫做什么&#xff0c;最后学完了却用不上。大多数人其实是不需要去学习爬虫的&#xff0c;因…...

白日梦怎么做的网站/天堂网

快速找到未知长度单链表中的中间结点 1.普通方法 首先需要遍历一下链表&#xff0c;然后得知链表长度&#xff0c;然后在重新查找中间长度的结点&#xff0c;然后进行输出结点值。算法复杂度为O(n)O(1/2n)。这里就不进行普通代码演示了。 2.加分方法 运用快慢指针的方法&#…...

pdf viewer wordpress/网络市场营销

http://edu.51cto.com/lesson/id-10135.html http://edu.51cto.com/lecturer/user_id-140924.html转载于:https://www.cnblogs.com/mover/p/3406629.html...

黄埔营销型网站建设/广州网站seo公司

MySQL 提供了两种事务型的存储引擎&#xff1a;InnoDB 和 NDB Cluster 。另外还有一些第三方存储引擎也支持事务1. 数据库事务数据库事务指的是一组数据操作&#xff0c;事务内的操作要么就是全部成功&#xff0c;要么就是全部失败。例如在转账的流程下&#xff0c;张三给李四转…...

网站建设 青海/seo外包公司专家

其实可以用存储过程&#xff0c;但想用另一种方法实现&#xff1a; 首先创建一个辅助表&#xff0c;可以设置CREATE TABLE t4 (id int(11) NOT NULL AUTO_INCREMENT,num int(11) DEFAULT NULL,PRIMARY KEY (id) )insert into t4(num) select id from xxx limit 31;(偷懒插入31条…...