自己动手开发音乐播放器《六》播放方式的实现

提到播放方式经常听歌的朋友一定不会陌生,常见的播放方式有顺序播放,单曲循环,列表循环,随机播放,

在写代码前我先介绍我的思路:

在实现这些播放方式中一定要一个前提就是要保证歌曲能够连续播放,为了实现歌曲的连续播放,我用到了定时器和回调函数用于判断歌曲是否播放完毕

首先我定义了一个定时器 SetTimer(hwnd,1,1000,MusicNowTime),并且定义了一个回调函数MusicNowTime,

并且在MusicNowTime中放一个if语句用于判断当前歌曲的播放状态,当歌曲播放完成后,就播放下一曲,

因为使用了回调函数所以每隔1秒会判断一次,直到播放完毕就播放下一曲

有了思路后就开始写代码

首先在PlayMusic函数中添加一段定时器的代码

	SetTimer(hwnd,1,1000,MusicNowTime);//用于处理播放时间

然后定义一个全局变量用于实现歌曲的连续播放

/***************************************************************************
                 显示播放歌曲的时间所需的全局变量     
****************************************************************************/
static char curTime[256];//当前歌曲播放的位置

最后定义一个回调函数MusicNowTime实现歌曲的连续播放并且实现播放方式和显示播放时间

/***************************************************************************
               函数名:   MusicNowTime
			   函数功能: 显示当前歌曲的播放时间
*****************************************************************************/
void CALLBACK MusicNowTime(HWND hwnd,UINT message,UINT iTimerId,DWORD dwTime)
{
	TCHAR Position[256];//保存歌曲的播放位置
	TCHAR cmd[256];//保存得到歌曲的播放位置的命令

	//打印得到歌曲的播放位置的命令
	wsprintf(cmd,"status %s position",OpenMusicFile);

	//发送得到歌曲播放时间的命令
	mciSendString(cmd, Position, sizeof(Position)/sizeof(TCHAR), NULL);

	int Time = atoi(Position)/1000;//保存歌曲的播放时间(秒)

	int Minute = Time/60;//分钟

	int Second = Time - 60*Minute;//秒

	//打印播放时间
	wsprintf(curTime,"%02d:%02d",Minute,Second);

	//显示播放时间
	SetDlgItemText(hwnd,IDC_BEGIN_TIME,curTime);

	TCHAR mode[MAX_PATH];//保存的到当前的播放状态

	//打印得到状态的命令
	wsprintf(cmd,"status %s mode",OpenMusicFile);

	//发送得到状态的命令
	mciSendString(cmd,mode,sizeof(mode)/sizeof(TCHAR),NULL);

	//判断一首歌是否播完
	if(0 == strcmp(mode,TEXT("stopped")))
	{
		switch(iLoopType)
		{
		
           	case 0://列表循环
			{
				//下一曲
				JumpMusic(hwnd, 1);
			}
			break;
			
			case 1://顺序播放
			{
				if(numPlayMusicNow == totalMusicCount-1)
				{
					//停止
					StopMusic(hwnd);
				}
				else
				{
					//下一曲
					JumpMusic(hwnd, 1);
				}
			}
			break;

			case 2://单曲循环
			{
				PlayMusic(hwnd);
			}
			break;


			case 3://随机播放
			{
				//下一曲
				JumpMusic(hwnd, 1);
			}
			break;
			default:
			break;
		}
	}
}

实现了连续播放后还需要实现播放方式的自由切换,使用菜单可以实现播放方式的自由切换

/******************************************************************************
                   函数名;   void PlayTypeMenuSet(HWND hwnd,int indexs)
				   函数功能: 播放模式菜单设定
*******************************************************************************/
void PlayTypeMenuSet(HWND hwnd,int indexs)
{
	//该函数取得分配给指定窗口的菜单的句柄
	HMENU hMenu = GetMenu(hwnd);

	switch(indexs)
	{
	    case 0://列表循环
		{
			CheckMenuItem(hMenu,ID_MENUORDER,MF_CHECKED);
		    CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENURANDOM,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENUITEM40017,MF_UNCHECKED);
		}
		break;

		case 1://顺序播放
		{
			CheckMenuItem(hMenu,ID_MENUORDER,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_CHECKED);
		    CheckMenuItem(hMenu,ID_MENURANDOM,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENUITEM40017,MF_UNCHECKED);
		}
		break;

		case 2://单曲循环
		{
			CheckMenuItem(hMenu,ID_MENUORDER,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENURANDOM,MF_CHECKED);
		    CheckMenuItem(hMenu,ID_MENUITEM40017,MF_UNCHECKED);
		}
		break;

		case 3://随机播放
		{
			CheckMenuItem(hMenu,ID_MENUORDER,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENURANDOM,MF_UNCHECKED);
		    CheckMenuItem(hMenu,ID_MENUITEM40017,MF_CHECKED);
		}
		break;
		default:
		break;
	}
}

运行结果






  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 自己动手实现hdfs shell需要掌握Java编程语言和Hadoop分布式文件系统的基本知识。首先需要了解Hadoop的文件系统API,然后编写Java程序实现对HDFS的操作,例如创建、删除、上传、下载文件等。接着可以将这些操作封装成一个命令行工具,即HDFS Shell,使用户可以通过命令行界面来操作HDFS。最后,可以通过测试和优化来提高HDFS Shell的性能和稳定性。 ### 回答2: HDFS(Hadoop分布式文件系统)是Hadoop生态系统的核心组件之一。HDFS Shell是HDFS的命令行工具,可以通过它来管理和操作文件系统。自己动手实现HDFS Shell,可以更加深入地理解HDFS的内部细节和工作原理。 首先,我们需要理解HDFS的客户端-服务器架构和通信协议。Hadoop提供了Java API和RPC(远程过程调用)协议来实现HDFS客户端-服务器之间的通信。我们可以使用Java API编写客户端,或直接使用Hadoop提供的命令行工具hadoop fs来与HDFS进行交互。但为了更好地理解HDFS的操作细节和实现原理,我们选择使用RPC协议来实现HDFS Shell。 接下来,我们需要了解RPC协议的基本实现原理。RPC是一种远程过程调用机制,它允许客户端调用服务器端的函数,就像本地函数一样。在Hadoop中,RPC协议的通信是基于Java的序列化机制实现的。因此,我们需要先详细了解Java的序列化机制。 接着,我们需要设计HDFS Shell的基本命令以及调用服务器端的RPC函数。HDFS提供了大量的API函数来实现文件系统的各种操作,如文件创建、删除、读写等。我们可以根据需求选择合适的API函数并将其封装成对应的命令。 最后,我们需要编写HDFS Shell客户端的连接和交互代码。客户端需要向服务器发送RPC请求并解析返回结果。我们可以使用Java提供的Socket和IO类来实现客户端-服务器之间的通信。 总结来说,自己动手实现HDFS Shell需要深入理解HDFS的架构和通信协议,掌握Java的序列化机制,并能够使用Socket和IO类实现客户端-服务器之间的通信。通过这个过程,我们可以更好地理解HDFS的内部细节和工作原理,并提高编程能力。 ### 回答3: HDFS(Hadoop分布式文件系统)是一个分布式文件系统,适用于大规模数据处理。在HDFS中,我们通常使用shell命令来管理文件和目录。在本文中,我们将介绍如何使用Java来实现一个简单的HDFS shell。 步骤1:安装Hadoop 在开始编写HDFS shell之前,您需要安装Hadoop并了解其基本概念。Hadoop的安装可以参考其官方文档,本文不再赘述。 步骤2:连接HDFS 连接到HDFS是使用HDFS shell的第一步。您可以使用以下代码来连接到HDFS: ``` Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://localhost:9000"); FileSystem fs = FileSystem.get(conf); ``` 在这里,我们使用“localhost:9000”的默认配置文件来连接到HDFS。您可以根据自己的情况进行更改和定制。 步骤3:实现基本功能命令 下一步是实现基本功能命令,如mkdir,ls,rm等。以下是这些命令的实现方式: ``` // 创建目录 public void mkdir(String dirName) throws IOException { Path dirPath = new Path(dirName); fs.mkdirs(dirPath); } // 列出文件 public void ls(String path) throws IOException { Path dirPath = new Path(path); FileStatus[] fileStatuses = fs.listStatus(dirPath); for (FileStatus status: fileStatuses) { System.out.println("name: " + status.getPath().getName() + ", folder: " + status.isDirectory()); } } // 删除文件 public void rm(String path) throws IOException { Path filePath = new Path(path); boolean deleted = fs.delete(filePath, true); if (deleted) { System.out.println(filePath.toString() + " is deleted."); } else { System.out.println(filePath.toString() + " not deleted."); } } ``` 步骤4:实现高级命令 高级命令通常需要更复杂的实现方法。以下是实现cat和copyToLocal的示例: ``` // 读取文件内容 public void cat(String fileName) throws IOException { Path filePath = new Path(fileName); if (!fs.exists(filePath)) { System.out.println("File not exists!"); return; } FSDataInputStream inputStream = fs.open(filePath); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); inputStream.close(); } // 复制文件到本地 public void copyToLocal(String hdfsPath, String localPath) throws IOException { Path srcPath = new Path(hdfsPath); Path dstPath = new Path(localPath); fs.copyToLocalFile(srcPath, dstPath); } ``` 步骤5:编写主函数 最后一步是编写一个主函数来测试实现的命令。以下是一个简单的例子: ``` public static void main(String[] args) throws IOException { HdfsShell shell = new HdfsShell(); shell.mkdir("/test"); shell.ls("/"); shell.cat("/test/hello.txt"); shell.copyToLocal("/test/hello.txt", "/Users/username/Desktop/hello.txt"); shell.rm("/test/hello.txt"); } ``` 使用上述代码,我们可以创建一个名为“test”的目录并在其中创建一个名为“hello.txt”的文件。然后我们列出根目录下的所有文件,读取文件内容并复制到本地。最后,我们将删除该文件。 总结 在本文中,我们介绍了如何使用Java编写一个简单的HDFS shell。通过实现基础和高级命令,我们可以灵活地管理分布式文件系统中的文件和目录。如果您想深入了解Hadoop和HDFS,请阅读有关其官方文档和其他参考资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值