一种嵌入式Linux系统的多媒体播放器设计

2018-05-17 10:38石昊苏董欢张曼
电子设计工程 2018年9期
关键词:字幕音频部件

石昊苏,董欢,张曼

(西北政法大学商学院,陕西西安710063)

随着计算机多媒体技术和网络技术的飞速发展,“嵌入式”已经成为计算机领域诸多研究者密切关注的学术方向,在支持嵌入式硬件平台的主流操作系统中,Linux因出于自身的优越而成为嵌入式开发的最佳选择[1-2]。同时越来越多的用户对多媒体播放器也提出更高的要求,由最初的支持更多类型的音频、视频,即实现“能”播放,到对音质保真、画面清晰,再到对播放器本身系统资源占用、加载启动速度的追求等,使得多媒体播放器的设计者必需不断改进完善、追求完美。当前网络可供下载的多媒体播放器软件品种繁多、功能齐全,但是普遍性存在捆绑插件、加载速度慢等不足,甚或界面使用不便。因此在嵌入式Linux系统上开发一款克服上述缺点的多媒体播放器已经成为必需,不仅满足基本视听需要,而且功能实用、操作方便、加载速度快、占用资源少、移植性强等[3-4],这应该具有很好的应用前景及价值。

1 基于Linux下多媒体播放器的整体架构

1.1 系统的工作流程

Linux下多媒体播放器的整体工作流程:用户通过图形界面控制,添加媒体文件(音频或视频)到播放列表,软件自动关联媒体源(媒体文件)与媒体对象,然后建立媒体对象和音频汇点(虚拟渲染设备)/视频汇点的连接。开始播放后,汇点将音频和视频分流处理到系统后端解码插件,解码处理后,Phonon的后端对音频和视频进行同步处理。最终,音频通过连接在计算机的默认声卡输出,视频画面渲染到播放器界面对应部件上。这样,就完成了一个媒体文件从加载到完成播放的整个流程[5-8]。

1.2 多媒体播放器文件加载

多媒体播放器中,用户可以添加一个或多个媒体文件到播放列表。程序对所有被添加的文件遍历处理,检查每个文件的合法性,然后将所有的有效媒体源保存在一个媒体源队列中,并显示在播放器列表中。添加成功后,用户可以选择对播放列表中的某个媒体文件进行播放、暂停、停止、上一个、下一个、音量调节、拖动进度条播放等基本播放控制[9]。

1.3 多媒体播放器音频播放功能

音频文件在开始播放时,媒体解析器自动在媒体文件同级目录下加载字幕文件,解析后保存到内存中[10]。中央屏幕的字幕是固定显示的,用户可以选择是否显示桌面字幕。多媒体播放器的音频播放功能模块如图2所示。

图2 音频播放功能模块

1.4 多媒体播放器视频播放功能

针对视频媒体,可以调整视频画面的宽高比以及视频画面的色彩模式(色调、对比度、亮度等),可以全屏播放,支持屏幕截图。

视频播放功能模块如图3所示。

图3 视频播放功能模块

2 多媒体播放器的详细设计

2.1 解码库模块

Phonon多媒体框架从本地读入媒体源,传输至后端插件解码,最后输出到声卡和负责渲染视频画面的部件。从逻辑上来说,它可以分为4部分:在Phonon库支持下编写的应用程序、Phonon库(由逻辑路径相连接的媒体对象和汇点)、Phonon的后端插件、系统的后端插件[11-12]。

Phonon的API被前台程序所调用,它不需要知道自己输入的媒体流由哪套程序去解码,最后在哪个设备上去播放。它只需要将对媒体流的指定操作发送给后端,最后由后端实现并回馈给Phonon,从而实现目的。因此,实现多媒体播放,Phonon后端和系统的解码后端二者缺一不可。Phonon后端的准备:编译QT库中的的phonon库文件生成后端链接库文件,复制到开发路径调用。系统后端的准备:Linux下安装phonon-backend-gstreamer,采用GStreamer作为系统后端。

2.2 播放器界面设计

多媒体播放器的主界面包括窗口图标、菜单栏、PushButton按钮、Widget部件 QListWidget列表、进度条等。使用水平布局管理器和垂直布局管理器,以便在编写代码时对界面上每个部件进行固定的布局管理,自动控制部件的大小变化。在显示/隐藏播放列表、全屏播放等操作中,对每个部件的大小位置进行整体调整,以适应界面的美观性和体验感[13]。

在多媒体播放器的主界面类MPlayer中,实例化了一个ui类的堆对象,主界面所有部件的图标、大小、信号关联、styleSheet等属性都在代码中通过这个指针去访问对应部件进行控制。

播放进度条部件通过Phonon::SeekSlider::setMediaObject()函数初始化,关联到专门用于播放的Phonon::MediaObject媒体对象中,使得可以通过该滑块来对媒体对象进行控制。媒体对象在播放过程中,也会通过向滑块发射信号达到同步显示的效果。在每个媒体源播放即将结束时,Phonon会自动发射结束信号,滑块通过Phonon::MediaObject::seek()函数,将显示值设置为当前媒体的总时间。

声音控制滑块通过Phonon::VolumeSlider::setAutioOutput()函数与音频输出节点Phonon::AudioOutput相关联,通过移动滑块对音频输入对象进行控制,从而实现了音量高低的调整。滑块值每次发生变化时,会发射volumeChanged信号,信号参数中携带了变化后的值。通过关联这个信号,在对应的槽中设置每次音量变化时,实时在播放界面用QLabel部件显示出当前音量的百分比值。

2.3 媒体流图的实现

多媒体播放器实现播放媒体文件,需要创建Phonon媒体流图来实现。本地媒体文件的源数据是一个媒体源,Phonon中有一个MediaObjects类用来实现媒体对象。媒体源要实现播放,需要和专门负责播放任务的媒体对象绑定在一起。汇点相当于Phonon中的一个虚拟节点,它的功能是从媒体对象获取媒体流数据,通过后端解码、同步处理后,输送到声卡或者视频渲染部件中。创建一个媒体流图,就是分别创建媒体对象和汇点(音频汇点和视频汇点)的实例,通过Phonon::createPath()函数创建一条虚拟的路径,将二者连接起来[3,12]。

图4 视频媒体流图

音频媒体流相对来说比较简单,只需要建立媒体对象和音频汇点之间的一条路径。后端对媒体流解析后由音频节点直接输送到系统的默认音频设备,即声卡中实现声音播放。而视频媒体流需要建立两条虚拟路径,如图4所示,分别是媒体对象和音频汇点的连接和媒体对象和视频汇点的连接。前者与音频媒体流图的处理原理完全一致,后者通过解码、处理后的视频画面通过Phonon::VideoWidget类的部件对象在主界面上进行渲染。因为VideoWidget类是继承自QT的Widget部件类,它可以像普通的Widget部件一样,设置大小、背景等属性。

2.4 播放列表的实现

播放器的播放列表主要实现文件添加、从播放列表删除、清空播放列表、从播放列表控制播放、循环模式等功能。

为了降低系统模块之间的耦合性,播放列表采用单独的类(PlayerList)进行设计,该类继承自QListWidget部件类。QListWidget中的数据采用列表的数据结构保存条目的索引和数据(字符串)。为了方便显示,在播放列表类中,设置了条目的内容或数量超出控件的默认长度时,自动使用水平和垂直滚动条。播放列表中的所有功能通过关联部件的customContextMenuRequested(const QPoint&)信号,创建上下文菜单实现[14-15]。

添加文件:将文件打开对话框中选择的媒体源路径保存在字符串列表中。对这个字符串列表进行解析,为每个媒体文件创建媒体源,保存到媒体源列表中。解析每个媒体源的合法性,使用媒体对象的metaData()、totalTime()函数获取媒体源的文件名和总时长,作为播放列表的条目值。只有将前一个媒体源加入播放列表后,才开始后一个媒体文件的解析。通过这样的加载方式,媒体源列表和播放列表相互对应,方便后续播放处理。

从播放列表删除:要删除的媒体是在播放列表中被选中的条目,currentRow()函数可以获取正在选中条目的索引值,它和对应媒体源在媒体源列表中的索引值完全一致。文件加入播放列表后,删除前不会对两个列表中的数据进行任何操作。通过QListWidget::takeItem()和 QList::removeAt()函数分别将对应媒体从播放列表和媒体源列表中删除。QT中的列表结构会在删除某节点后,动态地调整后续节点。删除成功后,如果播放列表没有被清空,优先设置后一个媒体源为当期媒体源。

清空播放列表:由于播放列表和媒体源列表之间的同步管理关系,在清空播放列表时,需要使用两个对象的clear()函数同时清空两个列表。停止当前正在播放/暂停的媒体,断开媒体对象和所有媒体源的连接。

循环模式:利用全局的枚举对象,保存顺序播放、列表循环、随机播放、单个播放、单个循环模式状态。设计一个播放模式控制函数playerMode(),判断当前设置的模式(默认为顺序播放)。在与媒体对象结束信号相关联的槽函数中,设置当前模式下的下一个媒体源为当前媒体源,开始播放。

2.5 媒体字幕的实现

多媒体播放器的字幕显示,是针对于播放MP3类的音乐文件时,匹配本地下载好的歌词文件,进行解析处理。在播放过程中,根据播放时间动态地显示出对应字幕内容。多媒体播放器的字幕实现主要分为3个模块:字幕文件解析、桌面字幕显示、播放器界面中央字幕显示。

字幕文件解析。目前常用歌曲字幕文件是LRC格式的文本文件,字幕文件内容主要分为两种类型。一种是文件主要标识,包括歌曲名、歌手名等信息。另一种是歌曲的歌词,是时间(分:秒:毫秒)和歌词的数据对。按照这样的规律,对LRC格式的字幕文件的解析,只需要用一个合适的数据结构来保存(时间,字幕内容)数据对,而且时间不可重复[16]。

设计字幕解析函数myResolve(const QString&),在每次音频媒体文件开始播放时,获取播放媒体文件路径,调用解析函数。因为字幕文件和媒体文件的文件名相同,所以首先将文件路径的后缀修改为lrc后,开始寻找指定字幕文件。找到字幕文件后,使用QFile和QStringlist对象读出文件所有内容过后,按行进行解析。

使用设置更新播放时间的槽函数中来完成对QMap对象中字幕键值对的匹配,可以根据播放时间动态显示对应字幕的效果,实现字幕的单行显示。

播放器界面中央字幕显示。中央字幕显示在播放器显示视频画面的部件位置上层,在这个部件上层覆盖一个QListWidget部件,控制该部件条目数量为十个。在解析字幕完成时,一次性从QMap对象中读取十条数据,并使用全局迭代器记录读取位置。之后,在更新播放时间显示槽中,每次有字幕更新时,动态地将需要更新的一行字幕加入到中央字幕部件尾部,同时删除掉首行字幕,保证了屏幕中字幕的显示为固定十行。为了显示出字幕的动态效果,将播放时间对应的字幕条目设置为绿色(其余字幕为白色)。

图5 播放主界面中央字幕显示

图6 视频画面色彩调节后效果图

3 结束语

经实验测试(如图5、6所示),该播放器可播放当前绝大多数的主流多媒体文件类型,基本功能均已实现达到预期的目的。该设计具有存储空间小,速度快,功能简单,移植性良好等特点,可以供媒体播放器开发设计者的参考。不足之处暂时没有添加WiFi功能模块,这将在进一步解码器优化、支持高清视频H.264的播放时一并改进。

参考文献:

[1]武颖.基于Linux的嵌入式多媒体播放器的设计与实现[D].太原:中北大学,2013.

[2]赵宏,尹磊,曹洁,等.多媒体终端的设计与实现[J].科学技术与工程,2010,10(22):5420-5424.

[3]马晓敏.多媒体播放器的设计与开发[J].电子世界,2013,37(18):126.

[4]王洪斌.基于嵌入式Linux的多媒体系统研究与设计[D].哈尔滨:哈尔滨理工大学,2016.

[5]郑戊午,徐炜强.基于Xscale的掌上多媒体播放器设计[J].电子技术,2016,45(3):87-89.

[6]杨博,李可生,何书专,等.基于i.MX6的LED异步控制系统软件设计[J].计算机工程与设计,2016,37(6):1478-1484.

[7]胡国强,周兆永,信朝霞.基于SRS的开源直播系统的设计与实现[J].现代电子技术,2016,39(16):36-39.

[8]李毅航.流程图化的嵌入式系统开发平台[J].单片机与嵌入式系统应用,2017(2):15-17.

[9]潘文睿.基于Android系统多媒体播放器的设计与实现[D].西安:西北大学,2014.

[10]李飞,吴鸿江.河南电视台新数字播出系统亮点解析[J].广播与电视技术,2013,40(7):71-72..

[11]朱兆祺,李强,袁晋蓉.嵌入式Linux开发实用教程[M].北京:人民邮电出版社,2014.

[12]溪利亚,程殊,王侣为.基于Phonon的多媒体播放器的设计与实现[J].科学技术与工程,2011,11(29):7283-7285.

[13]张增虎.基于Qt的嵌入式多媒体播放终端的设计与实现[D].太原:中北大学,2014.

[14]孙熠,史剑,安辉耀,等.一种轻型高效的多媒体播放列表解决方案[J].计算机技术与发展,2014(3):1-5.

[15]张正政,林耀荣.基于Android系统的影音播放器开发[J].现代电子技术,2011,34(2):5-8.

[16]肖梦华,刘新,叶德建.一种基于嵌入式流媒体视频播放器的多字幕组件设计[J].计算机应用与软件,2014(3):139-141.

猜你喜欢
字幕音频部件
必须了解的音频基础知识 家庭影院入门攻略:音频认证与推荐标准篇
基于Daubechies(dbN)的飞行器音频特征提取
基于Siemens NX和Sinumerik的铣头部件再制造
部件拆分与对外汉字部件教学
音频分析仪中低失真音频信号的发生方法
一种基于单片机16×32点阵动态字幕的设计
整合适应选择度下的动画电影字幕翻译——以《冰河世纪》的字幕汉译为例
水轮机过流部件改造与节能增效
Pro Tools音频剪辑及修正
论纪录片的字幕翻译策略