مقدمة: فونون phonon هي عبارة عن Multimedia API لتشغيل ملفات الصوت والفيديو . هذا المشروع طور في الاساس لسطح المكتب 4 KDE بهدف عمل واجهة بسيطة Simple Interface لتطوير تطبيقات الـ Multimedia بدلا من الحلول المعقدة قبلها .ومن مميزاتها الرئيسية هي انها مفصولة تماما عن أي محرك صوتيات Multimedia Framework/Server مثل GStreamer,Xine,VLC...etc وتستطيع استخدامها مع اي محرك في حالة توفر plugin له. بداية مشروع phonon كانت بالاعتماد على محرك xine في تشغيل ملفات الصوت و الفيديو ، الى أن تدخلت TT "حاليا qtsoftware" وقامت باضافة عدة plugin بحيث أصبحت phonon أيضا تدعم GStreamer على اللينوكس " ، و DirectShow في ويندوز و QT" QuikTime" في OS X . اذا ياختصار phonon هي دوال فقط او front-end، ولا تعمل بدون محركات الصوت back-end ، فوظيفتها فقط هي توفير واجهة موحدة لتشغيل الملتميديا . وفي +Qt 4.4 قامت qtsoftware باستخدام phonon كموديل ،وبهكذا أصبح بالامكان تطوير تطبيقات لتشغيل ملفات الصوت والفيديو بشكل متعدد المنصات Cross Platform ،بدلا من اللجوء الى اي مكتبات خارجية External Libs ، لكن لن تستطيع سوى استخدام المحركات التي قامت qtsoftware بدعمها في Qt ، لذلك يجب توفر المحركات/البرامج الاتية لكي تعمل معك phonon بشكل صحيح : في اللينوكس يجب توفر GStreamer اما في الويندوز يجب توفر DirectShow وفي ماك OS X يجب توفر QuikTime تنصيب phonon على ويندوز يجب تحميل Dx و DirectShow 9 بالاضافة الى SDK لويندوز. وأيضا يجب توفر فيجوال سي++. وهذه روابط تشرح كيفية التنصيب : http://www.matthiaspospiech.de/blog/2008/0...der-windows-xp/ http://wiki.qtcentre.org/index.php?title=B...ows_using_MinGW التنصيب على لينوكس : قم بفتح مدير الحزم وحمل gstreamer اولا ثم قم بتحميل الباكج التالية : phonon libphonon4 phonon-devel phonon-backend-gstreamer فقط من دون الحاجة الى اعادة ترجمة كيوت ! الشكل العام ل phonon : تتكون phonon من ثلاث مفاهيم أساسية وهي media objects, sinks, and paths . ال media object هي الفئة التي تتعامل مع ملفات الصوت والفيديو وتقوم بالتحكم فيها starting, stopping, and pausing اما ال sinks فهي الفئات المتخصة باخراج الصوت او الفيديو الى كرت الصوت او الشاشة. اخيرا ال path يمثل الفئة التي تربط بين ال media objects و ال sinks ، بحيث يقوم ال media object بارسال ال media stream الى اي sink مرتبط به عبر path معين وبعدها يقوم ال sink بارسال هذا ال stream الى كرت الصوت او الشاشة. ملاحظات: +فئات ودوال phonon معرفة في مساحة الاسماء Phonon لذلك ستجد قبل كل فئة او دالة اسم مساحة الاسماء Phonon::XXX. +في ملف المشروع يجب إضافة : QT += phonon. كيفية استخدام phonon : يوجد طريقتين تستطيع بها تشغيل ملفات الصوت والفيديو في phonon ، الطريقة الاولى وهي بسيطة جدا ولا تتطلب انشاء العناصر الثلاثة السابقة ، فقط عليك ان تقوم باستدعاء الدالة Phonon::createPlayer مع تمرير الملف المراد تشغيله ومن ثم استدعاء الدالة play . مثال لتشغيل ملف صوت:
Phonon::MediaObject* audioPlayer = Phonon::createPlayer(Phonon::MusicCategory,Phonon::MediaSource("sound.mp3"));audioPlayer->play();
Phonon::VideoPlayer* videoPlayer = new Phonon::VideoPlayer(Phonon::VideoCategory,this);videoPlayer->play(Phonon::MediaSource("sound.mp3"));
Phonon::MediaObject* player=new Phonon::MediaObject(parent);player->setCurrentSource(Phonon::MediaSource("/home/audio.mp3"));Phonon::AudioOutput* audioOutput=new Phonon::AudioOutput(parent);Phonon::createPath(player,audioOutput);player->play();
Phonon::MediaObject* player=new Phonon::MediaObject(parent);player->setCurrentSource(Phonon::MediaSource("/home/video.mpg"));Phonon::VideoWidget* videoWidget=new Phonon::VideoWidget(parent);Phonon::createPath(player,videoWidget);player->play();
Phonon::MediaObject* player=new Phonon::MediaObject(parent);player->setCurrentSource(Phonon::MediaSource("/home/video.mpg"));Phonon::AudioOutput* audioOutput=new Phonon::AudioOutput(parent);Phonon::createPath(player,audioOutput);Phonon::VideoWidget* videoWidget=new Phonon::VideoWidget(parent);Phonon::createPath(player,videoWidget);player->play();
Phonon::MediaObject* player=new Phonon::MediaObject(parent);player->setCurrentSource(Phonon::MediaSource("/home/audio.mp3"));Phonon::AudioOutput* audioOutput=new Phonon::AudioOutput(parent);Phonon::createPath(player,audioOutput);Phonon::SeekSlider *slider = new Phonon::SeekSlider;slider->setMediaObject(player);slider->show();player->play();
Phonon::VolumeSlider *volumeSlider = new Phonon::VolumeSlider;volumeSlider->setAudioOutput(audioOutput);//...etcvolumeSlider->show();
Phonon::Effect *effect =new Phonon::Effect(Phonon::BackendCapabilities::availableAudioEffects()[0], this);path.insertEffect(effect);
Phonon::EffectWidget *effectWidget = new Phonon::EffectWidget(effect);effectWidget->show();
QPlayer::QPlayer(QWidget* parent):QWidget(parent){ player = new Phonon::MediaObject(this); audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory,this); videoWidget = new Phonon::VideoWidget(this); createPath(player,audioOutput); createPath(player,videoWidget); player->setTickInterval(1000); connect(player,SIGNAL(tick(qint64)),this,SLOT(tick(qint64))); setupUi(); setWindowTitle(tr("QPlayer v0.1")); setWindowIcon(QIcon(":/images/qplayer.png"));}
void QPlayer::setupUi(){ seekSlider = new Phonon::SeekSlider(player,this); volumeSlider = new Phonon::VolumeSlider(audioOutput,this); QLabel* fileLable=new QLabel(tr("&File Name:")); fileEdit=new QLineEdit; fileLable->setBuddy(fileEdit); lcdTimer = new QLCDNumber; lcdTimer->display("00:00"); QPushButton* browseButton=new QPushButton(tr("&Browse")); playButton=new QPushButton(tr("&Play")); QPushButton* pauseButton=new QPushButton(tr("P&ause")); QPushButton* stopButton=new QPushButton(tr("&Stop")); playButton->setIcon(QIcon(":/images/play.png")); pauseButton->setIcon(QIcon(":/images/pause.png")); stopButton->setIcon(QIcon(":/images/stop.png")); browseButton->setIcon(QIcon(":/images/folder-music.png")); playButton->setEnabled(false); connect(browseButton,SIGNAL(clicked()),this,SLOT(browseClicked())); connect(playButton,SIGNAL(clicked()),this,SLOT(playClicked())); connect(pauseButton,SIGNAL(clicked()),this,SLOT(pauseClicked())); connect(stopButton,SIGNAL(clicked()),this,SLOT(stopClicked())); connect(fileEdit,SIGNAL(textChanged(const QString&)),this,SLOT(checkFileName(const QString&))); QHBoxLayout* upperLayout=new QHBoxLayout; upperLayout->addWidget(fileLable); upperLayout->addWidget(fileEdit); upperLayout->addWidget(browseButton); QHBoxLayout* midLayout=new QHBoxLayout; midLayout->addWidget(seekSlider); midLayout->addWidget(lcdTimer); QHBoxLayout* lowerLayout=new QHBoxLayout; lowerLayout->addWidget(playButton); lowerLayout->addWidget(pauseButton); lowerLayout->addWidget(stopButton); lowerLayout->addWidget(volumeSlider); QVBoxLayout* layout=new QVBoxLayout(this); layout->addLayout(upperLayout); layout->addWidget(videoWidget); layout->addLayout(midLayout); layout->addLayout(lowerLayout); lcdTimer->setSizePolicy(QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed)); seekSlider->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed)); volumeSlider->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed));}void QPlayer::tick(qint64 time){ QTime displayTime(0,(time/60000)%60,(time/1000)%60); lcdTimer->display(displayTime.toString("mm:ss"));}void QPlayer::playClicked(){ player->setCurrentSource(fileEdit->text()); player->play();}void QPlayer::pauseClicked(){ player->pause();}void QPlayer::stopClicked(){ player->stop(); lcdTimer->display("00:00");}void QPlayer::browseClicked(){ QString fileName = QFileDialog::getOpenFileName(this); if ( !fileName.isEmpty() ) fileEdit->setText(fileName);}void QPlayer::checkFileName(const QString& str){ if( !str.isEmpty() ) playButton->setEnabled(true); elseplayButton->setEnabled(false);}