Closed cnhbljp closed 10 years ago
你代码貼下
MainWindow.cpp
/** QtAV Player Demo: this file is part of QtAV examples Copyright (C) 2012-2014 Wang Bin wbsecg1@gmail.com
This file is part of QtAV
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. **/
//#include "StatisticsView.h"
/ TODO:
qDebug("%s %s @%d", **FILE**, **FUNCTION**, **LINE**);
using namespace QtAV; const qreal kVolumeInterval = 0.05;
static void QLabelSetElideText(QLabel label, QString text, int W = 0) { QFontMetrics metrix(label->font()); int width = label->width() - label->indent() - label->margin(); if (W || label->parent()) { int w = W; if (!w) w = ((QWidget)label->parent())->width(); width = qMax(w - label->indent() - label->margin() - 13*(30), 0); //TODO: why 30? } QString clippedText = metrix.elidedText(text, Qt::ElideRight, width); label->setText(clippedText); }
MainWindow::MainWindow(QWidget *parent) : QWidget(parent) , mIsReady(false) , mHasPendingPlay(false) , mNullAO(false) , mControlOn(false) , mShowControl(2) , mpPlayer(0) , mpRenderer(0) , mpTempRenderer(0) {
setMouseTracking(true); //mouseMoveEvent without press.
connect(this, SIGNAL(ready()), SLOT(processPendingActions()));
//QTimer::singleShot(10, this, SLOT(setupUi()));
setupUi();
//setToolTip(tr("Click black area to use shortcut(see right click menu)"));
}
MainWindow::~MainWindow() {
if (mpVolumeSlider && !mpVolumeSlider->parentWidget()) {
mpVolumeSlider->close();
delete mpVolumeSlider;
mpVolumeSlider = 0;
}
}
void MainWindow::initPlayer() {
mpPlayer = new AVPlayer(this);
mIsReady = true;
//mpPlayer->setAudioOutput(AudioOutputFactory::create(AudioOutputId_OpenAL));
//QHash<QByteArray, QByteArray> dict;
//dict.insert("rtsp_transport", "tcp");
//mpPlayer->setOptionsForFormat(dict);
qDebug("player created");
// connect(mpStopBtn, SIGNAL(clicked()), mpPlayer, SLOT(stop())); // connect(mpForwardBtn, SIGNAL(clicked()), mpPlayer, SLOT(seekForward())); // connect(mpBackwardBtn, SIGNAL(clicked()), mpPlayer, SLOT(seekBackward())); connect(mpVolumeBtn, SIGNAL(clicked()), SLOT(showHideVolumeBar())); connect(mpVolumeSlider, SIGNAL(sliderPressed()), SLOT(setVolume())); connect(mpVolumeSlider, SIGNAL(valueChanged(int)), SLOT(setVolume()));
// connect(mpPlayer, SIGNAL(mediaStatusChanged(QtAV::MediaStatus)), SLOT(onMediaStatusChanged())); connect(mpPlayer, SIGNAL(error(QtAV::AVError)), this, SLOT(handleError(QtAV::AVError))); connect(mpPlayer, SIGNAL(started()), this, SLOT(onStartPlay())); connect(mpPlayer, SIGNAL(stopped()), this, SLOT(onStopPlay())); connect(mpPlayer, SIGNAL(paused(bool)), this, SLOT(onPaused(bool))); connect(mpPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64))); qDebug( "intplayerend") ; emit ready(); //emit this signal after connection. otherwise the slots may not be called for the first time }
void MainWindow::setupUi() { QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->setSpacing(0); mainLayout->setMargin(0); setLayout(mainLayout);
mpPlayerLayout = new QVBoxLayout();
mpControl = new QWidget(this);
mpControl->setMaximumHeight(25);
//mpPreview = new QLable(this);
mpTimeSlider = new Slider(mpControl);
mpTimeSlider->setDisabled(true);
//mpTimeSlider->setFixedHeight(8);
mpTimeSlider->setMaximumHeight(8);
mpTimeSlider->setTracking(true);
mpTimeSlider->setOrientation(Qt::Horizontal);
mpTimeSlider->setMinimum(0);
QGraphicsOpacityEffect *oe = new QGraphicsOpacityEffect(this);
oe->setOpacity(0.5);
mpTimeSlider->setGraphicsEffect(oe);
mpCurrent = new QLabel(mpControl);
mpCurrent->setToolTip(tr("Current time"));
mpCurrent->setMargin(2);
mpCurrent->setText("00:00:00");
mpDuration = new QLabel(mpControl);
mpDuration->setToolTip(tr("Duration"));
mpDuration->setMargin(2);
mpDuration->setText("00:00:00");
mPlayPixmap = QPixmap(":/theme/button-play-pause.png");
int w = mPlayPixmap.width(), h = mPlayPixmap.height();
mPausePixmap = mPlayPixmap.copy(QRect(w/2, 0, w/2, h));
mPlayPixmap = mPlayPixmap.copy(QRect(0, 0, w/2, h));
qDebug("%d x %d", mPlayPixmap.width(), mPlayPixmap.height());
mpPlayPauseBtn = new Button(mpControl);
int a = qMin(w/2, h);
const int kMaxButtonIconWidth = 20;
const int kMaxButtonIconMargin = kMaxButtonIconWidth/3;
a = qMin(a, kMaxButtonIconWidth);
mpPlayPauseBtn->setIconWithSates(mPlayPixmap);
mpPlayPauseBtn->setIconSize(QSize(a, a));
mpPlayPauseBtn->setMaximumSize(a+kMaxButtonIconMargin+2, a+kMaxButtonIconMargin);
// mpStopBtn = new Button(mpControl); // mpStopBtn->setIconWithSates(QPixmap(":/theme/button-stop.png")); // mpStopBtn->setIconSize(QSize(a, a)); // mpStopBtn->setMaximumSize(a+kMaxButtonIconMargin+2, a+kMaxButtonIconMargin); // mpBackwardBtn = new Button(mpControl); // mpBackwardBtn->setIconWithSates(QPixmap(":/theme/button-rewind.png")); // mpBackwardBtn->setIconSize(QSize(a, a)); // mpBackwardBtn->setMaximumSize(a+kMaxButtonIconMargin+2, a+kMaxButtonIconMargin); // mpForwardBtn = new Button(mpControl); // mpForwardBtn->setIconWithSates(QPixmap(":/theme/button-fastforward.png")); // mpForwardBtn->setIconSize(QSize(a, a)); // mpForwardBtn->setMaximumSize(a+kMaxButtonIconMargin+2, a+kMaxButtonIconMargin); // mpOpenBtn = new Button(mpControl); // mpOpenBtn->setToolTip(tr("Open")); // mpOpenBtn->setIconWithSates(QPixmap(":/theme/open_folder.png")); // mpOpenBtn->setIconSize(QSize(a, a)); // mpOpenBtn->setMaximumSize(a+kMaxButtonIconMargin+2, a+kMaxButtonIconMargin);
mpVolumeBtn = new Button();
mpVolumeBtn->setIconWithSates(QPixmap(":/theme/button-max-volume.png"));
mpVolumeBtn->setIconSize(QSize(a, a));
mpVolumeBtn->setMaximumSize(a+kMaxButtonIconMargin+2, a+kMaxButtonIconMargin);
mpVolumeSlider = new Slider();
mpVolumeSlider->hide();
mpVolumeSlider->setOrientation(Qt::Horizontal);
mpVolumeSlider->setMinimum(0);
const int kVolumeSliderMax = 100;
mpVolumeSlider->setMaximum(kVolumeSliderMax);
mpVolumeSlider->setMaximumHeight(8);
mpVolumeSlider->setMaximumWidth(188);
mpVolumeSlider->setValue(int(1.0/kVolumeInterval*qreal(kVolumeSliderMax)/100.0));
setVolume();
//subMenu->setEnabled(false);
// TODO: move to a func or class
mainLayout->addLayout(mpPlayerLayout);
mainLayout->addWidget(mpTimeSlider);
mainLayout->addWidget(mpControl);
QHBoxLayout *controlLayout = new QHBoxLayout();
controlLayout->setSpacing(0);
controlLayout->setMargin(1);
mpControl->setLayout(controlLayout);
controlLayout->addWidget(mpCurrent);
QSpacerItem *space = new QSpacerItem(mpPlayPauseBtn->width(), mpPlayPauseBtn->height(), QSizePolicy::MinimumExpanding);
controlLayout->addSpacerItem(space);
controlLayout->addWidget(mpVolumeSlider);
controlLayout->addWidget(mpVolumeBtn);
controlLayout->addWidget(mpPlayPauseBtn);
// controlLayout->addWidget(mpStopBtn); // controlLayout->addWidget(mpBackwardBtn); // controlLayout->addWidget(mpForwardBtn);
// controlLayout->addWidget(mpOpenBtn);
controlLayout->addWidget(mpDuration);
// connect(mpOpenBtn, SIGNAL(clicked()), SLOT(openFile()));
connect(mpPlayPauseBtn, SIGNAL(clicked()), SLOT(togglePlayPause()));
connect(mpTimeSlider, SIGNAL(sliderPressed()), SLOT(seek()));
connect(mpTimeSlider, SIGNAL(sliderReleased()), SLOT(seek()));
connect(mpTimeSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int)));
qDebug( "setupuiend11") ;
QTimer::singleShot(0, this, SLOT(initPlayer()));
qDebug( "setupuiend") ;
}
void MainWindow::processPendingActions() { qDebug( "processPendingActions") ; if (!mpTempRenderer) return; setRenderer(mpTempRenderer); mpTempRenderer = 0; if (mHasPendingPlay) { mHasPendingPlay = false; qDebug( " play(mFile);") ; play(mFile); } }
void MainWindow::enableAudio(bool yes) { mNullAO = !yes; if (!mpPlayer) return; mpPlayer->enableAudio(yes); }
void MainWindow::setAudioOutput(AudioOutput *ao) { Q_UNUSED(ao); }
void MainWindow::setRenderer(QtAV::VideoRenderer *renderer) { if (!mIsReady) { mpTempRenderer = renderer; return; } if (!renderer) return;
int old_pos = 0;
int old_total = 0;
if (mpTimeSlider) {
old_pos = mpTimeSlider->value();
old_total = mpTimeSlider->maximum();
mpTimeSlider->hide();
} else {
}
renderer->widget()->setMouseTracking(true); //mouseMoveEvent without press.
mpPlayer->setRenderer(renderer);
QWidget *r = 0;
if (mpRenderer)
r = mpRenderer->widget();
//release old renderer and add new
if (r) {
mpPlayerLayout->removeWidget(r);
if (r->testAttribute(Qt::WA_DeleteOnClose)) {
r->close();
} else {
r->close();
delete r;
}
r = 0;
}
mpRenderer = renderer;
//setInSize?
mpPlayerLayout->addWidget(renderer->widget());
resize(renderer->widget()->size());
if (mpTimeSlider) {
mpTimeSlider->setParent(mpRenderer->widget());
mpTimeSlider->show();
}
if (mpPlayer->renderer()->id() == VideoRendererId_GLWidget) {
} else if (mpPlayer->renderer()->id() == VideoRendererId_XV) {
} else {
}
mpPlayer->renderer()->forcePreferredPixelFormat(false);
qDebug("setrenderend");
}
void MainWindow::play(const QString &name) { mFile = name; if (!mIsReady) { mHasPendingPlay = true; return; } // if (!mFile.contains("://") || mFile.startsWith("file://")) { // mTitle = QFileInfo(mFile).fileName(); // }
QFile vidfile(mFile);
if (!vidfile.open(QIODevice::ReadOnly))
return ;
QByteArray data = vidfile.read(vidfile.size());
vidfile.seek(0);
QBuffer buf(&data);
if (buf.open(QIODevice::ReadOnly)) {
mpPlayer->setIODevice(&buf);
mpPlayer->play();
}
//mpPlayer->play(name); }
void MainWindow::setVideoDecoderNames(const QStringList &vd)
{
QStringList vdnames;
foreach (QString v, vd) {
vdnames << v.toLower();
}
QVector
void MainWindow::openFile() { QString file = QFileDialog::getOpenFileName(0, tr("Open a media file")); if (file.isEmpty()) return; play(file); }
void MainWindow::togglePlayPause() { if (mpPlayer->isPlaying()) { qDebug("isPaused = %d", mpPlayer->isPaused()); mpPlayer->pause(!mpPlayer->isPaused()); } else { if (mFile.isEmpty()) return; mpPlayer->play(); mpPlayPauseBtn->setIconWithSates(mPausePixmap); } }
void MainWindow::onSpinBoxChanged(double v) { if (!mpPlayer) return; mpPlayer->setSpeed(v); }
void MainWindow::onPaused(bool p) { if (p) { qDebug("start pausing..."); mpPlayPauseBtn->setIconWithSates(mPlayPixmap); } else { qDebug("stop pausing..."); mpPlayPauseBtn->setIconWithSates(mPausePixmap); } }
void MainWindow::onStartPlay() { mpRenderer->setRegionOfInterest(QRectF()); mFile = mpPlayer->file(); //open from EventFilter's menu setWindowTitle(mTitle);
mpPlayPauseBtn->setIconWithSates(mPausePixmap);
mpTimeSlider->setMaximum(mpPlayer->duration());
mpTimeSlider->setValue(0);
qDebug(">>>>>>>>>>>>>>enable slider");
mpTimeSlider->setEnabled(true);
mpDuration->setText(QTime(0, 0, 0).addMSecs(mpPlayer->duration()).toString("HH:mm:ss"));
setVolume();
mShowControl = 0;
QTimer::singleShot(3000, this, SLOT(tryHideControlBar()));
mCursorTimer = startTimer(3000);
}
void MainWindow::onStopPlay() { if (mpPlayer->currentRepeat() < mpPlayer->repeat()) return; mpPlayPauseBtn->setIconWithSates(mPlayPixmap); mpTimeSlider->setValue(0); qDebug(">>>>>>>>>>>>>>disable slider"); mpTimeSlider->setDisabled(true); mpCurrent->setText("00:00:00"); mpDuration->setText("00:00:00"); tryShowControlBar();
//mRepeateMax = 0;
killTimer(mCursorTimer);
unsetCursor();
}
void MainWindow::seekToMSec(int msec) { mpPlayer->seek(qint64(msec)); }
void MainWindow::seek() { mpPlayer->seek((qint64)mpTimeSlider->value()); }
void MainWindow::showHideVolumeBar() { if (mpVolumeSlider->isHidden()) { mpVolumeSlider->show(); } else { mpVolumeSlider->hide(); } }
void MainWindow::setVolume() { AudioOutput _ao = mpPlayer ? mpPlayer->audio() : 0; qreal v = qreal(mpVolumeSlider->value())_kVolumeInterval; if (ao) { ao->setVolume(v); } mpVolumeSlider->setToolTip(QString::number(v)); mpVolumeBtn->setToolTip(QString::number(v)); }
void MainWindow::closeEvent(QCloseEvent *e) { Q_UNUSED(e); if (mpPlayer) mpPlayer->stop(); qApp->quit(); }
void MainWindow::resizeEvent(QResizeEvent _e) { Q_UNUSED(e);
if (e->size() == qApp->desktop()->size()) {
mpControl->hide();
mpTimeSlider->hide();
} else {
if (mpControl->isHidden())
mpControl->show();
if (mpTimeSlider->isHidden())
mpTimeSlider->show();
}
/_
if (mpTitle)
QLabelSetElideText(mpTitle, QFileInfo(mFile).fileName(), e->size().width());
_/
int m = 4;
QWidget *w = static_cast<QWidget_>(mpTimeSlider->parent());
if (w) {
mpTimeSlider->resize(w->width() - m_2, 44);
qDebug("%d %d %d", m, w->height() - mpTimeSlider->height() - m, w->width() - m_2);
mpTimeSlider->move(m, w->height() - mpTimeSlider->height() - m);
}
}
void MainWindow::timerEvent(QTimerEvent *e) { if (e->timerId() == mCursorTimer) { if (mpControl->isVisible()) return; setCursor(Qt::BlankCursor); } }
void MainWindow::onPositionChange(qint64 pos) { mpTimeSlider->setValue(pos); mpCurrent->setText(QTime(0, 0, 0).addMSecs(pos).toString("HH:mm:ss")); }
void MainWindow::keyPressEvent(QKeyEvent *e) { mControlOn = e->key() == Qt::Key_Control; }
void MainWindow::keyReleaseEvent(QKeyEvent *e) { Q_UNUSED(e); mControlOn = false; }
void MainWindow::mousePressEvent(QMouseEvent *e) { if (!mControlOn) return; mGlobalMouse = e->globalPos(); }
void MainWindow::mouseMoveEvent(QMouseEvent *e) { unsetCursor(); if (e->pos().y() > height() - mpTimeSlider->height() - mpControl->height()) { if (mShowControl == 0) { mShowControl = 1; tryShowControlBar(); } } else { if (mShowControl == 1) { mShowControl = 0; QTimer::singleShot(3000, this, SLOT(tryHideControlBar())); } } if (mControlOn && e->button() == Qt::LeftButton) { if (!mpRenderer || !mpRenderer->widget()) return; QRectF roi = mpRenderer->realROI(); QPointF delta = e->pos() - mGlobalMouse; roi.moveLeft(-delta.x()); roi.moveTop(-delta.y()); mpRenderer->setRegionOfInterest(roi); } }
void MainWindow::wheelEvent(QWheelEvent _e) { if (!mpRenderer || !mpRenderer->widget()) { return; }
qreal deg = e->angleDelta().y()/8;
qreal deg = e->delta()/8;
if (!mControlOn) {
qreal speed = mpPlayer->speed();
mpPlayer->setSpeed(qMax(0.01, speed + deg/15.0_0.02));
return;
}
QPointF p = mpRenderer->widget()->mapFrom(this, e->pos());
QPointF fp = mpRenderer->mapToFrame(p);
if (fp.x() < 0)
fp.setX(0);
if (fp.y() < 0)
fp.setY(0);
if (fp.x() > mpRenderer->frameSize().width())
fp.setX(mpRenderer->frameSize().width());
if (fp.y() > mpRenderer->frameSize().height())
fp.setY(mpRenderer->frameSize().height());
QRectF viewport = QRectF(mpRenderer->mapToFrame(QPointF(0, 0)), mpRenderer->mapToFrame(QPointF(mpRenderer->rendererWidth(), mpRenderer->rendererHeight())));
//qDebug("vo: (%.1f, %.1f)=> frame: (%.1f, %.1f)", p.x(), p.y(), fp.x(), fp.y());
qreal zoom = 1.0 + deg*3.14/180.0;
//qDebug("deg: %d, %d zoom: %.2f", e->angleDelta().x(), e->angleDelta().y(), zoom);
QTransform m;
m.translate(fp.x(), fp.y());
m.scale(1.0/zoom, 1.0/zoom);
m.translate(-fp.x(), -fp.y());
QRectF r = m.mapRect(mpRenderer->realROI());
mpRenderer->setRegionOfInterest((r | m.mapRect(viewport))&QRectF(QPointF(0,0), mpRenderer->frameSize()));
}
void MainWindow::about() { QtAV::about(); }
void MainWindow::help() { QFile f(qApp->applicationDirPath() + "/help.html"); if (!f.exists()) { f.setFileName(":/help.html"); } if (!f.open(QIODevice::ReadOnly)) { qWarning("Failed to open help.html: %s", qPrintable(f.errorString())); return; } QTextStream ts(&f); QString text = ts.readAll(); QMessageBox::information(0, "Help", text); }
void MainWindow::openUrl() { QString url = QInputDialog::getText(0, tr("Open an url"), tr("Url")); if (url.isEmpty()) return; play(url); }
void MainWindow::playOnlineVideo(QAction *action) { mTitle = action->text(); play(action->data().toString()); }
void MainWindow::tryHideControlBar() { if (mShowControl > 0) { return; } if (mpControl->isHidden() && mpTimeSlider->isHidden()) return; mpControl->hide(); mpTimeSlider->hide(); }
void MainWindow::tryShowControlBar() { unsetCursor(); if (mpTimeSlider->isHidden()) mpTimeSlider->show(); if (mpControl->isHidden()) mpControl->show(); }
//void MainWindow::showInfo() //{ //// // why crash if on stack //// static StatisticsView *sv = new StatisticsView; //// if (mpPlayer) //// sv->setStatistics(mpPlayer->statistics()); //// sv->show(); //}
void MainWindow::onTimeSliderHover(int pos, int value) { QToolTip::showText(mapToGlobal(mpTimeSlider->pos() + QPoint(pos, 0)), QTime(0, 0, 0).addMSecs(value).toString("HH:mm:ss")); }
void MainWindow::onTimeSliderLeave() {
}
void MainWindow::handleError(const AVError &e) { QMessageBox::warning(0, "Player error", e.string()); }
void MainWindow::onMediaStatusChanged() { QString status; AVPlayer _player = qobjectcast<AVPlayer>(sender()); switch (player->mediaStatus()) { case NoMedia: status = "No media"; break; case InvalidMedia: status = "Invalid meida"; break; case BufferingMedia: status = "Buffering..."; break; case BufferedMedia: status = "Buffered"; break; case LoadingMedia: status = "Loading..."; break; case LoadedMedia: status = "Loaded"; break; default: break; } if (!status.isEmpty()) setWindowTitle(status); }
void MainWindow::donate() { //QDesktopServices::openUrl(QUrl("https://sourceforge.net/p/qtav/wiki/Donate%20%E6%8D%90%E8%B5%A0/")); QDesktopServices::openUrl(QUrl("http://wang-bin.github.io/QtAV/#donate")); }
main.cpp /** QtAV Player Demo: this file is part of QtAV examples Copyright (C) 2012-2014 Wang Bin wbsecg1@gmail.com
This file is part of QtAV
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. **/
using namespace QtAV;
int main(int argc, char *argv[]) { QApplication a(argc, argv);
QString file = a.arguments().last() ;
file = QString::fromUtf8("/mnt/sdcard2/test.avi");
qDebug()<< "qtplayer filename " << file ;
VideoRenderer *renderer = 0;
renderer = VideoRendererFactory::create(VideoRendererId_Widget);
MainWindow window;
window.show();
window.setWindowState(Qt::WindowFullScreen);
window.setRenderer(renderer);
renderer->widget()->resize(1024, 730);
window.play(file);
int ret = a.exec();
return ret;
}
你这样必须挂呀,AVPlayer::setIODevice(QIODevice*)
不会获得指针的所有权,出了作用域,也就是对应的大括号外面那个QBuffer就销毁了,自然就崩了
另外,贴代码要代吗前后留一行,每行前面再空4格贴上来就会正常显示代码
我发现在android下,单独使用您的例子 qiodevice 正常,但如果加上UI ,则程序会终止。 修改使用player的例子,直接播放文件正常,但是用QIODevice的方式播放文件,程序也会终止。