Linux下mp3播放器的实现.docx
- 文档编号:29831069
- 上传时间:2023-07-27
- 格式:DOCX
- 页数:33
- 大小:193.64KB
Linux下mp3播放器的实现.docx
《Linux下mp3播放器的实现.docx》由会员分享,可在线阅读,更多相关《Linux下mp3播放器的实现.docx(33页珍藏版)》请在冰豆网上搜索。
Linux下mp3播放器的实现
基于Linux下mp3播放器的研究实现
学生姓名:
XXX指导老师:
XXX
摘要:
由于Linux具有高度便携性和高度自由。
最近几年,它在移动设备和个人电脑领域的应用也越来越广泛。
鉴于以上应用领域对用户界面友好性方面的要求,几乎所有的此类应用都是采用图形用户界面。
基于GTK的GNOME,是Linux领域中最主要的桌面环境。
而GTK本身,则是创造图形用户界面的最流行的跨平台GUI工具箱之一。
这里将通过一个使用GTK和GStreamer技术的简单mp3播放器的实现,详细描述Linux环境下的图形界面编程技术。
关键词:
Linux;mp3播放器;GTK
TheExaminationandImplementationofMp3Player
inLinux
Studentname:
XIAOHong-zheAdvisor:
ZHOUShu-ren
Abstract:
Linuxeditionsinstalledonbothmobiledevicesandpersonalcomputershavebecomeincreasinglycommonplaceinrecentyears,owinglargelytoitshighlyportabilityandhighdegreeoffreedom.Inviewoftheimportanceofuserfriendlyoperation,almostalloftheseeditionsarebasedonGraphicalUserInterface(GUI).BasedonGTK,oneofthemostpopularcross-platformwidgettoolkitsforcreatinggraphicaluserinterfaces,Gnomeisadominantdesktopenvironment—theGUIwhichrunsontopofacomputeroperatingsystem.ThispapermainlyfocusedontheimplementationofasimpleGUIinterfacedmp3playerusingGTKandGStreamertechnologyunderGnomeenvironment,willillustratedetailedstepsonLinuxGUIprogramming.
Keywords:
Linux;mp3Player;GTK
1引言
1.1课程设计目的
随着时代的进步,科技的发展。
开源化的Linux在IT行业中运用越来越广泛了。
熟练的掌握Linux的相关操作,Linux内的程序开发,是作为一名当代大学生的首要目的。
所以,此课程将通过一个使用GTK和GStreamer技术的简单mp3播放器的实现,详细描述Linux环境下的图形界面编程技术。
1.2课程设计的意义
目前,我国在计算机应用、计算机软件和电子类相关专业的人才培养方面,取得了长足的发展,但同时也让我们深刻地感觉到缺乏实际开发设计项目的经验,不善与综合运用所学理论,对知识的把握缺乏融会贯通的能力。
本次课程设计是在我们学完了Linux操作系统之后开展的,通过此次Linux操作系统课程设计,可以让我们把书本上的理论知识用于实践中去,对Linux操作系统的各种操作能真正的理解,在设计的过程中,会出现很多问题是我们想不到的,书上也从来没有的,通过实践,提高了我们解决实际问题的能力。
本次我的课题的做一个简单的mp3播放器,现在音乐播放器随处可见,应用范围广,一定程度上对人们的生活做了一定的贡献,此次通过对论坛的设计,可以让自己所学的知识融入到实际生活。
2编译环境的搭建和检测
2.1基本编译环境的搭建
刚装好的系统中已经有GCC了,但是这个GCC几乎什么文件都不能编译,因为它缺少一些必须的头文件。
这里可以选择安装build-essential这个软件包来解决这个问题,方法是在Synaptic里面搜索build-essential或在终端中输入下面命令:
sudoapt-getinstallbuild-essential
安装完成后写一个C语言程序testc.c测试一下:
#include
intmain()
{
printf("HelloUbuntu!
\n");
return0;
}
编译运行:
$gcc-Walltestc.c-otestc
$./testc
$HelloUbuntu!
这样,基本开发环境就搭建成功了。
2.2安装GTK/GNOME编译环境
要安装GTK环境,只需要安装一个libgtk2.0-dev软件包就可以了;而安装GNOME开发环境的话,则需要安装gnome-devel,由于它包含有GTK开发包,此时不再需要libgtk2.0-dev包。
[8]在一般情况下,由于考虑到以后需要有一个Glade,并且还需要帮助文件,于是安装gnome-devel包和gnome-dev-doc包:
sudoapt-getinstallgnome-develgnome-dev-doc
安装完成后也同样做个测试程序:
#include
voidhello(GtkWidget*widget,gpointerdata)
{
g_print("HelloUbuntu!
\n");
}
gintdelete_event(GtkWidget*widget,GdkEvent*event,gpointerdata)
{
g_print("deleteeventoccurred\n");
return(TRUE);
}
voiddestroy(GtkWidget*widget,gpointerdata)
{
gtk_main_quit();
}
intmain(intargc,char*argv[])
{
GtkWidget*window;
GtkWidget*button;
gtk_init(&argc,&argv);
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_signal_connect(GTK_OBJECT(window),"delete_event",GTK_SIGNAL_FUNC(delete_event),NULL);
gtk_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(destroy),NULL);
gtk_container_set_border_width(GTK_CONTAINER(window),10);
button=gtk_button_new_with_label("HelloUbuntu!
");
gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(hello),NULL);
gtk_signal_connect_object(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(gtk_widget_destroy),GTK_OBJECT(window));
gtk_container_add(GTK_CONTAINER(window),button);
gtk_widget_show(button);
gtk_widget_show(window);/*显示一个窗口*/
gtk_main();/*进入主循环*/
return(0);
}
用下面命令编译运行:
$gccgtkhello.c-ogtktest`pkg-config--cflags--libsgtk+-2.0`
$./gtktest
此时会显示一个带有一个按钮的窗口,点击按钮以后窗口关闭,命令行显示HelloUbuntu!
2.3安装GStreamer编译环境
在Ubuntu中构建GStreamer开发环境同样非常简单,使用下面命令安装GStreamer就可以了。
$sudoapt-getinstallgstreamer0.10-toolsgstreamer0.10-xgstreamer0.10-plugins-basegstreamer0.10-plugins-goodgstreamer0.10-plugins-uglygstreamer0.10-plugins-badgstreamer0.10-ffmpeggstreamer0.10-alsagstreamer0.10-schroedingergstreamer0.10-pulseaudio
本段代码用于测试:
#include
intmain(int argc,char*argv[])
{
constgchar*nano_str;
guintmajor,minor,micro,nano;
gst_init(&argc,&argv);
gst_version(&major,&minor,µ,&nano);
if(nano==1)
nano_str=“(CVS)”;
elseif(nano==2)
nano_str=“(Prerelease)”;
else
nano_str=“”;
printf(“ThisprogramislinkedagainstGStreamer%d.%d.%d%s\n”,
major,minor,micro,nano_str);
return0;
}
用以下命令进行编译:
$gcc–Wallmu.c–ogstest`pkg-configgstreamer-0.10–cflags–libs`
$./gstest
成功则输出:
“ThisprogramislinkedagainstGStreamer0.10.21”。
至此,编环境搭建完毕。
3需求分析
3.1程序设计需求
结合GTK和GStreamer实现一个图形界面mp3音频播放器。
具体需求如下:
(1)能够方便地选择本机上的一个mp3文件进行播放。
选择mp3文件时,不需要有键盘输入操作。
(2)播放过程中可以暂停,暂停后可以从暂停处再次播放。
播放过程中可以停止,按下播放按钮后,可以再次从开头播放本文件。
本程序提供“快进”、“快退”按钮,分别跳到后方5%处和前方5%处,播放和暂停状态都可以快进快退,并保持当前状态不变。
(3)播放、暂停、或停止状态中,都可以选择其它mp3文件代替当前mp3文件进行播放。
(4)本程序中要有一个滚动条来显示当前的mp3文件播放位置,拖动滚动条,可以调节mp3文件的播放位置。
(5)在面板上显示mp3文件当前播放的时间和mp3文件的名字。
播放时间随时刷新,配合好前面的播放调节操作。
(6)提供“帮助”,“关于”等菜单按钮。
退出按钮要绝对有效,能够完美地结束整个程序,不在内存中留下垃圾。
(7)界面尽量美观,程序运行时不要出现异常。
(8)程序能在所有使用Gnome的Linux发行版上安装使用。
3.2需求分析
用GTK和GStreamer实现一个简单的mp3播放器并不是一件困难。
但要搞清楚具体执行逻辑,使写出的程序不出现难以解决的逻辑错误而导致最后的返工,还是需要事先认真规划好的。
图形界面mp3播放器。
根据常识来看,打开软件后,会出现图形界面,然后点击图形界面,选择mp3文件,点击开始,即可播放了。
图形界面出现后,要想让其响应用户的点击,就必然要有一个类似服务器的进程来执行接受用户命令的任务,GTK中的gtk_main函数可以担当这个角色,因此,本文将围绕这个函数来进行程序的设计。
程序规划流程图如图3-1所示:
图3-1程序规划流程图
无论在什么平台下,无论用什么开发工具,GUI应用程序的基本开发方法都是相似的。
开发人员都要编写两方面的代码,即应用于实现图形界面的代码和用于实现程序运行的代码,然后再将这两部分的代码结合起来,本程序也不例外。
用GTK绘制完用户界面后,要给控件加上信号,信号中附上自己编写的函数地址。
然后,操纵控件时,比如按下按钮后就会产生信号,gtk_main()循环会捕捉这个信号,按照信号注册时附上的函数地址调用特定的函数:
例如播放音频的函数。
这样,程序的大体构架就清楚了。
即,程序由事件信号驱动,接收到响应信号时调用预先编写好的处理函数进行处理。
4详细设计
4.1程序文件的组织
为了程序逻辑的清晰着想,不能把一个大程序中的所有内容放到一个文件里,否则,当程序增大到一定程度时修改和调试将变得极为困难。
再加之前面需求分析中已经提到的,编写GUI程序时,通常的做法是界面和后台分别编码,这样做简单且逻辑清晰。
因此可以在main函数中调用绘制界面的函数,并分别注册上信号,用gtk_main()循环完成函数调度的工作。
但绘制界面如果全部都在main函数中完成的话,程序代码会显得非常混乱,因此可以把绘制界面的工作分成很多步来完成,main函数调用每一步中相应的绘制函数。
当然可以把这些绘制函数跟main函数都一起放到main.c文件中,但这样做的话,还是不够清晰。
不妨新建一个gui.c文件,将完成图形绘制以及注册信号工作的函数集中放到里面。
接着考虑后台处理函数,很自然的,把这些函数都放到back.c文件中。
综上所述,本程序将建立main.c、gui.c、back.c三个头文件。
由于函数之间具有相互调用关系,如果要将这三个.c文件结合起来,就需要用到头文件。
因而,将按照程序的需要,选择性地建立main.h、gui.h、back.h头文件,在其中放入对应的.c文件中非静态函数和变量的声明。
4.2main.c文件
文件的的开始,程序先引入GTK和GStreamer工具包中所有类和函数的声明:
#include
#include
externGtkWidget*gui();
我在随后的gui.c文件中将会编写一个生成图形界面的gui()函数。
上面将其它文件中的函数导入时,使用了extern关键字,让程序更规范。
接着声明window变量:
GtkWidget*window;
GtkWidget类声明了一个名字为window的指针变量。
由于gui.c中的函数要使用本变量,这里将其放到main函数外面,使其具有全局作用域。
同时,考虑到main.c文件中只有一个main函数和一个全局变量,我决定不再编写main.h头文件,如果其它文件需要使用window变量的,显式的将所需变量引入即可。
下面的是main()函数:
intmain(intargc,char*argv[])
main函数中,程序首先分别对GTK和GStreamer进行初始化,初始化会设置函数库并处理命令行参数中的GTK和GStreamer知道的参数。
由于本程序中用不到这些参数,因此,这里只是起到初始化的作用。
[9]
接着,初始化gtk和gst:
gtk_init(&argc,&argv);
gst_init(&argc,&argv);
窗口本身是由gtk_window_new()创建的:
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
该函数是一个对象构造器,它返回一个指向新GtkWindow对象的指针。
命名约定在这里非常重要,因为GTK中的所有对象构造器和方法都要遵循它——名字的第一部分是类名,这里是GtkWindow(对于函数名来说,将它写为gtk_window,以将它和类本身的数据类型区分开来),然后是方法名。
gtk_window_new()接受一个参数,这个参数是一个常量,它指定了要创建的窗口类型。
GTK_WINDOW_TOPLEVEL是一个正常的应用程序窗口,它可以通过窗口管理器关闭、最小化和调整大小。
调用gst_container_add()函数:
gtk_container_add(GTK_CONTAINER(window),gui());
随后编写的gui()函数将生成并返回window内的各个控件的集合,程序将window作为一个容器,把gui()生成的图形界面加入进来,然后显示窗口。
要注意,GTK生成的窗口和控件默认都是不显示的,程序必须调用gtk_widget_show函数来显示它:
gtk_widget_show(window);
gtk_main();
GTK应用程序采用事件驱动机制,在完成用户界面创建后进入gtk_main()主循环,由此GTK接管了控制权,然后在主循环中循环地监听事件和信号的发生。
当捕获事件或信号后,则将控制权传递至所注册的信号事件处理程序进行处理,然后根据此程序选择返回或者退出GTK应用程序。
后面将用到的函数gtk_main_quit用来结束主事件循环,即退出GTK程序的运行。
至此,main.c文件就结束了。
显然,它的脉络很清晰,符合需求分析中所作的程序流程图的规划。
以下就要分别对图形界面和后台进行编程了。
4.3图形界面的结构
现在程序有了一个窗口(window变量),但是,如果没有其他构件来提供有用的用户界面,它是没有什么用处的。
GTK+中的窗口是GtkBin的子类,它是一种只能包含一个子构件的容器对象。
这好像并不是特别有用,但GTK+还提供了各种可以容纳多个构件的GtkBin子类。
因此,GTK+中的窗口布局总是在一个GtkWindow中添加一个多构件容器来构成的。
这些容器中最有用的是GtkVBox、GtkHBox和GtkTable。
GtkVBox允许任意数量的构件垂直叠放。
GtkHBox的功能相同,但提供的是水平排列。
GtkTable是上述两者的结合,它允许构件在一个灵活的网格中进行排放。
[10]
这三种布局构件几乎提供了所有必要的布局功能。
需要注意的是,GTK+很少处理对象的绝对位置或大小——容器和其中的构件将调整大小以适应可用空间。
不过可以改变这类大小调整的一些约束以获得所需的效果,如果确实需要精确的像素布局,那么GtkFixed可作为最后的选择。
应该首先选择灵活的盒状模型布局(Box),因为它更容易使用。
最后,mp3播放器的最终效果如图4-1所示
图4-1播放器的最终效果
上图显示了在装载文件进行播放之前的音乐播放器窗口。
从上往下,依次是菜单栏,用于显示文件名的标签,五个控制播放的按钮,下面是显示播放经过时间的标签,最后是一个在当前文件中进行搜寻的滑动条。
整个图形界面的布局如图4-2所示
以上显示的是垂直盒子(vbox)及其内部控件的布局,gui()函数返回这个垂直盒子,正如在main函数中看到的那样,把这个垂直盒子放到了window窗口中,整个图形界面就完成了。
图4-2图形界面的布局
4.4PLAY按钮
关于构件盒子里的一个个控件的的方法,以“PLAY”按钮为例进行说明。
首先,先声明垂直盒子的变量:
GtkWidget*vbox;
其次,再创造按钮盒子变量:
GtkWidget*buttonbox;
再到PLAY按钮变量:
GtkWidget*playbutton;
分别为它们赋值:
vbox=gtk_vbox_new(FALSE,0);
buttonbox=gtk_hbox_new(FALSE,0);
playbutton=gtk_button_new_with_label("PLAY");
gtk_vbox_new参数的作用是调整构件在盒子中的摆放方式。
第一个参数指明组装盒中的构件是否都必须具有相同的高度,一个false值表示构件可能根据它们的需求有不同的高度。
第二个参数指明在构件之间的以像素为单位的间距,把它设置为0。
gtk_hbox_new中的参数与vbox中的类似。
gtk_button_new_with_label函数返回一个带有文字标签的按钮,本按钮上的文字是“PLAY”。
可是,单有“PLAY”标签并不能让这个按钮发出播放的命令,程序还要为它注册上信号处理函数,让它既有名又有实:
g_signal_connect(G_OBJECT(playbutton),"clicked",G_CALLBACK(play_pressed),NULL);
信号处理函数即play_pressed函数。
调用本函数完成信号向gtk_main()的注册,每次“click”鼠标来点击“playbutton”以后,gtk_main()会自动调用play_pressed函数。
g_signal_connect的第一个参数是要发出信号的构件,第二个参数是你想要连接的信号的名称,第三个参数是信号被捕获时所要调用的函数,第四个参数是你想传递给这个函数的数据。
由于不需要向play_pressed函数传数据,这里忽略了第四个参数。
G_OBJECT()和G_CALLBACK()都是宏,被定义为具有强制类型转换的功能。
程序把play_pressed的函数放到back.c文件中。
函数的功能调用链接GStreamer插件的函数,进行mp3文件的播放。
函数原型如下:
voidplay_pressed();
现在重新回到这个按钮上来。
程序刚刚为它添加了信号处理函数,但是,如何做到将按钮本身添加到面板上去呢?
这就需要逐级添加了,先把按钮添加到按钮盒里:
gtk_box_pack_start(GTK_BOX(buttonbox),playbutton,TRUE,TRUE,0);gtk_box_pack_start用于把组件添加到盒子里,添加组件的顺序决定了组件在盒子中的位置。
竖直盒子中,先添加的在上面,水平盒子中,先添加的在左边。
第一个参数是将组件塞入盒子的指针,这里是按钮盒。
第二个参数是要塞入的组件指针,即PLAY按钮。
第三个参数是布尔类型,用来控制组件与盒子之间的空间大小关系,其中TRUE表示允许组件扩展至分配给盒子的空间大小,FALSE表示盒子空间收缩至组件的实际大小。
第四个参数是用来控制是否将多余的空间分配给组件,即选择是否将组件扩展到盒子的大小(TRUE);还是多余的空间不变,保留作为盒子和打包组件间的间隔(FALSE),该参数只有在第三个参数取TRUE时才有效。
最后一个参数是指组件四周与盒子的间隔大小。
同样的,再把按钮盒放到垂直盒里:
gtk_box_pack_start(GTK_BOX(vbox),buttonbox,FALSE,TRUE,5);最后,全部把他们显示:
gtk_widget_show(playbutton);
gtk_widget_show(bu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux mp3 播放 实现