QT中调用mplayaer(转)
转自:http://topkung.blog.163.com/blog/static/10526804320093114558713/
申请博友中。。。。。
如果是想在QT之外打开一个mplayer窗口就很容易:
const QString mplayerPath("D:/tools/mplayer/mplayer.exe");
QStringList args;
args<<"2.avi";
QProcess* myProcess=new QProcess;
myProcess->start(mplayerPath,args);
如果是想在QT的窗口里用mplayer,就像smplayer那像,这可不是件容易的事。
在网上只找到一上法文的例子:http://doc.qtfr.org/post/2007/03/21/Un-conteneur-pour-MPlayer-utilisation-de-QProcess 用QProcess实现的。可用google英文翻译后阅读。
代码在:http://doc.qtfr.org/public/2007/qt_mplayer.tar.gz
我在windows下实验成功。
也可以研究一下smplayer的源码。大体思想是(别人总结的,跟上面的例子一样):
发现mplayer的参数-wid可以把输出流重定向的指定的窗体,通过winId()得到窗体的id即可,但是我不知道视频流或者说外部显示的数据是怎么在Qwidget上呈现的。
这是那个法国人的例子程序,我加了些comment,注意要把2.avi放到release文件夹下,执行可执行程序,而不是编译后点运行:
#include <QApplication>
#include <QProcess>
#include <QVBoxLayout>
#include <QLayoutItem>
#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QColor>
#include <QRect>
#include <QLinearGradient>
#include <QSizePolicy>
#include <QPushButton>
#include <QTextEdit>
#include <QSlider>
#include <QCloseEvent>
#include <QTimer>
#ifdef Q_OS_WIN32
const QString mplayerPath("D:/tools/mplayer/mplayer.exe");
#else
const QString mplayerPath("/usr/bin/mplayer");
#endif
const QString movieFile("2.avi");
class PlayerWidget: public QWidget
...{
Q_OBJECT
private:
QPushButton *controller;
QWidget *renderTarget;
QProcess *mplayerProcess; //main thing
bool isPlaying;
QSlider *timeLine;
QTimer *poller;
QTextEdit *log;
public:
PlayerWidget(QWidget *parent =0)
:QWidget(parent), isPlaying(false)
...{
controller = new QPushButton("Play");
renderTarget = new QWidget(this);
renderTarget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
renderTarget->setAttribute(Qt::WA_OpaquePaintEvent );
renderTarget->setMinimumSize(500, 500);
timeLine = new QSlider(Qt::Horizontal);
log = new QTextEdit;
log->setReadOnly(true);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(controller);
layout->addWidget(renderTarget);
layout->addWidget(timeLine);
layout->addWidget(log);
setLayout(layout);
mplayerProcess = new QProcess(this);
poller = new QTimer(this);
connect(controller, SIGNAL(clicked()), this, SLOT(switchPlayState())); //switchPlayState在后面
connect(mplayerProcess, SIGNAL(readyReadStandardOutput()),
this, SLOT(catchOutput())); //catchOutput在后面
connect(mplayerProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(mplayerEnded(int, QProcess::ExitStatus))); //mplayerEnded在后面
connect(poller, SIGNAL(timeout()), this, SLOT(pollCurrentTime())); //pollCurrentTime在后面
connect(timeLine, SIGNAL(sliderMoved(int)), this, SLOT(timeLineChanged(int))); //timeLineChanged在后面
}
protected:
virtual void closeEvent(QCloseEvent *e)
...{
stopMPlayer();
e->accept();
}
private:
bool startMPlayer()
...{
if(isPlaying)
return true;
QStringList args; //运行mplayer需要的参数
// On demande ? utiliser mplayer comme backend
// are asked to use mplayer as backend
args << "-slave";
// Et on veut ne pas avoir trop de chose ? parser :)
//And we want to not having too many things to parser:)
args << "-quiet";
#ifdef Q_WS_WIN
// reinterpret_cast<qlonglong> obligatoire, winId() ne se laissant pas convertir gentiment ;)
//reinterpret_cast <qlonglong> mandatory winId () not allowing convert nicely;)
args << "-wid" << QString::number(reinterpret_cast<qlonglong>(renderTarget->winId()));
args << "-vo" << "directx:noaccel";
#else
// Sur linux, aucun driver n''a ?t? n?cessaire et pas de manip pour Wid :)
//On linux, no driver has been necessary and no manip for Wid:)
args << "-wid" << QString::number(renderTarget->winId());
log->append("Video output driver may not be necessary for your platform.
Check: http://www.mplayerhq.hu/DOCS/man/en/mplayer.1.html
at the VIDEO OUTPUT DRIVERS section.");
#endif
args << movieFile;
// On parse la stdout et stderr au m?me endroit, donc on demande ? "fusionnner" les 2 flux
//parse the stdout and stderr in the same place, so we are asking "fusionnner"
mplayerProcess->setProcessChannelMode(QProcess::MergedChannels);
mplayerProcess->start(mplayerPath, args); //开始运行这个进程
if(!mplayerProcess->waitForStarted(100))
...{
qDebug("allez, cherche le bug :o");
return false;
}
// On r?cup?re les infos de base
//retrieve basic information
mplayerProcess->write("get_video_resolution ");
mplayerProcess->write("get_time_length ");
poller->start(1000);
isPlaying = true;
return true;
}
bool stopMPlayer()
...{
if(!isPlaying)
return true;
mplayerProcess->write("quit ");
if(!mplayerProcess->waitForFinished(100))
...{
qDebug("ZOMG, ?a plante :(");
return false;
}
return true;
}
private slots:
//响应readyReadStandardOutput消息
void catchOutput()
...{
while(mplayerProcess->canReadLine())
...{
QByteArray buffer(mplayerProcess->readLine());
log->append(QString(buffer));
// On v?rifie si on a eu des r?ponses
//It checks if we had answers
// r?ponse ? get_video_resolution : ANS_VIDEO_RESOLUTION=''<width> x <height>''
//response to get_video_resolution: ANS_VIDEO_RESOLUTION
if(buffer.startsWith("ANS_VIDEO_RESOLUTION"))
...{
buffer.remove(0, 21); // vire ANS_VIDEO_RESOLUTION=
buffer.replace(QByteArray("''"), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
int sepIndex = buffer.indexOf(''x'');
int resX = buffer.left(sepIndex).toInt();
int resY = buffer.mid(sepIndex+1).toInt();
renderTarget->setMinimumSize(resX, resY);
}
// r?ponse ? get_time_length : ANS_LENGTH=xx.yy
//response to get_time_length: ANS_LENGTH =
else if(buffer.startsWith("ANS_LENGTH"))
...{
buffer.remove(0, 11); // vire ANS_LENGTH=
buffer.replace(QByteArray("''"), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
float maxTime = buffer.toFloat();
timeLine->setMaximum(static_cast<int>(maxTime+1));
}
// r?ponse ? get_time_pos : ANS_TIME_POSITION=xx.y
//response to get_time_pos: ANS_TIME_POSITION = 2.4
else if(buffer.startsWith("ANS_TIME_POSITION"))
...{
buffer.remove(0, 18); // vire ANS_TIME_POSITION=
buffer.replace(QByteArray("''"), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
buffer.replace(QByteArray(" "), QByteArray(""));
float currTime = buffer.toFloat();
timeLine->setValue(static_cast<int>(currTime+1));
}
//qApp->processEvents();
}
}
void pollCurrentTime()
...{
mplayerProcess->write("get_time_pos ");
}
// Dirige la timeline
//Directs the timeline
void timeLineChanged(int pos)
...{
mplayerProcess->write(QString("seek " + QString::number(pos) + " 2 ").toUtf8());
}
// Play/stop
void switchPlayState()
...{
if(!isPlaying)
...{
if(!startMPlayer())
return;
log->clear();
controller->setText("Stop");
isPlaying = true;
}
else
...{
if(!stopMPlayer())
return;
poller->stop();
log->clear();
controller->setText("Play");
isPlaying = false;
}
}
void mplayerEnded(int exitCode, QProcess::ExitStatus exitStatus)
...{
isPlaying = false;
controller->setText("Play");
poller->stop();
}
};
int main(int argc, char **argv)
...{
QApplication app(argc, argv);
PlayerWidget *pw = new PlayerWidget;
pw->show();
return app.exec();
}
#include "main.moc" //I don''t understand this.
文章出处:http://www.diybl.com/course/4_webprogram/asp.net/netjs/200847/108687.html