QT中的多媒体类phonon.docx
《QT中的多媒体类phonon.docx》由会员分享,可在线阅读,更多相关《QT中的多媒体类phonon.docx(13页珍藏版)》请在冰点文库上搜索。
QT中的多媒体类phonon
Qtphonon多媒体框架
Phonon是什么?
Qt从4.4版本开始提供的一套多媒体框架,提供多媒体回放的功能。
目前在Qt4.6中实现多媒体播放图形界面主要依赖于phonon框架,其实qt中还有一个Multimedia模块,帮助文档中对它的描述是:
实现底层的多媒体播放功能,在一般情况下上层的接口phonon模块更适合实现这些功能。
phonon最初是一个源于KDE的项目,为使用音频和视频的应用程序开发提供的一个框架。
应用程序不用去管多媒体播放是通过什么实现的(如gstreamer、xine),只需调用相应的接口就行,但这中间需要一个中转,被称为backend。
Qt也是通过phonon来实现夸平台的多媒体播放。
多媒体文件的播放主要过程包括:
文件读取、分流、解码、输出。
这些在不同的系统中实现方式不同,如windows下的DirectX、Linux下的gstreamer或xine及Mac下的QuickTime。
而Qt中的phonon作为夸平台的多媒体解决方案,就因该为用户屏蔽掉这些差异。
而实际上它做得还不够好,因为用户还需要自己来安装相应的后端插件来完成播放任务。
看完上图,你可以知道,应用Phonon框架实质上分4个部分,你的程序,Phonon库,Phonon后端插件(phonon_backend),真正的后端。
Phonon其实什么都不干,他只是提供了一套API接口,这套接口可以给你的程序调用,同时也是给编写后端插件提供一个规范。
程序完全不知道最后谁来放我的Mp3,谁来解码我的视频,播放的又是哪个设备。
同样,Phonon库也不知道,他只管搜索符合自己规范的插件。
并告诉这些插件,现在程序发出的指令是什么,从插件返回给程序现在的媒体状态和信息。
而后端才是实际进行读入媒体、解码并且播放的部分,他们和后端插件是一一对应的。
后端可以是任何形式,只要你写出了相应的后端插件。
所以,你要使用Phonon必需要先做3件事:
(1)编译你的Phonon库:
通常情况下,Qt默认没有编译,你只需要configure后加好参数,然后单独进入phonon的文件夹进行编译就可以了
(2)编译你的Phonon后端插件:
Qt为3大平台分别提供了一个可用的后端插件,放在src\plugins\phonon目录下。
进入目录编译即可,Qt会自动选择你当前系统的后端插件的。
(出现phononbackendplugincouldnotbeloaded就是这步没有做)
如果你是MinGW用户,那抱歉了,Windows下Qt只提供了DirectShow这个后端插件,而这个后端插件因为调用了DX的SDK,所以只能由VC编译。
当然你其实有更好的选择,比如这个phonon-vlc-mplayer插件,通过他,你可以将mplayer作为你的后端,彻底抛弃臃肿的VS以及读ID3v2都会出错的DirectShow(其实也不能怪DirectShow,DirectShow同样只是个框架,解码还靠系统里安的解码器、滤镜们,我用的播放器都太绿色了,于是DirectShow就很弱)
(3)你要保证你的后端正常运作:
对于Qt提供默认提供插件的后端来说,基本不成问题。
但要是你想做嵌入式播放器?
恩,很大的问题。
据做过GStreamer移植的人反映,这事恼火的很。
想做Qt嵌入式播放器的还是老老实实的QProcess+Mplayerslave模式吧!
(新的Qt4.5说是提供了CE上的DirectShow后端插件,有兴趣的可以去试试看)
以上3点做完,你就可以拿demo里那个mediaplayer去测试了,测试成功的话,你就可以非常容易的用Qt实现你自己的媒体回放了。
想要更高级的操作,比如编码、混音、储存媒体文件?
呵呵,等Phonon慢慢更新吧,现在来说,Phonon还只是个什么都不能干的传声筒。
如上所述,如果想要运行使用Qt中的phonon写的程序,需要满足一下条件:
Qt基本库、Qtphonon库、phonon_backend(后端插件)和多媒体播放后台。
下面以linux(Fedora12)系统、Qt4.6、mplayer为例,假设Qt基本库已经安装好,默认phonon是没有被安装的,介绍phonon和后端插件的安装。
1.Phonon库安装:
进入源代码的phonon目录,如"/usr/src/qt-everywhere-opensource-src-4.6.0/src/phonon",实际代码并不在里面,从phonon.pro文件可知源代码在“/src/3rdparty/phonon/phonon”,但并不影响编译。
在终端输入“make;makeinstall”即可,如果安装时出错,也可手动将lib、include下相关文件拷贝到安装目录。
2.后端插件安装:
(1)下载phonon-mplayer。
地址:
http:
//websvn.kde.org/trunk/playground/multimedia/phonon-backends/mplayer/
使用svn下载:
svncosvn:
//anonsvn.kde.org/home/kde/trunk/playground/multimedia/phonon-backends/mplayer
(2)返回phonon-mplayer目录,编译(qmake;make)生成phonon_backend/libphonon_mplayer.so动态链接库。
(3)将libphonon_mplayer.so拷贝到$QTDIR/plugins/phonon_backend/
说明:
帮助文档中介绍Linux下Qt默认只支持gstreamer,其它的不做保证。
但实际中由于mplayer安装比较方便,支持的文件格式全,使用的人也非常多,所以以mplayer为例。
而gstreamer的后端插件可以在系统的“/usr/lib64/kde4/plugins/phonon_backend”目录直接找到(如果已经从源上安装了的话)。
3.测试
examples/phonon/qmusicplayer下的例子用mplayer做后端播放音乐会有问题,这里选择使用demos/qmediaplayer。
当然也可以用一个简单的例子,如下:
#include
#include
#include
#include
intmain(intargv,char**args)
{
QApplicationapp(argv,args);
Phonon:
:
MediaObject*music=
Phonon:
:
createPlayer(Phonon:
:
MusicCategory,
Phonon:
:
MediaSource("/home/dlw/Music/mxshf.mp3"));
music->play();
/*视频播放
Phonon:
:
MediaObject*music=
Phonon:
:
createPlayer(Phonon:
:
VideoCategory,
Phonon:
:
MediaSource("/media/DLW/movie/One.Night.in.Supermarket.avi"));
music->play();
*/
returnapp.exec();
}
Qt4Phonon多媒体框架详解及简单实例
整体来说,Phonon的架构只需要记住以下的三东西:
∙mediaobjectPhonon的基础,用於管理多媒体来源。
来源可能是影音档等,而能够提供基本的播放控制,例如开始、暂停或结束。
而提供多媒体资料给mediaobject的则为mediasource,在给mediaobject之前通常是rawdata,再由mediaobject进行转换。
∙sinks输出多媒体,例如在widget上播放影片或是输出至音效卡(播放音乐)。
通常sink是一个播放的装置(例如音效卡等)。
而sink只接受mediaobject来的资料,由mediaobject控制播放;而由sink来处理这些多媒体
∙paths用来连接Phonon的物件,意即mediaobject与sink之间的连接。
可从下图看出彼此的关系
上图是一个有声视频avi文件的播放机制图。
媒体源DieHard.avi由MediaObject进行管理,而MediaObject与两个Sink通过Path连接,一个是AudioSink,管理着声音播放,另一个是VideoSink,管理着视频播放。
最终都是由Sink将媒体数据传送给物理设备。
所以整个播放影音的流程就是首先由mediaobject开始播放,接著把媒体串流经由path送至sink,sink会经由音效卡等装置重新播放(playback)影音。
【内部机制】
Phonon有三个基本概念:
媒体对象、接收端和路径。
一个媒体对象管理一个媒体源,比如一个音乐文件;它提供了简单的播放控制,比如开始、停止和暂停播放。
一个接收端输出来自Phonon的媒体,比如,通过提供录像到一个窗口,或者通过提供声音到一个声卡上。
路径是用来连接Phonon对象的,比如,一个媒体对象和一个接收端,从而构成了Phonon中的mediagraph,如下:
图1:
上图中,音乐的播放是由mediaobject启动和管理的,并且mediaobject把媒体流发送给通过路径(path)连接到它的接收端(sink),继而接收端(sink)通过声卡播放媒体流。
而与其他Qt应用程式一样,若有使用到Phonon函式库的应用程式在build的时候都需要额外设定使用Phonon模组,必须要在qmaekprojectfile(即.pro)中加入:
QT+=phonon
使用
在此部分将会开始介绍如何使用Phonon这套函式库,并且会列出一些小范例来demo,首先就先来介绍几个简单好用的类别。
VideoPlayerClass
Phonon有提供很多类别可供使用,其中最简单的,莫过於VideoPlayer这个类别了。
VideoPlayerwidget如它的名字一样,就是用来播放video,而且使用起来相当简易,而且功能也不会缺少,包括播放、暂停与停止。
而一开始早先提到的MediaObject等类别与VideoPlayer在使用上有什么差异呢?
如果不需要更复杂的功能,例如建立一个mediagraph,你只需要能够播放影音档案的话,其实使用VideoPlayer类别即可达到你的要求。
而另外值得一提的就是,VideoPlayer大部分函式都是非同步,所以载入mediasource并不会马上播放多媒体档案,只有在呼叫函式play()之後才会播放。
要怎么使用这个类别呢?
其实相当简单,下面就是程式码片段:
VideoPlayer*player=newVideoPlayer(Phonon:
:
VideoCategory,parentWidget);
player->play(url);
在实体化VideoPlayer类别物件时,可以在constructor就载入多媒体种类与要放在哪个widget中(即为parentWidget),而mediasource可以利用函式load()来载入或是在play()时载入,而载入方式可直接从档案或是从网路位址。
以下就是一个简单的影音播放功能小程式:
#include
#include
#include
#include
intmain(intargc,char*argv[])
{
QApplicationapp(argc,argv);
QWidget*widget=newQWidget;
widget->setWindowTitle("VideoPlayer");
widget->resize(400,400);
Phonon:
:
VideoPlayer*player=newPhonon:
:
VideoPlayer(Phonon:
:
VideoCategory,widget);
player->load(Phonon:
:
MediaSource("../Puppet.mpg"));
player->play();
widget->show();
returnapp.exec();
}
MediaObjectClass
MediaObject类别主要提供一个能够处理媒体播放的介面。
MediaObject可说是处理多媒体档案最基本的一部份,它接受并管理来自於MediaSource的媒体档案。
而媒体播放、暂停与停止都是由它来控制;而在此之前,media物件必须要与outputnode连接,如早先所讲的,这个nodes主要将媒体输出至底层的硬体,例如音效卡或显示卡等,而所需要的outputnode则是根据多媒体的内容而所不同,目前Phonon有两种outputnode;
∙AudioOutput-声音播放
∙VideoWidget-影像播放
如果MediaSource包含声音与影像的话,这两种node都必须要连接至media物件。
就这个类别来说,有几个函式是你必须要知道的,分别是
∙setCurrentSource():
设定MediaObject的多媒体来源,而来源可以是网路上的影音档(利用QUrl来存取)或是本机档案(利用QString),使用上相当简单:
QUrlurl(" //指定URL 这里我是乱写的URL
mediaObject->setCurrentSource(url);
∙play():
开始播放多媒体资料
∙pause():
暂停播放
∙stop():
停止播放
以下为一个简单的程式片段,说明如何使用:
Phonon:
:
MediaObject*mediaObject=newPhonon:
:
MediaObject(this);
Phonon:
:
VideoWidget*videoWidget=newPhonon:
:
VideoWidget(this);
Phonon:
:
createPath(mediaObject,videoWidget);
Phonon:
:
AudioOutput*audioOutput=newPhonon:
:
AudioOutput(Phonon:
:
VideoCategory,this);
Phonon:
:
createPath(mediaObject,audioOutput);
mediaObject->play();
Phonon:
:
createPath()
这是相当重要的一个函数,主要用於建立一个Path,连接两个MediaNodes,就是source与sink。
其实它的主要用途是在更进阶的部分,就是在使用到mediagraph,不过如果只是利用Phonon来播放多媒体影音档,其实只要记得它是用来连接source与输出装置即可。
AudioOutputClass
AudioOutput类别主要是用来把多媒体的声音送到声音输出装置。
所以它能够经由类似喇叭等输出装置来播放声音,稍早有提过,多媒体资料的来源必须要经过Phonon:
:
createPath()由MediaObject连接。
Phonon:
:
MediaObject*mediaObject=newPhonon:
:
MediaObject(this);
mediaObject->setCurrentSource(Phonon:
:
MediaSource("E:
/hello.mp3"));
Phonon:
:
AudioOutput*audioOutput=newPhonon:
:
AudioOutput(Phonon:
:
MusicCategory,this);
Phonon:
:
Pathpath=Phonon:
:
createPath(mediaObject,audioOutput);
VideoWidgetClass
VideoWidget类别提供能够显示出影片的widget,即视频的显示主窗口,没有VideoWidget则可能造成有声音无图像的情况。
VideoWidget类别会在QWidget上播放多媒体串流的影像,跟AudioOutput一样,必须使用Phonon:
:
createPath()来与MediaObject连接。
你可以利用一些函数来控制在QWidget中的VideoWidget显示的大小,你可以利用setAspectRatio()或setScaleMode()来控制,而它们接收的参数可以到网站上察看,使用方式如下(预设是使用aspectratio):
videowidget->setAspectRatio(Phonon:
:
VideoWidget:
:
AspectRatioAuto);
videowidget->setScaleMode(Phonon:
:
VideoWidget:
:
ScaleAndCrop);
当然也有提供函式让影片进入或退出全萤幕模式。
以下为一个简短的程式码范例:
MediaObject*mediaObject=newMediaObject(parent);
VideoWidget*vWidget=newVideoWidget(parent);Phonon:
:
createPath(mediaObeject,vWidget);
SeekSliderClass
SeekSlider类别提供一个可滑动的slider来设定多媒体串流播放的位置,即播放进度条,所以它会连接到MediaObject,并控制串流目前的位置。
以下是一个使用的范例:
Phonon:
:
MediaObject*mediaObject=newPhonon:
:
MediaObject;
Phonon:
:
AudioOutput*audioOutput=newPhonon:
:
AudioOutput;
Phonon:
:
createPath(mediaObject,audioOutput);
mediaObject->setCurrentSource(QString("E:
/hello.avi"));
Phonon:
:
SeekSlider*seekSlider=newPhonon:
:
SeekSlider;
seekSlider->setMediaObject(mediaObject); //与媒体对象mediaObject进行关联
seekSlider->show();
mediaObject->play();
VolumeSliderClass
VolumeSliderwidget提供可以控制声音装置音量的widget。
用法其实与上面的SeekSlider类似,使用范例如下:
Phonon:
:
AudioOutput*audioOutput=newPhonon:
:
AudioOutput(Phonon:
:
MusicCategory);
Phonon:
:
createPath(mediaObject,audioOutput);
Phonon:
:
VolumeSlider*volumeSlider=newPhonon:
:
VolumeSlider;
volumeSlider->setAudioOutput(audioOutput); //与音频输出设备进行关联
简单范例
再看过上面的一些类别介绍之後,其实就可以显一个简单的媒体播放器了,代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
intmain(intargc,char*argv[])
{
QApplicationapp(argc,argv);
QWidget*mainWidget=newQWidget;
mainWidget->setWindowTitle("MediaPlayer");
mainWidget->resize(640,480);
Phonon:
:
MediaObject*mediaObject=newPhonon:
:
MediaObject; //媒体对象
mediaObject->setCurrentSource(Phonon:
:
MediaSource("E:
/hello.avi"));
Phonon:
:
VideoWidget*videoWidget=newPhonon:
:
VideoWidget; //影像窗口
Phonon:
:
createPath(mediaObject,videoWidget);
videoWidget->setAspectRatio(Phonon:
:
VideoWidget:
:
AspectRatioAuto);
Phonon:
:
AudioOutput*audioOutput=newPhonon:
:
AudioOutput(Phonon:
:
VideoCategory); //音频输出
Phonon:
:
createPath(mediaObject,audioOutput);
QLabel*label=newQLabel("Volume:
");
Phonon:
:
VolumeSlider*volumeSlider=newPhonon:
:
VolumeSlider;
volumeSlider->setAudioOutput(audioOutput);
volumeSlider->setSizePolicy(QSizePolicy:
:
Maximum,QSizePolicy:
:
Maximum);
Phonon:
:
SeekSlider*seekSlider=newPhonon:
:
See