zoukankan      html  css  js  c++  java
  • 基于QT的mplayer播放器 .

    转载来自:http://blog.csdn.net/songjinshi/article/details/6521320

    一、项目概述
    Mplayer。它支持大量的多媒体文件格式,像常见的音频文件如mp3/wav/mid,常见的视频文件如avi/vcd/dvd/rm等等,各种视频编/解码方式也是应有尽有。
    我们项目的目标是在liunx下,用QT做一个MPlayer皮肤,能够实现播放器的常见
    功能,如:播放、停止、快进、快退、上/下一曲等。并把程序移植到ARM平台上。

    二、功能体验
    本节主要目的是让大家在学习具体实现过程前,先体验下播放器的功能。
    1、PC端功能体验
    将“项目代码/工程代码”目录下的mplayer.tar.gz拷贝linux系统中(主机环境配置好以后,参照第四节的实现过程)。
    #tar xvfz mplayer.tar.gz
    #./mplayer
    2、目标平台功能体验
    l         将“项目代码/工程镜像”文件夹中的zImage、rootfs.cramfs烧写到目标板(或者采用nfs方式)。分区情况为:
    Boot: 0 - 40000   size=0x40000
    Kernel:40000 – 240000  size=0x200000
    Rootfs: 240000 -3740000  size=0x3500000
    启动参数为:
    setenv root=1f02 init=/linuxrc rootfstype=cramfs console=ttySAC0,115200 display=sam240
    setenv bootcmd setenv bootcmd nand read 30008000 40000 200000 /; go 30008000
    l         启动系统后运行:
    #. ./Qtopia.sh
    #cd mymplayer
    #./mymplayer -qws

    三、实现原理
    先来考虑考虑如何为mplayer编写前端界面的问题。有两种思路,一种是把mplayer解剖,直接修改他里面的代码,这样我们做得界面就能够和mplayer一体了(当然也能够通过link mplayer用到的任何的库和.o文档,把他无缝的集成在程式里面);第二种方法就是mplayer所谓的slave模式。
    mplayer '/home/linux/1.mp3' -quiet -slave
    现在来探讨一下slave模式:所谓的slave模式,就是mplayer在运行过程中能够接收用户的输入命令行,具体支持哪些命令行,能够通过mplayer -input cmdlist这条命令来得到,在Mplayer源码的slave.txt中也有对这些命令有详细的讲解。Slave模式下工作的Mplayer可以和系统的标准输入、输出进行信息交互。我们可以用linux C编程来完成对slave模式工作的Mplayer进行控制和信息获取。
    如:
    mkfifo(“/tmp/fifo”,0777);
    可以使用popen()来打开Mplayer
    FILE* mp;
    mp=popen(“mplyer /home/linux/1.mp3 -quiet –slave –input file=/tmp/fifo,”r”);
    可以通过管道/tmp/fifo给mplayer发送命令,通过mp获取mplay的返回数据
    如:system(“echo /”mute 0/” > /tmp/fifo”);//写命令
    fgets(buf,1000,mp);//读取mplay返回数据
    而Qt给我们提供了更方便的实现方法。
    通过定义一个QProcess对象调用已编译好的Mplayer。
    QProcess *process = new QProcess();
    process->setProcessChannelMode(QProcess::MergedChannels);
    Process->start(“mplayer –ac mad xxxxx”);
    在命令中添加 -slave 和 -quiet就可以通过命令设置Mplayer实现相应的功能。在mplayer源码中的,slave.txt中对这些命令有详细的讲解。
    Process->start(“mplayer –slave –quiet –ac mad xxxxx”);
    1、暂停功能
    通过如下代码可以设置Mplayer暂停。
    process->write(“pause/n”);
    执行这段代码的时候如果是播放状态就会暂停,暂停状态时就会继续播放。
    2、获取播放文件的总时间和当前播放进度
    执行下面代码时,Mplayer将时间在标准输出显示。
    process->write("get_time_pos/n");
    process->write("get_time_length/n");
    通过如下代码即可读出我们需要的信息:
    connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(back_message_slots()));
    process有可读取的信息时,发出信号,在槽函数back_message_slots()中读取信息。
    void MPlayer::back_message_slots()
    {
    while(process->canReadLine())
    {
    QString message(process->readLine());
    //message即为读取的信息我们可以根据需要取我们要的信息如
    //文件总时间为:ANS_LENGTH=23.00
    //当前时间为:ANS_TIME_POSITION=23.00
    }
    }
    3、快进功能
    seek <value> [type]
    Seek to some place in the movie.
    0 is a relative seek of +/- <value> seconds (default).
    1 is a seek to <value> % in the movie.
    2 is a seek to an absolute position of <value> seconds.
    下面代码即可实现快进功能:
    process->write(“seek ** 1/n”);
    4、音量调节
    volume <value> [abs]
    Increase/decrease volume or set it to <value> if [abs] is nonzero.
    下面代码即可实现快进功能:
    Process->write(“volume -1/n”);           //音量减小
    Process->write(“volume +1/n”);          //音量增加
    5、静音功能
    mute [value]
    Toggle sound output muting or set it to [value] when [value] >= 0
    (1 == on, 0 == off).
    下面代码即可实现快进功能:
    process->write("mute 0/n");         //开启静音
    process->write("mute 1/n");         //关闭静音
    6、定位视频窗口
    通过上面的代码基本功能实现了,可是播放视频的时候发现又弹出一个窗口。并没有出现在我们的窗口里。
    如下代码即可时间窗口的定位。
    QString common = "mplayer -slave -quiet -ac mad -zoom movie/" + file_name + " -wid " + QString::number(widget->winId());
    process->start(common);
    红色部分实现窗口的定位。Widget是一个QWidget对象。通过winId可以获得一个数字,-wid既将视频输出定位到widget窗体部件中。
    注意:-wid参数只在X11、directX和OpenGL中适用。

    四、PC环境下的实现过程
    1、PC环境搭建
    主机环境:Red Hat Enterprise Linux 5.0
    交叉编译工具:gcc-3.4.5-glibc-2.3.6
    主机编译工具:gcc-4.1.2
    (1)主机端安装mplayer
    l         将“项目代码/mplay源码”目录下的MPlayer-1.0rc2.tar.bz2、libmad-0.15.1b.tar.gz(1个mp3解码库)拷贝到linux系统中,如:/home/linux/mplayer目录下
    l         安装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节将tslib按照好
    l         将“项目代码/qtopia源码”目录下的qtopia-opensource-src-4.2.0.tar.gz拷贝到linux系统中,如:/home/linux/Qtopia目录下
    # tar zxvf qtopia-opensource-src-4.2.0.tar.gz
    # mv qtopia-opensource-4.2.0 source
    # mkdir target  //创建在source同级目录下创建目录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
    修改时区信息
    # vi src/libraries/qtopia/qtimezone.cpp
    将114行的 /usr/share/zoneinfo/ 改为/Qtipia/zoneinfo/ ,保存退出。
    # vi src/settings/systemtime/settime.cpp
    将318行的 /usr/share/zoneinfo/ 改为/Qtipia/zoneinfo/ ,保存退出。
    l         裁减Qtopia core的库(下列操作后在屏幕上会出现一个光标,否则没有光标。根据需求配置)
    # vi qtopiacore/qconfig-qpe.h
    首先注释掉关于鼠标光标的宏定义,让程序运行时,触摸屏中央有光标出现:
    // 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
    */
    其它宏定义根据需要进行注释。
    保存后将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
    注释掉如下内容:
    /*
    #if !defined(QT_NO_QWS_CURSOR) && (defined(QT_NO_CURSOR))
    #define QT_NO_QWS_CURSOR
    #endif
    */
    保存退出。
    # vi qtopiacore/qt/src/corelib/global/qglobal.h
    注释掉以下内容:
    //# 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>
    并修改如下内容
    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 = :pen(tmpFile.toLatin1(), O_CREAT | O_WRONLY);
    为:
    f = :pen(tmpFile.toLatin1(), O_CREAT | O_WRONLY ,0777);
    l         修改交叉工具
    #vim qtopiacore/qt/mkspecs/qws/linux-arm-g++/qmake.conf
    将文件中的arm-linux-***全部修改为arm-softfloat-linux-gnu-**
    这样做的前提是我的交叉工具链是arm-softfloat-linux-gnu,如果你的是arm-linux就不用改了。
    l         生成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,体系结构为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
    数据库支持Sqlite。
    -qt-kbd-usb
    键盘支持usb协议。
    -no-mouse-linuxtp -qt-mouse-tslib
    -I/home/linux/tslib/include -L/home/linux/tslib/lib
    触摸屏协议不支持linuxtp,支持tslib,并在后面添加上刚才编译的tslib的头文件和库。
    2>../qtopiaconfigureERR.txt
    最后将配置过程中的错误输出到qtopiaconfigureERR.txt文件中。
    l         编译
    #make
    #make install
    l         将安装和的目录考到nfsroot目录下
    #cp /Qtopia /rootfs -a
    (3)熟悉主机开发环境
    l         提供给PC端的开发工具
    上面的qtopia编译安装完成后,会在咱们前面创建的target目录下生成很多开发工具。
    先看一下供主机端使用的工具
    [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
    如果系统以前有其它qt开发工具,把环境变量修改一下,保证它们不要和我们这几个工具冲突。下面可以试一下你的designer了。
    #./designer
    2、在PC端实现基于qt前端的mplayer播放器
    创建工程目录/home/linux/mplayer
    (1)搭建ui界面
    利用前面安装的designer搭建ui界面,并将其保存至/home/linux/mplayer/mplayer.ui
    #./designer
    圆角矩形标注: 加了一个widget,留作mplayer的播放区
    (2)编写程序
    在/home/linux/mymplayer/下创建mplayer.cpp、mplayer.h、main.cpp 、image.qrc
    Main.cpp
    /*****************************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
    mplayer.cpp
    /*******************************mplayer.cpp **********************************/
    #include "mplayer.h"
    #include <QDebug>
    #include <unistd.h>
    MPlayer::MPlayer(QWidget *parent)Dialog(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的返回信息时,产生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的显示区
    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/n");
    }
    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/n");
    }
    }
    void MPlayer::stop_slots()
    {
    if(!isStop)
    {
    process->write("quit/n");
    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/n");
    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/n");     
    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/n").toAscii());
    }
    }
    void MPlayer::get_time_slots()
    {
    if(isPlay)
    {
    process->write("get_time_pos/n");
    process->write("get_time_length/n");
    }
    }
    void MPlayer::set_volume_slots(int volume)
    {
    qDebug()<<volume;
    process->write(QString("volume +" + QString::number(volume) + " /n").toAscii());
    //process->write(QString("volume +1/n").toAscii());
    }
    void MPlayer::set_sound_slots()
    {
    if(isSound)
    {
    process->write("mute 1/n");
    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/n");
    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/n";
    //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/n";
    //process->write(cmd.toAscii());
    qDebug()<<"Forward";
    }*/
    }
    void MPlayer::back_message_slots()
    {
    while(process->canReadLine())
    {
    QString message(process->readLine());
    QStringList message_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>
    (3)编译工程
    l         拷贝qmake到当前工程目录下
    #cp /home/linux/Qtopia/target/qtopiacore/host/bin/qmake ./
    l         生成项目文件、
    #qmake –project
    l         生成Makefile
    #qmake
    l         编译
    #make
    成功后,可以生成mplayer可执行程序
    l         建立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
    l         运行程序
    [root@localhost mplayer]#./mplayer
    五、移植到ARM平台过程
    1、内核要求
    要求内核支持framebuffer驱动、OSS音频驱动、支持input事件的触摸屏驱动。
    2、目标板上部署qt环境
    将前面交叉编译好的/Qtopia目录拷贝到nfsroot目录下
    #cp /Qtopia /rootfs –a
    注:rootfs为目标平台的nfs根文件系统位置
    3、文件系统中移植tslib
    (下面的步骤是在ubantu-8.10环境下编译的,其它的系统基本相同)
    (1)拷贝“项目代码/tslib源码”目录下的tslib-1.4.tar.gz到linux系统
    (2)# tar -zxvf tslib-1.4.tar.gz
    # cd tslib-1.4
    # ./autogen.sh
    这一步需要安装一些工具,如:在ubantu系统下可以执行:sudo apt-get install automake
    (3)执行autogen.sh脚本所生成的Makefile文件
    请打入以下命令:
    echo "ac_cv_func_malloc_0_nonnull=yes" >$ARCH-linux.cache
    ./configure --host=arm-softfloat-linux-gnu  --prefix=/home/linux/tslib --cache-file=$ARCH-linux.cache
    --host是指你的交叉编译器的前最;例如:你的交叉编译器是arm-linux-gcc,则--host=arm-linux.如果是arm-softfloat-linux-gnu-gcc
    则--host=arm-softfloat-linux-gnu
    --prefix 是你执行make install 的时候编译后生成的可执行文件和库文件以及配置文所安装的目录;
    configure文件下还有好多选项,你可以执行./configure --help 来进行选择其他项,不过在这里这些选项就够了。
    (4)#make
    #make install
    (5)把指定安装目录下的mytslib的文件都copy到你所挂载的根文件下
    #cp -rf /home/linux/tslib/*    /rootfs/tslib
    (6)修改/rootfs/tslib下的etc目录中ts.cong文件
    #vi ts.conf  将第二行的#module_raw input修改成module_raw input 注意一定要顶格写否则程序执行时会发生读取ts.conf错误
    (7)启动你的开发板
    在终端上设置一下环境变量:
    export TSLIB_ROOT=/mytslib
    export TSLIB_TSDEVICE=/dev/event0
    export LD_LIBRARY_PATH=/mytslib/libLD_LIBRARY_PATH
    export QWS_SIZE=320x240
    export TSLIB_FBDEVICE=/dev/fb0
    export TSLIB_PLUGINDIR=/mytslib/lib/ts
    export TSLIB_CONSOLEDEVICE=none
    export TSLIB_CONFFILE=/mytslib/etc/ts.conf
    export POINTERCAL_FILE=/etc/pointercal
    export QWS_MOUSE_PROTO=Tslib:/dev/event0
    export TSLIB_CALIBFILE=/etc/pointercal
    export QWS_DISPLAY="LinuxFb:mmWidth100:mmHeight130:0"
    export TSLIB_TSEVENTTYYPE=H3600
    为了实现Tslib的正确运行,需要对如下的Tslib的环境变量进行配置:
    TSLIB_TSDEVICE  //触摸屏设备文件名。
    TSLIB_CALIBFILE  //校准的数据文件,由ts_calibrate校准程序生成。
    SLIB_CONFFILE  //配置文件名。
    TSLIB_PLUGINDIR //插件目录
    TSLIB_CONSOLEDEVICE //控制台设备文件名
    TSLIB_FBDEVICE  //设备名
    以上环境变量在实际开发中的实际配置可以根据实际情况决定。而这些指定的设备节点一定要和你的开发板上的/dev目录下的设备节点相对应。
    为了不浪费时间我们把上面的这些设置写入一个脚本里面:参见5.6节
    (8)就可以运行mytslib/bin下的测试文件,如ts_calibrate校准程序。
    4、文件系统中移植mplayer播放器
    需要在目标板上也移植开源的mplayer播放器,步骤如下:
    l         编译libmad
    重新配置前面针对主机编译过的libmad
    #./configure --enable-fpm=arm --host=arm-linux --disable-shared /
    --disable-debugging --prefix=/usr/local/arm/3.4.1/lib /
    CC=arm-linux-gcc
    #make
    就可以编译出libmad了。注意--prefix配置选项表示libmad库和头文件在哪个目录生成,比如本例中make install后在/usr/local/arm/3.4.1/lib目录下就多了include和lib两个目录。这与mplayer的配置选项--with-extraincdir指定的目录是相符的。如果没找到编译生成的lib库和include头文件。则在当前编译目录下的mad.h以及.libs目录下的libmad.a拷到你自己指定的目录下
    l         编译mplayer
    ./configure --cc=arm-linux-gcc --host-cc=gcc --target=arm-linux --enable-static /
    --prefix=/tmp/mplayer-rc2 --disable-win32dll --disable-dvdread /
    --enable-fbdev --disable-mencoder --disable-live --disable-mp3lib /
    --enable-mad --enable-libavcodec_a --language=zh_CN /
    --disable-armv5te --disable-armv6 /
    --with-extraincdir=/usr/local/arm/3.4.1/lib/include /
    --with-extralibdir=/usr/local/arm/3.4.1/lib/lib
    几点注意:—host-cc参数指定X86的gcc,不指定的话,有些必须用gcc编译的,make会交叉编译,就会出错
    --cc指定交叉工具链名称
    --with-extraincdir与--with-extralibdir指定刚才交叉编译libmad生成的mad.h与liblibmad.a存放路径
    编译过程中会出现如下错误:
    armv4l/dsputil_arm_s.S:79:error:selected processor does not support 'pld[r1]'
    【解决办法】
    修改dsputil_arm_s.S,在前面添加上:
    #ifndef HAVE_PLD
    .macro pld reg
    .endm
    #endif
    5、主机交叉编译工程
    (1)针对目标平台调整UI
    由于目标平台的液晶是320*240分辨率的,所以需要调整下UI的大小。将UI的整个窗口大小调整为320*240。
    (2)交叉编译工程
    l         拷贝针对目标平台的qmake工具到工程目录下
    #cp /home/linux/Qtopia/target/qtopiacore/target/bin/qmake ./
    l         生成项目文件
    #qmake –project
    l         生成Makefile文件
    #qmake
    l         编译生成目标文件mymplayer
    #make
    6、设置环境变量脚本文件Qtopia.sh
    #vim Qtopia.sh
    !/bin/sh
    export TSLIB_ROOT=/tslib
    export TSLIB_TSDEVICE=/dev/event0
    export LD_LIBRARY_PATH=/tslib/libLD_LIBRARY_PATH
    export QWS_SIZE=320x240
    export TSLIB_FBDEVICE=/dev/fb0
    export TSLIB_PLUGINDIR=/tslib/lib/ts
    export TSLIB_CONSOLEDEVICE=none
    export TSLIB_CONFFILE=/tslib/etc/ts.conf
    export POINTERCAL_FILE=/etc/pointercal
    export QWS_MOUSE_PROTO=Tslib:/dev/event0
    export TSLIB_CALIBFILE=/etc/pointercal
    export TSLIB_TSEVENTTYYPE=H3600i
    export LD_LIBRARY_PATH=/Qtopia/libLD_LIBRARY_PATH
    export QWS_SW_CURSOR
    export set HOME=/root
    export set QPEDIR=/Qtopia
    export set QWS_KEYBOARD="TTY:/dev/tty1"
    export QWS_DISPLAY="LinuxFb:mmWidth60:mmHeight65:0"   
    7、通过nfs方式测试程序
    (1)设置uboot参数
    setenv bootcmd tftp 30008000 zImage /; go zImage
    setenv bootargs root=nfs nfsroot=192.168.1.112:/rootfs ip=192.168.1.202 init=/linuxrc console=ttySAC0,115200 devfs=mount display=sam240
    (2)启动目标系统
    l         将“项目代码/工程镜像”目录下的zImage拷贝到tftp服务目录/tftpboot下
    l         开启nfs、tftp服务,服务目录分别为/rootfs /tftpboot
    l         启动系统
    l         运行测试程序
    #. ./Qtopia.sh  //设置环境变量
    #cd mymplayer
    #./mymplayer –qws  //运行程序
    8、QT程序国际化
    利用/home/linux/Qtopia/target/qtopiacore/host/bin下面的几个工具给程序做汉化工作
    (1)修改pro文件
    在.pro文件添加如下内容:
    TRANSLATIONS = zh_CN.ts
    (2)生成ts文件
    #lupdate mymplayer.pro
    生成zh_CN.ts文件
    (3)生成qm翻译文件
    #linguist zh_CN.ts
    (4)拷贝字体文件到目标系统
    l         从C:/WINDOWS/Fonts选择一个字体,如simsun.ttc
    cp simsun.ttc /rootfs/Qtopia/lib/fonts           //simsun.ttc 是宋体字库
    l         修改fonts中文件fontdir,添加如下内容
    simsun simsun.ttc TTC n 50 120 u    
    (5)修改源码
    修改main.cpp为如下形式
    #include <QApplication>
    #include "mplayer.h"
    #include <QtCore/QTextCodec>
    #include <QTranslator>
    int main(int argc, char **argv)
    {
    QApplication app(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")) ;//设置编码为UTF8
    app.setFont(QFont("simsun", 10));                            //设置显示字体为汉字
    QTranslator *translator = new QTranslator( 0 );                              //导入中文化qm文件
    translator->load( "zh_CN.qm", "." );
    app.installTranslator( translator );
    MPlayer player;
    player.show();
    return app.exec();
    }
    9、目标机独立测试
    (1)裁剪系统
    (2)制作cramfs镜像

  • 相关阅读:
    ElasticSearch基础4:相关度
    ElasticSearch基础3:全文搜索
    ElasticSearch基础2:查询和过滤初步
    ElasticSearch基础1:初步
    Kafka高级设计和架构,一文深化理解
    JAVA :Jpanel 控件 无法显示问题
    beansbinding NetBeans IDE 中 Swing数据绑定插件
    关于网页游戏断线重连的思路和demo求助
    http://www.classicdosgames.com/
    easyui validatebox 验证集合
  • 原文地址:https://www.cnblogs.com/start530/p/3834406.html
Copyright © 2011-2022 走看看