基于QT前端的mplayer播放器2

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镜像

原文地址:https://www.cnblogs.com/zzxap/p/2175738.html