QT中调用mplayer显示视频并加透明文字
2011-03-17 16:14
651 查看
之前使用QT的多媒体库phonon播放视频,后来发现在跨平台时也比较麻烦,不如直接带一个mplayer播放。CPU占用还可以。
#include <QApplication>
#include <QtGui>
#ifdef Q_WS_WIN
const QString mplayerPath("C:\\Program Files\\SMPlayer\\mplayer\\mplayer.exe");
const QString movieFile("c:/traffic.mpg");
#else
const QString mplayerPath("/usr/bin/mplayer");
const QString movieFile("/home/anderson/test.avi");
#endif
class MaskedLabel : public QLabel
{
public:
MaskedLabel(QWidget *parent = 0):QLabel(parent)
{
}
protected:
void resizeEvent(QResizeEvent* event)
{
QLabel::resizeEvent(event);
QPixmap pixmap(size());
pixmap.fill(Qt::transparent);
QPainter::setRedirected(this, &pixmap);
QPaintEvent pe(rect());
paintEvent(&pe);
QPainter::restoreRedirected(this);
setMask(pixmap.mask());
}
};
class PlayerWidget : public QWidget
{
Q_OBJECT
public:
virtual ~PlayerWidget() {}
PlayerWidget(QWidget *parent =0): QWidget(parent)
{
controller = new QPushButton("Play");
renderTarget = new QWidget(this);
renderTarget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
renderTarget->setAttribute(Qt::WA_OpaquePaintEvent );
renderTarget->setMinimumSize(g00, g00);
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在后面
QLabel* label = new MaskedLabel();
label->setText("<font color=\"#0000e0\" size=\"22\"> <b> 1Now there was a man of the Pharisees named Nicodemus, a member of the Jewish ruling council. 2He came to Jesus at night and said, \"Rabbi, we know you are a teacher who has come from God. For no one could perform the miraculous signs you are doing if God were not with him.\" 3In reply Jesus declared, \"I tell you the truth, no one can see the kingdom of God unless he is born again.[a]\" 4\"How can a man be born when he is old?\" Nicodemus asked. \"Surely he cannot enter a second time into his mother's womb to be born!\" </b></font>");
//label->setGeometry(renderTarget->geometry());
label->setWordWrap(true);
label->show();
}
private:
QPushButton *controller;
QWidget *renderTarget;
QProcess *mplayerProcess; //main thing
bool isPlaying;
QSlider *timeLine;
QTimer *poller;
QTextEdit *log;
protected:
void closeEvent(QCloseEvent *e)
{
stopMPlayer();
e->accept();
}
private:
bool startMPlayer()
{
if(isPlaying)
return true;
QStringList args; //运行mplayer需求的参数parameter
// 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 obligatoire, winId() ne se laissant pas convertir gentiment ;)
//reinterpret_cast mandatory winId () not allowing convert nicely;)
args << "-wid" << QString::number(reinterpret_cast<long>(renderTarget->winId()));
args << "-vo" << "directx:noaccel";
// args << "-nocache";
// args << "-framedrop";
#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("can not start mplayer !");
return false;
}
//retrieve basic information
mplayerProcess->write("get_video_resolution ");
mplayerProcess->write("get_time_length ");
poller->start(0);
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=' x '
//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<long>(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<long>(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 "hello.moc"
#include <QApplication>
#include <QtGui>
#ifdef Q_WS_WIN
const QString mplayerPath("C:\\Program Files\\SMPlayer\\mplayer\\mplayer.exe");
const QString movieFile("c:/traffic.mpg");
#else
const QString mplayerPath("/usr/bin/mplayer");
const QString movieFile("/home/anderson/test.avi");
#endif
class MaskedLabel : public QLabel
{
public:
MaskedLabel(QWidget *parent = 0):QLabel(parent)
{
}
protected:
void resizeEvent(QResizeEvent* event)
{
QLabel::resizeEvent(event);
QPixmap pixmap(size());
pixmap.fill(Qt::transparent);
QPainter::setRedirected(this, &pixmap);
QPaintEvent pe(rect());
paintEvent(&pe);
QPainter::restoreRedirected(this);
setMask(pixmap.mask());
}
};
class PlayerWidget : public QWidget
{
Q_OBJECT
public:
virtual ~PlayerWidget() {}
PlayerWidget(QWidget *parent =0): QWidget(parent)
{
controller = new QPushButton("Play");
renderTarget = new QWidget(this);
renderTarget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
renderTarget->setAttribute(Qt::WA_OpaquePaintEvent );
renderTarget->setMinimumSize(g00, g00);
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在后面
QLabel* label = new MaskedLabel();
label->setText("<font color=\"#0000e0\" size=\"22\"> <b> 1Now there was a man of the Pharisees named Nicodemus, a member of the Jewish ruling council. 2He came to Jesus at night and said, \"Rabbi, we know you are a teacher who has come from God. For no one could perform the miraculous signs you are doing if God were not with him.\" 3In reply Jesus declared, \"I tell you the truth, no one can see the kingdom of God unless he is born again.[a]\" 4\"How can a man be born when he is old?\" Nicodemus asked. \"Surely he cannot enter a second time into his mother's womb to be born!\" </b></font>");
//label->setGeometry(renderTarget->geometry());
label->setWordWrap(true);
label->show();
}
private:
QPushButton *controller;
QWidget *renderTarget;
QProcess *mplayerProcess; //main thing
bool isPlaying;
QSlider *timeLine;
QTimer *poller;
QTextEdit *log;
protected:
void closeEvent(QCloseEvent *e)
{
stopMPlayer();
e->accept();
}
private:
bool startMPlayer()
{
if(isPlaying)
return true;
QStringList args; //运行mplayer需求的参数parameter
// 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 obligatoire, winId() ne se laissant pas convertir gentiment ;)
//reinterpret_cast mandatory winId () not allowing convert nicely;)
args << "-wid" << QString::number(reinterpret_cast<long>(renderTarget->winId()));
args << "-vo" << "directx:noaccel";
// args << "-nocache";
// args << "-framedrop";
#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("can not start mplayer !");
return false;
}
//retrieve basic information
mplayerProcess->write("get_video_resolution ");
mplayerProcess->write("get_time_length ");
poller->start(0);
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=' x '
//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<long>(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<long>(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 "hello.moc"
相关文章推荐
- <Linux+Qt>Qt4编程控制mplayer嵌入自定义界面监控或视频显示
- QT透明显示文字
- QT透明显示文字
- Qt 调用mplayer视频
- <Qt>windows平台调用mplayer播放视频
- EasyDSS RTMP流媒体服务器中调用videojs播放rtmp视频显示在左上角问题
- IOS网络第二天 - 03-JSON显示数据,调用本地视频播放,数据转模型
- Qt 调用phonon 在xp下不能播放视频的解决方法(Phonon::createPath: Cannot connect Phonon::MediaObject ( no objectName )...)
- qt显示视频大小和位置
- QT调用mplayer
- webrtc视频捕获并通过QT显示
- QT 生成DLL并显示调用
- QT之QTabWidget 为West方向时实现文字垂直显示
- MFC调用Opencv显示视频
- 基于Python OpenCV加载视频文件,显示,并绘制自定义文字
- jQuery [jQuery视频教程--->Jq网页开发精解04] 设计列表 文字滚动 图片按比例显示
- qt界面上显示摄像头视频
- Linux下使用QT调用opencv读取摄像头视频 调试心得
- Qt 调用phonon 在xp下不能播放视频的解决方法(Phonon::createPath: Cannot connect Phonon::MediaObject ( no objectName )...)
- opencv调用是视频图像并且显示