基于QT前端的Mplayer播放器項目之PC環(huán)境下的實現(xiàn)過程
一、PC環(huán)境搭建
主機環(huán)境:Red Hat Enterprise Linux 5.0
交叉編譯工具:gcc-3.4.5-glibc-2.3.6
主機編譯工具:gcc-4.1.2
1、主機端安裝mplayer
將“項目代碼/mplay源碼”目錄下的MPlayer-1.0rc2.tar.bz2、libmad-0.15.1b.tar.gz(1個mp3解碼庫)拷貝到linux系統(tǒng)中,如:/home/linux/mplayer目錄下
安裝libmad-0.15.1b.tar.gz
- #tar xvfz libmad-0.15.1b.tar.gz
 - #cd libmad-0.15.1b
 - #./configure
 - #make
 - #mkdir /lib/lib
 - #mkdir /lib/include
 - #cp mad.h /lib/include
 - #cp .libs/libmad.a /lib/lib
 - l 安裝mplayer
 - #tar xvfj MPlayer-1.0.rc2.tar.bz2
 - #cd MPlayer-1.0rc2
 - #./configure --with-extraincdir=/lib/include --with-extralibdir=/lib/lib
 - #make
 - #make install
 
此時可以試著播放一下mp3、avi等文件了
- # mplayer -ac mad 1.mp3
 - # mplayer -ac mad 2.avi
 
2、安裝、移植qtopia-4.2.0
注:需要先按照5.2節(jié)將tslib按照好,將“項目代碼/qtopia源碼”目錄下的qtopia-opensource-src-4.2.0.tar.gz拷貝到linux系統(tǒng)中,如:/home/linux/Qtopia目錄下
- # tar zxvf qtopia-opensource-src-4.2.0.tar.gz
 - # mv qtopia-opensource-4.2.0 source
 - # mkdir target //創(chuàng)建在source同級目錄下創(chuàng)建目錄target
 
修改源碼包
- # cd source
 - # cd src/libraries/qtopiabase/
 - # cp custom-linux-cassiopeia-g++.h custom-linux-arm-g++.h
 - # cp custom-linux-cassiopeia-g++.cpp custom-linux-arm-g++.cpp
 
修改時區(qū)信息
- # vi src/libraries/qtopia/qtimezone.cpp
 - 將114行的 /usr/share/zoneinfo/ 改為/Qtipia/zoneinfo/ ,保存退出。
 - # vi src/settings/systemtime/settime.cpp
 - 將318行的 /usr/share/zoneinfo/ 改為/Qtipia/zoneinfo/ ,保存退出。
 
裁減Qtopia core的庫(下列操作后在屏幕上會出現(xiàn)一個光標,否則沒有光標。根據(jù)需求配置)
- # vi qtopiacore/qconfig-qpe.h
 
首先注釋掉關于鼠標光標的宏定義,讓程序運行時,觸摸屏中央有光標出現(xiàn):
- // Qtopia Core
 - /*
 - #ifndef QT_NO_QWS_CURSOR
 - # define QT_NO_QWS_CURSOR
 - #endif
 - */
 - /*
 - #ifndef QT_NO_QWS_MOUSE
 - # define QT_NO_QWS_MOUSE
 - #endif
 - #ifndef QT_NO_QWS_MOUSE_AUTO
 - # define QT_NO_QWS_MOUSE_AUTO
 - #endif
 - */
 
其它宏定義根據(jù)需要進行注釋。
#p#
保存后將qconfig-qpe.h拷貝到global目錄。
- # cp qtopiacore/qconfig-qpe.h qtopiacore/qt/src/corelib/global/qconfig-qpe.h (必須進行的操作)
 
注釋掉其他文件里的QT_NO_QWS_CURSOR的定義
- # vi qtopiacore/qt/src/corelib/global/qfeatures.h
 
注釋掉如下內(nèi)容:
- /*
 - #if !defined(QT_NO_QWS_CURSOR) && (defined(QT_NO_CURSOR))
 - #define QT_NO_QWS_CURSOR
 - #endif
 - */
 
保存退出。
- # vi qtopiacore/qt/src/corelib/global/qglobal.h
 
注釋掉以下內(nèi)容:
- //# define QT_NO_QWS_CURSOR
 - #vim qtopiacore/qt/tools/qvfb/qvfbshmem.cpp
 
注釋掉asm/page.h
- //#include <asm/page.h>
 - #vim qtopiacore/qt/tools/qvfb/qvfbmmap.cpp
 
注釋掉asm/page.h
- //#include <asm/page.h>
 
并修改如下內(nèi)容
- unsigned char *data;
 - uint data_offset_value = sizeof(QVFbHeader);
 - if (data_offset_value % PAGE_SIZE)
 - data_offset_value += PAGE_SIZE - (data_offset_value % PAGE_SIZE);
 
為:
- unsigned char *data;
 - uint data_offset_value = sizeof(QVFbHeader);
 - const int page_size = getpagesize();
 - if (data_offset_value % page_size)
 - data_offset_value += page_size - (data_offset_value % page_size);
 - # vim src/libraries/qtopiabase/qmemoryfile_unix.cpp +128
 
修改:
- f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY);
 
為:
- f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY ,0777);
 
修改交叉工具
- #vim qtopiacore/qt/mkspecs/qws/linux-arm-g++/qmake.conf
 
將文件中的arm-linux-***全部修改為arm-softfloat-linux-gnu-**
這樣做的前提是我的交叉工具鏈是arm-softfloat-linux-gnu,如果你的是arm-linux就不用改了。
#p#
生成Makefile
#cd ../target //為了不破壞源碼,選擇在此目錄下配置、編譯源碼
- #../source/configure -release -image /Qtopia -prefix /Qtopia -xplatform linux-arm-g++
 - -arch arm -no-qvfb -displaysize 320x240 -no-modem -extra-qtopiacore-config "-release
 - -xplatform qws/linux-arm-g++ -embedded arm -qconfig qpe -depths 4,8,16,32
 - -qt-sql-sqlite -no-mouse-linuxtp -qt-mouse-tslib -I/home/linux/tslib/include
 - -L/home/linux/tslib/lib " 2>../configureERR.txt
 
注意:這里/Qtopia是***Qtopia的安裝路徑,安裝到主機的某個路徑下,最終這個路徑和目標板上的路徑必須一致。
主要配置選項說明如下:
- -xplatform linux-arm-g++ -arch arm
 
目標平臺為arm-linux,體系結(jié)構(gòu)為arm。
- -no-qvfb
 
目標平臺已支持framebuffer,因而不使用虛擬幀緩沖。
- -extra-qtopiacore-config
 
為Qtopia core 配置選項。
- -xplatform qws/linux-arm-g++ -embedded arm
 
目標平臺編譯配置文件使用qtopiacore/qt/mkspecs/qws/linux-arm-g++目錄下的配置文件,嵌入式平臺為arm。
- -qconfig qpe
 
使用配置文件qconfig-qpe.h,若使用qconfig-large.h配置文件,則使用-qconfig large選項。
- -qt-sql-sqlite
 
數(shù)據(jù)庫支持Sqlite。
- -qt-kbd-usb
 
鍵盤支持usb協(xié)議。
- -no-mouse-linuxtp -qt-mouse-tslib
 - -I/home/linux/tslib/include -L/home/linux/tslib/lib
 
觸摸屏協(xié)議不支持linuxtp,支持tslib,并在后面添加上剛才編譯的tslib的頭文件和庫。
- ../qtopiaconfigureERR.txt
 
***將配置過程中的錯誤輸出到qtopiaconfigureERR.txt文件中。
編譯
- #make
 - #make install
 
將安裝和的目錄考到nfsroot目錄下
- #cp /Qtopia /rootfs -a
 
3、熟悉主機開發(fā)環(huán)境
提供給PC端的開發(fā)工具
上面的qtopia編譯安裝完成后,會在咱們前面創(chuàng)建的target目錄下生成很多開發(fā)工具。
先看一下供主機端使用的工具
- [root@localhost bin]# pwd
 - /home/linux/Qtopia/target/qtopiacore/host/bin
 - [root@localhost bin]# ls
 - assistant linguist lupdate qmake rcc uic
 - designer lrelease moc qvfb templates uic3
 
如果系統(tǒng)以前有其它qt開發(fā)工具,把環(huán)境變量修改一下,保證它們不要和我們這幾個工具沖突。下面可以試一下你的designer了。
- #./designer
 
二、在PC端實現(xiàn)基于qt前端的mplayer播放器
創(chuàng)建工程目錄/home/linux/mplayer
1、搭建ui界面
利用前面安裝的designer搭建ui界面,并將其保存至/home/linux/mplayer/mplayer.ui
- #./designer
 
圓角矩形標注: 加了一個widget,留作mplayer的播放區(qū)
2、編寫程序
在/home/linux/mymplayer/下創(chuàng)建mplayer.cpp、mplayer.h、main.cpp 、image.qrc
Main.cpp
- #include <QApplication>
 - #include "mplayer.h"
 - int main(int argc, char **argv)
 - {
 - QApplication app(argc, argv);
 - MPlayer player; //實例最終的MPlayer類
 - player.show(); //顯示界面
 - return app.exec(); //運行程序
 - }
 - mplayer.h
 - #ifndef _MPLAYER_H
 - #define _MPLAYER_H
 - #include <QIcon>
 - #include <QProcess>
 - #include <QTimer>
 - #include <QStringList>
 - #include <QDir>
 - #include <QTime>
 - #include <QString>
 - #include "ui_mplayer.h"
 - class MPlayer:public QDialog,private Ui_Dialog
 - {
 - Q_OBJECT
 - public:
 - MPlayer(QWidget *parent = 0);
 - public:
 - QTime int_to_time(int);
 - public slots:
 - void play_pause_slots(); //暫停
 - void stop_slots(); //停止
 - void previous_slots(); //上一曲
 - void next_slots(); //下一曲
 - void seek_slots(int);
 - void get_time_slots(); //得到播放時間
 - void set_volume_slots(int); //設置音量
 - void set_sound_slots(); //靜音
 - void playerReward_slots(); //快退
 - void playerForward_slots(); //快進
 - void back_message_slots(); //更新顯示信息
 - private:
 - QProcess *process;
 - QStringList files;
 - QDir directory;
 - int file_count;
 - QString file_name;
 - bool isPlay;
 - bool isSound;
 - bool isStop;
 - QTimer *timer;
 - int file_length;
 - int curr_time;
 - };
 - #endif
 
#p#
mplayer.cpp
- #include "mplayer.h"
 - #include <QDebug>
 - #include <unistd.h>
 - MPlayer::MPlayer(QWidget *parent):QDialog(parent)
 - {
 - setupUi(this); //初始化界面
 - isPlay = true;
 - isSound = true;
 - isStop = false;
 - /************************為按鍵添加圖標**************************/
 - //play
 - QIcon icon_play;
 - icon_play.addPixmap(QPixmap(QString::fromUtf8("images/pause_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_2->setIcon(icon_play);
 - //stop
 - QIcon icon_stop;
 - icon_stop.addPixmap(QPixmap(QString::fromUtf8("images/stop_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_3->setIcon(icon_stop);
 - //reward
 - QIcon icon_reward;
 - icon_reward.addPixmap(QPixmap(QString::fromUtf8("images/reward_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_4->setIcon(icon_reward);
 - //forward
 - QIcon icon_forward;
 - icon_forward.addPixmap(QPixmap(QString::fromUtf8("images/forward_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_5->setIcon(icon_forward);
 - //sound
 - QIcon icon_sound;
 - icon_sound.addPixmap(QPixmap(QString::fromUtf8("images/sound_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton->setIcon(icon_sound);
 - QIcon icon_previous;
 - icon_previous.addPixmap(QPixmap(QString::fromUtf8("images/previous_disabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_6->setIcon(icon_previous);
 - QIcon icon_next;
 - icon_next.addPixmap(QPixmap(QString::fromUtf8("images/next_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_7->setIcon(icon_next);
 - /************************設置按鈕無邊框**********************************/
 - pushButton->setFlat(true);
 - pushButton_2->setFlat(true);
 - pushButton_3->setFlat(true);
 - pushButton_4->setFlat(true);
 - pushButton_5->setFlat(true);
 - pushButton_6->setFlat(true);
 - pushButton_7->setFlat(true);
 - /*************************獲得播放列表***************************/
 - directory.setPath("./movie");
 - files = directory.entryList(QDir::AllEntries,QDir::Time);
 - file_name = files[2]; //文件0和1為 ”.” ”..”,所以從文件2開始播放
 - file_count = 2;
 - label_3->setText(files[2]);
 - /*************************初始化進度條及QProcess類**************/
 - horizontalSlider->setPageStep(1);
 - process = new QProcess(this);
 - process->setProcessChannelMode(QProcess::MergedChannels);
 - /*************************初始化信號、槽*************************/
 - connect(pushButton_2,SIGNAL(clicked()),this,SLOT(play_pause_slots()));
 - connect(pushButton_3,SIGNAL(clicked()),this,SLOT(stop_slots()));
 - connect(pushButton_4,SIGNAL(clicked()),this,SLOT(playerReward_slots()));
 - connect(pushButton_5,SIGNAL(clicked()),this,SLOT(playerForward_slots()));
 - connect(pushButton_6,SIGNAL(clicked()),this,SLOT(previous_slots()));
 - connect(pushButton_7,SIGNAL(clicked()),this,SLOT(next_slots()));
 - //connect(horizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(seek_slots(int)));
 - connect(spinBox,SIGNAL(valueChanged(int)),this,SLOT(set_volume_slots(int)));
 - connect(pushButton,SIGNAL(clicked()),this,SLOT(set_sound_slots()));
 - connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(back_message_slots()));
 - //當process可以讀到Mplayer的返回信息時,產(chǎn)生readyReadStandardOutput()信號
 - //process->start("mplayer -slave -quiet -ac mad 2.avi");
 - //add -wid QWidget->winId();
 - QString common = "mplayer -slave -quiet -ac mad -zoom movie/" + file_name + " -wid " + QString::number(widget->winId()); //這里的widget是ui中MPlayer的顯示區(qū)
 - process->start(common); //開始運行程序
 - spinBox->setValue(40);
 - timer = new QTimer(this);
 - connect(timer,SIGNAL(timeout()),this,SLOT(get_time_slots()));
 - //定時獲取MPlayer的時間信息
 - timer->start(1000); //啟動定時器 1秒timeout 1次
 - }
 - void MPlayer::play_pause_slots()
 - {
 - if(!isPlay)
 - {
 - if(isStop)
 - {
 - file_name = files[file_count];
 - QString common = "mplayer -slave -quiet -ac mad -zoom movie/" + file_name + " -wid " + QString::number(widget->winId());
 - process->start(common);
 - QIcon icon_stop;
 - icon_stop.addPixmap(QPixmap(QString::fromUtf8("images/stop_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_3->setIcon(icon_stop);
 - isStop = false;
 - }
 - else
 - {
 - process->write("pause ");
 - }
 - QIcon icon_play;
 - icon_play.addPixmap(QPixmap(QString::fromUtf8("images/pause_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_2->setIcon(icon_play);
 - isPlay = true;
 - }
 - else
 - {
 - QIcon icon_pause;
 - icon_pause.addPixmap(QPixmap(QString::fromUtf8("images/play_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_2->setIcon(icon_pause);
 - isPlay = false;
 - process->write("pause ");
 - }
 - }
 - void MPlayer::stop_slots()
 - {
 - if(!isStop)
 - {
 - process->write("quit ");
 - QIcon icon_pause;
 - icon_pause.addPixmap(QPixmap(QString::fromUtf8("images/play_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_2->setIcon(icon_pause);
 - isPlay = false;
 - QIcon icon_stop;
 - icon_stop.addPixmap(QPixmap(QString::fromUtf8("images/stop_disabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_3->setIcon(icon_stop);
 - isStop = true;
 - label->setText("00:00:00");
 - label_2->setText("00:00:00");
 - }
 - }
 - void MPlayer::previous_slots()
 - {
 - if(file_count > 2)
 - {
 - if(file_count == (files.size()-1))
 - {
 - QIcon icon_next;
 - icon_next.addPixmap(QPixmap(QString::fromUtf8("images/next_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_7->setIcon(icon_next);
 - }
 - process->write("quit ");
 - process = new QProcess(this);
 - connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(back_message_slots()));
 - file_count--;
 - if(!isStop)
 - {
 - file_name = files[file_count];
 - QString common = "mplayer -slave -quiet -ac mad -zoom movie/" + file_name + " -wid " + QString::number(widget->winId());
 - process->start(common);
 - }
 - if(file_count == 2)
 - {
 - QIcon icon_previous;
 - icon_previous.addPixmap(QPixmap(QString::fromUtf8("images/previous_disabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_6->setIcon(icon_previous);
 - }
 - label_3->setText(files[file_count]);
 - }
 - }
 - void MPlayer::next_slots()
 - {
 - if(file_count < (files.size()-1))
 - {
 - if(file_count == 2)
 - {
 - QIcon icon_previous;
 - icon_previous.addPixmap(QPixmap(QString::fromUtf8("images/previous_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_6->setIcon(icon_previous);
 - }
 - process->write("quit ");
 - process = new QProcess(this);
 - connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(back_message_slots()));
 - file_count++;
 - if(!isStop)
 - {
 - file_name = files[file_count];
 - QString common = "mplayer -slave -quiet -ac mad -zoom movie/" + file_name + " -wid " + QString::number(widget->winId());
 - process->start(common);
 - }
 - if(file_count == (files.size()-1))
 - {
 - QIcon icon_next;
 - icon_next.addPixmap(QPixmap(QString::fromUtf8("images/next_disabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton_7->setIcon(icon_next);
 - }
 - }
 - label_3->setText(files[file_count]);
 - }
 - void MPlayer::seek_slots(int seek_num)
 - {
 - qDebug()<<seek_num;
 - if(process && process->state() == QProcess::Running )
 - {
 - process->write(QString("seek " + QString::number(qMin(seek_num,100)) + "1 ").toAscii());
 - }
 - }
 - void MPlayer::get_time_slots()
 - {
 - if(isPlay)
 - ]{
 - p
 - rocess->write("get_time_pos ");
 - process->write("get_time_length ");
 - }
 - }
 - void MPlayer::set_volume_slots(int volume)
 - {
 - qDebug()<<volume;
 - process->write(QString("volume +" + QString::number(volume) + " ").toAscii());
 - //process->write(QString("volume +1 ").toAscii());
 - }
 - void MPlayer::set_sound_slots()
 - {
 - if(isSound)
 - {
 - process->write("mute 1 ");
 - QIcon icon_sound;
 - icon_sound.addPixmap(QPixmap(QString::fromUtf8("images/nosound_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton->setIcon(icon_sound);
 - isSound = false;
 - }
 - else
 - {
 - process->write("mute 0 ");
 - QIcon icon_sound;
 - icon_sound.addPixmap(QPixmap(QString::fromUtf8("images/sound_enabled.png")), QIcon::Normal, QIcon::Off);
 - pushButton->setIcon(icon_sound);
 - isSound = true;
 - }
 - }
 - void MPlayer::playerReward_slots()
 - {
 - //bool ok;
 - //int m=moviePosition.toInt(&ok);
 - if (process && process->state()==QProcess::Running && !isPlay)
 - {
 - //QString cmd="seek "+QString::number(qMax(m-10,0))+" 1 ";
 - //process->write(cmd.toAscii());
 - qDebug()<<"Reward";
 - }
 - }
 - void MPlayer::playerForward_slots()
 - {
 - // groupBox->setVisible(false);
 - //bool ok;
 - //int m=moviePosition.toInt(&ok);
 - /* if (process && process->state()==QProcess::Running && !isPlay)
 - {
 - //QString cmd="seek "+QString::number(qMin(m+10,100))+" 1 ";
 - //process->write(cmd.toAscii());
 - qDebug()<<"Forward";
 - }*/
 - }
 - void MPlayer::back_message_slots()
 - {
 - while(process->canReadLine())
 - {
 - QString message(process->readLine());
 - QStringList messagemessage_list = message.split("=");
 - if(message_list[0] == "ANS_TIME_POSITION")
 - {
 - curr_time = message_list[1].toDouble();//toInt();
 - QTime time = int_to_time(curr_time);
 - label->setText(time.toString("hh:mm:ss"));
 - horizontalSlider->setValue(100 * curr_time / file_length);
 - }
 - else if(message_list[0] == "ANS_LENGTH")
 - {
 - file_length = message_list[1].toDouble();//toInt();
 - QTime time = int_to_time(file_length);
 - label_2->setText(time.toString("hh:mm:ss"));
 - }
 - }
 - }
 - QTime MPlayer::int_to_time(int second)
 - {
 - int sec = 0, min = 0, hour = 0;
 - QTime time;
 - if(second < 60)
 - {
 - sec = second;
 - min = 0;
 - hour = 0;
 - }
 - if(second >= 60 && second < 3600)
 - {
 - sec = second % 60;
 - min = second / 60;
 - hour = 0;
 - }
 - if(second >= 3600)
 - {
 - sec = second % 60;
 - min = (second / 60) % 60;
 - hour = second / 3600;
 - }
 - time.setHMS(hour,min,sec);
 - return time;
 - }
 - image.qrc
 - <RCC>
 - <qresource prefix="images" >
 - <file>images/player_play.png</file>
 - <file>images/player_stop.png</file>
 - <file>images/player_pause.png</file>
 - <file>images/play_enabled.png</file>
 - <file>images/pause_enabled.png</file>
 - <file>images/reward_enabled.png</file>
 - <file>images/forward_enabled.png</file>
 - <file>images/stop_enabled.png</file>
 - <file>images/sound_enabled.png</file>
 - <file>images/nosound_enabled.png</file>
 - <file>images/previous_enabled.png</file>
 - <file>images/previous_disabled.png</file>
 - <file>images/next_enabled.png</file>
 - <file>images/next_disabled.png</file>
 - </qresource>
 - </RCC>
 
#p#
3、編譯工程
拷貝qmake到當前工程目錄下
- #cp /home/linux/Qtopia/target/qtopiacore/host/bin/qmake ./
 
生成項目文件、
- #qmake –project
 - 生成Makefile
 - #qmake
 
編譯
- #make
 
成功后,可以生成mplayer可執(zhí)行程序
建立movie和images
- #mkdir movie
 - #mkdir images
 - [root@localhost mplayer]# ls movie/
 - 1.mp3 2.avi 3.avi 4.avi 5.avi
 - [root@localhost mplayer]# ls images
 - forward_enabled.png nosound_enabled.png player_play.png reward_enabled.png
 - images pause_enabled.png player_stop.png sound_enabled.png
 - next_disabled.png play_enabled.png previous_disabled.png stop_disabled.png
 - next_enabled.png player_pause.png previous_enabled.png stop_enabled.png
 
運行程序
- [root@localhost mplayer]#./mplayer
 
【編輯推薦】















 
 
 

 
 
 
 