在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

这篇具有很好参考价值的文章主要介绍了在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先,祝贺阿根廷获得2022世界杯冠军!


简介

Winform作为一个比较老的平台,应用其实越来越少了,而即使设计Winform程序,多数人也会选择C#,而不是C++。但是题主在学校学习一门课程被迫使用了Winform/C++,并完成了课程作业,在此分享以下自己的作业,也当作学习纪录。在完成这个播放器过程中,我也参考了网上许多资料,最主要的可能是下面这位大佬做的三篇文章,不过他是用C#完成的,且没有加入在线的搜索播放功能(但是做的属实很好):
C#-WinForm-简单的音频播放器(基于WindowsMediaPlayer控件)(一)
C#-WinForm-简单的音频播放器(基于WindowsMediaPlayer控件)(二)
C#简单音乐播放器(三)

我的播放器同样是通过WMP控件实现,具备的主要功能有导入并播放本地歌曲,读取本地歌词文件,搜索、播放、收藏并下载在线歌曲。另外,由于老师要求使用到数据库操作,还加入了用户注册并登录功能,每个用户都能设置单独的播放器主题和歌单。这个播放器最终也实现成功打包为一个安装包,便于在其它电脑安装使用。下图是播放器的整体界面及注释:
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)


功能展示

1.用户注册、登录、自定义主题

在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

2.本地歌曲导入、播放并读取歌词文件

歌词文件需要为.lrc格式,且与歌曲同名并放在同个路径下

在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

3.在线歌曲搜索、收藏、播放

在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

4.歌词同步及桌面歌词

在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

5.在线歌曲下载

在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)


一、新建Winform项目

介绍完主要功能就要进入到正式设计了,首先当然要新建一个Winform的空项目,这个步骤网上的教程其实很多,前人之述备矣。我采用的是新建CLR空项目后新建窗体再重启VS的方法(不得不吐槽经常出现窗体加载不出来的问题),这里要注意不同版本的VS可能操作过程不同,我使用的是2017版的,同个版本可以使用下面这位兄弟的方法,不过里面的那段代码要改一下:

#include "MyForm.h"

using namespace Project1;

[STAThread]
void Main(array<String ^>^ args)
{
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false);

	MyForm form;
	Application::Run(%form);
}

提示:工程名和窗体名要根据自己的项目更改,另外我发现工程名一般设为Project加数字就行,改成别的容易运行失败

VS2017 C++中创建winform窗体应用


二、界面UI设计

主要控件:

播放器:AxWMPLib::AxWindowsMediaPlayer
控制按钮:PictureBox
菜单栏按钮:Panel+PictureBox
提示文本:Label
搜索框:TextBox
搜索数设置:NumericUpDown
列表:ListView
进度条和音量条:TrackBar

1.按钮控件

按钮是本项目中最常用的控件,简介图片中蓝色字体的注释均为此控件,但由于Winform自带的按钮控件外观实在有些落后,我选择使用PictureBox控件搭配图片进行设计,添加过程为:新建PictureBox控件->Name属性命名->Image属性添加图片->BackColor设置颜色(一般为透明使其与窗体同色)->SizeMode设置为Zoom->Cusor设置为Hand(鼠标的图标)->添加Click,MouseEnter,MouseMove触发事件(分别表示点击、悬停、离开)。下面以播放按钮为例:
按钮使用时的效果
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

下面是该按钮需要添加的触发函数

			//鼠标悬停 播放 按钮
	private: System::Void Play_Enter(System::Object^  sender, System::EventArgs^  e) {
		if ((int)MusicPlayer->playState != 3) {
			PlayBtn->Image = (cli::safe_cast<System::Drawing::Image^>(rm->GetObject(L"播放pink")));
		}
		else if ((int)MusicPlayer->playState == 3) {
			PlayBtn->Image = (cli::safe_cast<System::Drawing::Image^>(rm->GetObject(L"暂停pink")));
		}
	}
			 //鼠标离开 播放 按钮
	private: System::Void Play_Leave(System::Object^  sender, System::EventArgs^  e) {
		if ((int)MusicPlayer->playState != 3) {
			PlayBtn->Image = /*gcnew Bitmap(Application::StartupPath + "\\Icon\\播放white.png");*/(cli::safe_cast<System::Drawing::Image^>(rm->GetObject(L"播放white")));
		}
		else if ((int)MusicPlayer->playState == 3) {
			PlayBtn->Image = (cli::safe_cast<System::Drawing::Image^>(rm->GetObject(L"暂停white")));
		}
	}
			 //鼠标点击 播放 按钮
	private: System::Void Play_Click(System::Object^  sender, System::EventArgs^  e) {
		if ((int)MusicPlayer->playState == 2)//如果播放器暂停
		{
			MusicPlayer->Ctlcontrols->play();//开始播放
		}
		else if ((int)MusicPlayer->playState == 3)//如果播放器正在播放
		{
			MusicPlayer->Ctlcontrols->pause();//暂停播放
		}
	}

具体的实现过程可以参考我的一篇教程:
Winform/C++按钮控件自定义外观、触发函数

本项目中还有菜单栏按钮(简介图红色注释对应按钮),此类按钮实现原理相似,不同的是我将用PictureBox制作的按钮放在一个Panel控件中,使用时通过改变Panel的BackColor来实现按钮反馈,方法较为简单,此处不再赘述。

2.Windows Meida Player控件

由于设计的是一个音乐播放器,因此自然少不了具有播放功能的控件。关于这个控件的使用网上也已经有了不少资料,要添加这个控件有两种方法,一种是直接拖动控件添加,值得注意的是,WMP控件并不在默认的工具箱中,因此我们需要在工具箱中右击鼠标,在弹出菜单中单击“选择项”,在弹出的“选择工具箱项”对话框中单击“COM组件”选项卡,选择“Windows Media Player”,点击确定添加,再在工具箱中把该控件拖放到窗体中。另一种方法是在程序中通过编写代码添加,好处是更为灵活,也不会在设计器中出现控件。

在MainForm.h中添加命名空间 using namespace System::Media;
在MainForm类中生成播放器的对象: private: AxWMPLib::AxWindowsMediaPlayer^ MusicPlayer = gcnew AxWMPLib::AxWindowsMediaPlayer;
在MainForm类中FormLoad函数中(避免设计器出现控件)
MusicPlayer->BeginInit();
this->MusicPlayer->Visible = false;
MusicPlayer->EndInit();

在触发函数中调用此播放器如:
MusicPlayer->URL = Path;
MusicPlayer->Ctlcontrols->play();

添加控件后,由于我们不打算使用默认的UI,因此需要将控件的Visible属性设置为False

关于WMP控件的属性及函数等,网上有很多资料,这里推荐一篇文章以作参考:
c#—如何借助windows media player控件编写播放器

3.桌面歌词

桌面歌词我使用的方法是新建一个窗体,窗体上只有一个Label控件用来显示歌词。窗体属性的设置流程如下:

  1. 将窗体的FormBorderSyle设置为None(去掉边框)
  2. 将窗体的BackColor设置为某个特定颜色(除了Transparent)
  3. 将窗体的TransparencyKey设置为上面设置的颜色(意味着窗体中这种颜色的区域会呈现透明效果
  4. 将Label的BackColor也设置为此颜色
  5. Label的ForeColor设置为另一种不同的颜色

设置完成后即可以在主窗体MainForm.h中调用该窗体类生成对象如:

	public:LrcForm^ lrcform = gcnew LrcForm();//桌面歌词窗体

4.界面全屏显示

在运行程序时,控制窗体大小的按钮(最小化、最大化、关闭)控件功能实现基本只需要通过改变窗体的WindowState即可,如最大化窗体:

this->WindowState = FormWindowState::Maximized;

但是,实际操作时我们会发现,最大化后窗体内的控件位置会集中在左上角,无法实现真正的全屏效果。解决这个问题,我们主要通过设置控件的anchor属性Dock属性,这两个属性的基本含义是:
anchor:表示控件与窗体的位置关系,有left、top、bottom、right、none五个参数。激活任意一个即表示控件与窗体某一边绝对位置保持不变,可同时激活多个。
dock:表示控件填充窗体某一边。
例如,播放按钮我们希望在任何时候都位于界面的左下角,那么只需要把anchor设置为Bottom+Left。以此类推,设置其它控件后即可呈现全屏效果,如下所示:
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)


二、主要功能实现

这个音乐播放器实现的功能比较杂,这篇文章很难都详细涉及,只能随缘选一些纪录一下了。

1.数据库操作(Access)

数据库在本项目中还是比较重要的,在此特别展开讲一下。数据库方面使用的是Access数据库,一共使用了两个数据库:用户信息(UserData)数据库和歌曲信息(LocalSongs)数据库,分别用来存放用户信息歌曲信息。如下图所示:
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)
数据库的链接和使用同样有两种方法
一种是在窗体可视化设计界面添加特定的控件(如下图)并设置链接数据库,再在程序文件中调用这些控件从而实现对数据库的增删查改等操作。这种方法在网上能查到很多资料,此处不再赘述。
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

另一种是在程序文件中直接使用代码的方式调用数据库的链接并使用,代码主要框架如下(注意数据库放到程序debug文件夹中,便于最后打包):

private:String^ strConn2= String::Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}\\UserData.mdb", Application::StartupPath);
private:OleDbConnection^ Conn2 = gcnew OleDbConnection(strConn2);
Conn2->Open();
String^ cmd=······;//sql语句
Data::OleDb::OleDbCommand^ selectCmd = gcnew Data::OleDb::OleDbCommand(strcmd, Conn2);
	······//根据需要编写,如Object^ oRes = selectCmd->ExecuteScalar();返回的oRes可表示真/假
Conn2->Close();

这两种方法各有优劣,前者链接过程较为简单,可视化操作,缺点是所连接的数据库在程序运行时较难更改;后者需要在程序中通过代码新建数据库连接,但优点是便于修改所连接的数据库,另一方面,后者更易实现最终程序的打包操作。本项目主要采用后者,部分使用了前者。
个人也较为推荐第二种方法

进行数据库操作时我们常常会用到SQL语句,这些在网上也都能找到资料,这里也推荐一个网址查询:
SQL语法

下面以本项目中注册按钮的数据库操作为例子(如下代码是注册按钮的Click函数),由于
在点击注册按钮时需要实现写入用户数据并创建歌曲信息表,即需要操作两个数据库文件,因此我选择编写了一个SqlWrite(String^ mdbName,String^ strcmd)函数,在函数中定义了可以随mdbName(数据库名)变化的链接,这里就体现了通过代码添加数据库链接的优越性

		 //注册按钮
private: System::Void SignUp_Click(System::Object^  sender, System::EventArgs^  e) {
	if (!IfCheckFill()) {
		NameGuideLabel->Text = "用户名和密码不能为空!";
		NameGuideLabel->Visible = true;
		return;
	}
	userName = UserNameTextbox->Text->Trim();
	passWord = PassWordTextbox->Text->Trim();
	String^ strCmd = String::Format("SELECT UserName FROM {0} WHERE UserName='{1}'", "UserData", userName);
	this->Conn1->ConnectionString = String::Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}\\{1}.mdb", Application::StartupPath, "UserData");
	Data::OleDb::OleDbCommand^ selectCmd = gcnew Data::OleDb::OleDbCommand(strCmd, Conn1);
	// 执行操作
	this->Conn1->Open();
	Object^ oRes = selectCmd->ExecuteScalar();
	this->Conn1->Close();
	if (oRes) {
		this->NameGuideLabel->Text = "×用户已存在!";
		NameGuideLabel->Visible = true;
	}
	else
	{
		//将用户名和密码存入用户数据表格中
		String^ strCmd1 = String::Format("INSERT INTO UserData(UserId,UserName) VALUES('{0}','{1}')", passWord, userName);
		SqlWrite("UserData",strCmd1);
		
		//创建用户专属表格(下载歌单和收藏歌单)
		String^ strCmd2 = String::Format("CREATE TABLE {0}DownloadedList(FilePath varchar(255),SongName varchar(255),Singer varchar(255),Duration varchar(255),FileSize varchar(255))",userName);
		SqlWrite("LocalSongs", strCmd2);
		String^ strCmd3 = String::Format("CREATE TABLE {0}FavoriteList(FilePath varchar(255),SongName varchar(255),Singer varchar(255),Duration varchar(255),FileSize varchar(255))", userName);
		SqlWrite("LocalSongs", strCmd3);

		NameGuideLabel->Text = "注册成功!";
		NameGuideLabel->ForeColor = Color::DarkGreen;
		NameGuideLabel->Visible = true;
	}
}
//检查文本框是否为空的函数
private:bool IfCheckFill() {
	userName = UserNameTextbox->Text->Trim();
	passWord = PassWordTextbox->Text->Trim();
	if (String::IsNullOrEmpty(userName))return false;
	if (String::IsNullOrEmpty(passWord))return true;
	else return true;
}
//数据库操作函数,输入参数为数据库名和指令
private:void SqlWrite(String^ mdbName,String^ strcmd)
{
	this->Conn1->ConnectionString =String::Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}\\{1}.mdb",Application::StartupPath,mdbName);
	Data::OleDb::OleDbCommand^ selectCmd = gcnew Data::OleDb::OleDbCommand(strcmd, Conn1);
	// 执行操作
	this->Conn1->Open();
	Object^ oRes = selectCmd->ExecuteScalar();
	this->Conn1->Close();
}

2.在线功能

仅供学习交流,不做商业用途
在线歌曲方面,Winform提供了联网功能,不过需要先添加引用System.Web.Extensions
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)
如果在引用里找不到的话,需要先将项目属性(右键Project->Porperties)按下图设置为V4.0再添加引用,添加完引用可以再改回来。
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)
当然,这样还不够,在程序中,我们还需要"Using"一些引用,如下所示:

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::Collections::Generic;
	using namespace System::Net;
	using namespace System::IO;
	using namespace System::Text;
	using namespace System::Web::Script::Serialization;
	using namespace System::Collections::Generic;

音源上,我使用的是酷我音乐的音源,获取的方法在网上基本也都能找到,以下列出主要的几个操作:

  1. 歌曲搜索:(返回含Rid的Json字符串,需要进行反序列化处理)
    Get(http://search.kuwo.cn/r.s?all=str&ft=music&rformat=json&encoding=utf8&rn=30&callback=song&vipver=MUSIC_8.0.3.1)

  2. 歌曲.mp3链接获取:(将获取的链接直接赋给MusicPlayer->URL,再播放
    Get(http://antiserver.kuwo.cn/anti.s?response=url&type=convert_url&br=320kmp3&format=mp3&rid=MUSIC_MusicRid)

  3. 歌词获取:
    Get(http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=MusicRid)

其中加了粗体的都是需要根据需求自己设置的,str表示搜索框的字符串,可以搜索歌手或歌曲;rn的值表示搜索数目;Musicrid的值表示歌曲对应的RID,即第一步中获取。
关于Get(String^ str)方法(http请求方法)和json反序列化的实现,网上也有不少资料,不过基本也都是C#编写的,稍作修改就好了。
下面给出我修改了的Get方法:

			//获取歌曲json类型数据,返回json字符串
	public:static String^ Get(String^ Url) {
		HttpWebRequest^ request = (HttpWebRequest^)WebRequest::Create(Url);
		request->Proxy = nullptr;
		request->KeepAlive = false;
		request->Method = "GET";
		request->ContentType = "application/json; charset=UTF-8";
		request->AutomaticDecompression = DecompressionMethods::GZip;

		HttpWebResponse^ response = (HttpWebResponse^)request->GetResponse();
		Stream^ myResponseStream = response->GetResponseStream();
		StreamReader^ myStreamReader = gcnew StreamReader(myResponseStream, Encoding::UTF8);
		String^ retString = myStreamReader->ReadToEnd();

		myStreamReader->Close();
		myResponseStream->Close();

		if (response != nullptr)
		{
			response->Close();
		}
		if (request != nullptr)
		{
			request->Abort();
		}
		return retString;
	}

下面是我定义的在线搜索方法,只需要在点击搜索按钮调用即可:

			//在线搜索函数(json)
	private:void OnlineSearch() {
		if (String::IsNullOrEmpty(SearchTextBox->Text->Trim())|| SearchTextBox->Text->Trim()=="在线搜索") {
			ExitForm^ form = gcnew ExitForm();
			form->GuideLabel->Text = "请输入歌曲或歌手!";
			form->StartPosition = FormStartPosition::CenterParent;
			form->ShowDialog();
			return;
		}
		OnlineSongslist->Clear();
		String^ searchNumber = SearchNumberChoose->Text;
		String^ searchName = Get(String::Format("https://search.kuwo.cn/r.s?all={0}&ft=music&itemset=web_2013&client=kt&pn=0&rn={1}&rformat=json&encoding=utf8&vipver=MUSIC_8.0.3.1", SearchTextBox->Text->Trim(),searchNumber));
		array <String^>^ ss = gcnew array <String^>{searchName};//将获取的json字符串放入字符串数组中,每首歌对应一个字符串
		
		//产生搜索提示窗口,并在搜索完成后关闭窗口
		ExitForm^ form = gcnew ExitForm();
		form->OKBtn->Visible = false;
		form->CancelBtn->Visible = false;
		form->CloseBtn->Visible = false;
		form->GuideLabel->Visible = true;
		form->GuideLabel->Text = "(*^_^*)正在搜索歌曲······";
		form->ShowInTaskbar = false;
		form->StartPosition = FormStartPosition::CenterScreen;
		form->Show();
		form->Update();//这条指令能确保搜索时提示框能显示
		//反序列化处理字符串
		for each(String^ s in ss)
		{
			JavaScriptSerializer^ serializer = gcnew JavaScriptSerializer();
 			Dictionary<String^, Object^>^ json = (Dictionary<String^, Object^>^)serializer->DeserializeObject(s);
			array<Object^>^ firstKey = (array<Object^>^)json["abslist"];
			for each(Object^ i in firstKey)
			{
				Dictionary<String^, Object^>^ y = (Dictionary<String^, Object^>^)i;
				String^ path = "http://antiserver.kuwo.cn/anti.s?response=url&type=convert_url&br=320kmp3&format=mp3&rid=" + y["MUSICRID"]->ToString();//hts_MVPIC
				String^ mp3Path = Get(path);//mp3后缀路径
				String^ songname = y["SONGNAME"]->ToString();//歌曲名
				String^ singername = y["ARTIST"]->ToString();//歌手名
				int During = int::Parse(y["DURATION"]->ToString());//歌曲时长-秒
				int Min = During / 60;
				int Sec = During % 60;
				String^ min;
				String^ sec;
				if (Min >= 10)min = Min.ToString();
				else if (Min < 10)min = "0" + Min;
				if (Sec >= 10)sec = Sec.ToString();
				else if (Sec < 10)sec = "0" + Sec;
				String^ during = min + ":" + sec;//歌曲时长-00:00

				OnlineSongslist->Add(gcnew SongsList(songname, singername, path, during,"未知"));
			}
		}		
		form->Close();
		localSongslist = OnlineSongslist;
		AddSongsToListView(localSongslist);
	}

上面这段代码中除了获取了歌曲链接和歌曲信息外,还通过Songslist生成歌曲对象存放这些信息,Songslist是自己定义的一个类,只需要在类中定义所需要的属性和构造函数就可以,这里我感受到了面向对象编程的优越性。类似的方法我也用在了歌词处理上。下面是我的歌曲类的一些属性:

	//定义索引属性,方便外部调用
	public: property String^ FileName { String^ get() { return fileName; } void set(String^ value) { fileName = value; } }
	public: property String^ FilePath { String^ get() { return filePath; } void set(String^ value) { filePath = value; } }
	public: property String^ FileSize { String^ get() { return fileSize; } void set(String^ value) { fileSize = value; } }
	public: property String^ SingerName { String^ get() { return singerName; } void set(String^ value) { singerName = value; } }
	public: property String^ SongDuration { String^ get() { return songDuration; } void set(String^ value) { songDuration = value; } }
	public: property int SongId { int get() { return songId; } void set(int value) { songId = value; } }
	public: property bool IfFavorite { bool get() { return ifFavorite; } void set(bool value) { ifFavorite = value; } }//是否被添加到最爱歌单
	public: property String^ RidPath { String^ get() { return ridPath; } void set(String^ value) { ridPath = value; } }

3.程序打包

程序的打包我参考的是下面这篇教程进行的,使用的是Visual Studio Installer。
[WinForm] VS2010发布、打包安装程序(超全超详细)
其中,这篇教程的一些操作并不是必要的,可以根据自己的需求选择。另外,我第一次尝试打包程序后在安装运行时报出了缺少动态链接库文件(dll)的错误,这种问题只需要在打包时将对应的dll文件添加进去即可(部分在自己电脑系统文件中可以找到)。除此之外,为了方便更新,我们可以给安装包设置版本号,不过每次更改版本号会导致ProductCode的改变
另外,由于每次更新时用户的歌单数据库和用户信息数据库是不需要更改的,我们可以将这两个文件的属性Permanent设置为True,如下图所示:
在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

程序完成打包后即可进行安装操作。


总结

这个音乐播放器在运行时仍然会存在一些小bug,不过主要是出现在在线歌曲的处理上,我自己专业也不是学软件的,因此对很多东西也一知半解,包括面向对象编程,数据库处理等也是刚刚基础,只是因为比较有趣才花了不少时间学习。在此留个记录,如果对其他读者也有帮助的话,那更是我的荣幸。文章来源地址https://www.toymoban.com/news/detail-484487.html

到了这里,关于在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【html本地工具】html+css+js本地音乐播放器,实现可视化音频频谱

    html+css+js本地音乐播放器,实现可视化音频频谱 之前用swing写了个本地音乐播放器(如下图),但是效果一言难尽,界面丑,功能bug也多,唉 所以后面又重新用html写了个,界面样式和功能方面,比swing写的好看、完善多了。 导入音乐(已完成) 展示列表(已完成) 列表双击

    2024年02月14日
    浏览(27)
  • html+css+js本地音乐播放器,实现可视化音频频谱

    html+css+js本地音乐播放器,实现可视化音频频谱 之前用swing写了个本地音乐播放器(如下图),但是效果一言难尽,界面丑,功能bug也多,唉 所以后面又重新用html写了个,界面样式和功能方面,比swing写的好看、完善多了。 导入音乐(已完成) 展示列表(已完成) 列表双击

    2024年02月09日
    浏览(33)
  • APP推荐:推荐一款免费无广告的本地音乐播放器,手机听歌必备

    目录 一、软件简介 二、软件特色 三、软件使用 四、软件下载 相信很多朋友都喜欢听歌,今天给大家推荐一款非常棒的手机本地音乐APP——糖醋音乐,完全无广告、免费听歌,大家只需要把自己需要的歌曲下载到你的手机就可以愉快的听歌了,并且不需要手机联网省点、省

    2024年02月05日
    浏览(31)
  • 基于android音乐播放器的设计

    本科毕业论文(设计)诚信声明 本人郑重声明:所呈交的毕业论文(设计),题目《………基于android音乐播放器的设计……………………………》是本人在指导教师的指导下,进行研究工作所取得的成果。对本文的研究作出重要贡献的个人和集体,均已在文章以明确方式注

    2024年02月03日
    浏览(34)
  • 基于FPGA设计的音乐播放器

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 本文将介绍如何使用FPGA和PCM5102音频解码模块来制作音乐播放器,从生成PCM格式的音频文件开始,到如何编写I2S总线协议代码,音频数据的储存等。 PCM(Pulse Code Modulation,脉冲编码调制)音频数据是未经压

    2023年04月23日
    浏览(42)
  • 【swjtu】数字电路课程设计-音乐播放器

    数字电子技术B 课程设计 报告 (2 021 - 2022 第 1 学期) 课题名称: 音乐播放器 指导教师:郑    狄 项目成员:

    2023年04月12日
    浏览(32)
  • Android课程设计大作业-音乐播放器

    1)使用Service播放音乐 Android SDK提供了Service。Service有两种类型: 本地服务(Local Service):用于应用程序内部 远程服务(Remote Sercie):用于Android系统内部的应用程序之间前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单

    2024年02月10日
    浏览(32)
  • Android程序设计之音乐播放器实现

    基于MediaPlayer技术实现在线音乐播放器,播放在线音乐,后端使用SpringBoot将音乐存放在Tomcat服务器。app通过网络请求获取音乐,从而实现在线音乐播放。该项目分为用户端和管理员端 一、核心技术Service组件介绍 Service它可以在后台执行长时间运行操作而没有用户界面的应用组

    2024年02月04日
    浏览(40)
  • Android手机开发课程设计之音乐播放器

    一、音乐播放器概述与分析 目前手机的音乐播放功能已经是大家比较关注的一个部分,不少在人在购买手机的时候都会关心手机的音乐播放的能力,这也足以看出目前大家对音乐播放功能的重视,所以一款性能良好的手机音乐播放器软件一定会受到欢迎。和传统的音乐播放器

    2024年02月05日
    浏览(40)
  • 基于FPGA的音乐播放器硬件电路设计

    基于FPGA的音乐播放器硬件电路设计 随着嵌入式系统技术的不断发展,音乐播放器作为一种便携式设备得到了广泛的应用。本文将介绍一种基于FPGA(Field Programmable Gate Array)的音乐播放器硬件电路设计方案,该方案可以实现高质量的音频播放和文件存储功能。 系统概述 基于

    2024年02月02日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包