基于QtAV的简易播放器(开源)
这个开源代码,是我利用QtAV源码,提取其中一部分代码,进行整合到我自己项目中,做的一个小型播放器测试,至于怎么安装一些环境以及QtAV源码编译在我以前写的一篇博客中可以看到(Qt第三方库QtAV--- ubuntu编译与运行),因为看到有人提出说怎么调用接口,怎么整合到自己项目中的问题, 因为网上资料关于QtAV的的确很少,由于也是去年年前带我的师傅让我了解调用接口,顺便做个简单的播放器,所以和大家分享下!!!该播放器主要实现了快进、后退、暂停、播放、选择文件、调节音量大小等。
整个环境即编译条件在ubuntu 64位 Qt 5.7.0下运行成功!!!
这是运行界面截图
废话不多说,直接上代码!!!
QtAVPlayer.pro
#-------------------------------------------------
#
# Project created by QtCreator 2017-01-16T22:05:51
# author: yangshujie
#-------------------------------------------------
QT += core gui
QT += avwidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QtAVPlayer
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
Slider.cpp
HEADERS += mainwindow.h \
Slider.h
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
Widgets::registerRenderers();
QApplication a(argc, argv);
MainWindow play;
play.show();
//play.setGeometry();
play.resize(800,500);
return a.exec();
}
Slider.h
#ifndef SLIDER_H
#define SLIDER_H
#include <QSlider>
class Slider : public QSlider
{
Q_OBJECT
public:
Slider(QWidget *parent = 0);
~Slider();
signals:
void onEnter();
void onLeave();
void onHover(int pos, int value);
protected:
virtual void enterEvent(QEvent* event);
virtual void leaveEvent(QEvent *e);
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void mousePressEvent(QMouseEvent *event);
//#if CODE_FOR_CLICK == 1
inline int pick(const QPoint &pt) const;
int pixelPosToRangeValue(int pos) const;
void initStyleOption_Qt430(QStyleOptionSlider *option) const;
//#endif
};
#endif // SLIDER_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "Slider.h"
#include <QMainWindow>
#include <QWidget>
#include <QString>
#include <QtAV>
#include <QLabel>
#include <QTime>
#include <QAction>
#include <QToolTip>
#include <QWidgetAction>
#include <QFileDialog>
#include <QVBoxLayout>
#include <QToolButton>
#include <QSpinBox>
#include <QMessageBox>
#include <QTimeEdit>
#include <QtAVWidgets>
#include <QtAV/AVClock.h>
#include <QtAV/AVPlayer.h>
using namespace QtAV;
//class Slider;
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void play(const QString &name);
void openFile();
void togglePlayPause();
private slots:
void setupUi();
void initPlayer();
void setVolume();
void setRepeateMax(int m);
void stopUnload();
void seek();
void onPaused(bool p);
void onStartPlay();
void onStopPlay();
void onSeekFinished();
void onTimeSliderHover(int pos, int value);
void onTimeSliderLeave();
void handleError(const QtAV::AVError& e);
void onPositionChange(qint64 pos);
void showHideVolumeBar();
void tryShowControlBar();
void toggleRepeat(bool r);
void repeatAChanged(const QTime& t);
void repeatBChanged(const QTime& t);
private:
int mRepeateMax;
int mCursorTimer;
bool mIsReady,mHasPendingPlay;
VideoOutput *mpVo;
AVPlayer *mpPlayer;
AVClock *mpClock;
VideoRenderer *mpRenderer, *mpTempRenderer;
QString mFile;
QString mTitle;
QTimeEdit *mpRepeatA, *mpRepeatB;
QVBoxLayout *mpPlayerLayout,*mainLayout;
QAction *mpRepeatEnableAction;
QWidgetAction *mpRepeatAction;
QWidget *mpControl;
QLabel *mpCurrent, *mpEnd;
QLabel *mpTitle;
QLabel *mpSpeed;
Slider *mpTimeSlider, *mpVolumeSlider;
QSpinBox *mpRepeatBox;
QToolButton *mpVolumeBtn;
QToolButton *mpPlayPauseBtn;
QToolButton *mpStopBtn, *mpForwardBtn, *mpBackwardBtn;
QToolButton *mpOpenBtn;
VideoPreviewWidget *m_preview;
};
#endif // MAINWINDOW_H
Slider.cpp
#include "Slider.h"
/* smplayer, GUI front-end for mplayer.
Copyright (C) 2006-2010 Ricardo Villalba <rvm@escomposlinux.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), Trolltech ASA
(or its successors, if any) and the KDE Free Qt Foundation, which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#define CODE_FOR_CLICK 1 // 0 = old code, 1 = code copied from QSlider, 2 = button swap
#include "Slider.h"
#include <QApplication>
#include <QMouseEvent>
#if CODE_FOR_CLICK <= 1
#include <QStyle>
#if CODE_FOR_CLICK == 1
#include <QStyleOption>
#endif
#endif
#if QT_VERSION < 0x040300
#define initStyleOption initStyleOption_Qt430
#endif //QT_VERSION
Slider::Slider(QWidget *parent):
QSlider(parent)
{
setOrientation(Qt::Horizontal);
setMouseTracking(true); //mouseMoveEvent without press.
}
Slider::~Slider()
{
}
#if CODE_FOR_CLICK == 1
// Function copied from qslider.cpp
inline int Slider::pick(const QPoint &pt) const
{
return orientation() == Qt::Horizontal ? pt.x() : pt.y();
}
// Function copied from qslider.cpp and modified to make it compile
void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const
{
if (!option)
return;
option->initFrom(this);
option->subControls = QStyle::SC_None;
option->activeSubControls = QStyle::SC_None;
option->orientation = orientation();
option->maximum = maximum();
option->minimum = minimum();
option->tickPosition = (QSlider::TickPosition) tickPosition();
option->tickInterval = tickInterval();
option->upsideDown = (orientation() == Qt::Horizontal) ?
(invertedAppearance() != (option->direction == Qt::RightToLeft))
: (!invertedAppearance());
option->direction = Qt::LeftToRight; // we use the upsideDown option instead
option->sliderPosition = sliderPosition();
option->sliderValue = value();
option->singleStep = singleStep();
option->pageStep = pageStep();
if (orientation() == Qt::Horizontal)
option->state |= QStyle::State_Horizontal;
}
// Function copied from qslider.cpp and modified to make it compile
int Slider::pixelPosToRangeValue(int pos) const
{
QStyleOptionSlider opt;
initStyleOption(&opt);
QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this);
QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
int sliderMin, sliderMax, sliderLength;
if (orientation() == Qt::Horizontal) {
sliderLength = sr.width();
sliderMin = gr.x();
sliderMax = gr.right() - sliderLength + 1;
} else {
sliderLength = sr.height();
sliderMin = gr.y();
sliderMax = gr.bottom() - sliderLength + 1;
}
return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin,
sliderMax - sliderMin, opt.upsideDown);
}
void Slider::enterEvent(QEvent *event)
{
emit onEnter();
QSlider::enterEvent(event);
}
void Slider::leaveEvent(QEvent *e)
{
emit onLeave();
QSlider::leaveEvent(e);
}
void Slider::mouseMoveEvent(QMouseEvent *e)
{
const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1;
int v = QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x()-o/2, width()-o, false);
emit onHover(e->x(), v);
QSlider::mouseMoveEvent(e);
}
// Based on code from qslider.cpp
void Slider::mousePressEvent(QMouseEvent *e)
{
qDebug("pressed (%d, %d)", e->pos().x(), e->pos().y());
if (e->button() == Qt::LeftButton) {
QStyleOptionSlider opt;
initStyleOption(&opt);
const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
const QPoint center = sliderRect.center() - sliderRect.topLeft();
// to take half of the slider off for the setSliderPosition call we use the center - topLeft
if (!sliderRect.contains(e->pos())) {
qDebug("accept");
e->accept();
int v = pixelPosToRangeValue(pick(e->pos() - center));
setSliderPosition(v);
triggerAction(SliderMove);
setRepeatAction(SliderNoAction);
emit sliderMoved(v);//TODO: ok?
emit sliderPressed(); //TODO: ok?
} else {
QSlider::mousePressEvent(e);
}
} else {
QSlider::mousePressEvent(e);
}
}
#endif // CODE_FOR_CLICK == 1
#if CODE_FOR_CLICK == 2
void Slider::mousePressEvent(QMouseEvent *e)
{
// Swaps middle button click with left click
if (e->button() == Qt::LeftButton) {
QMouseEvent ev2(QEvent::MouseButtonRelease, e->pos(), e->globalPos(), Qt::MidButton, Qt::MidButton, e->modifiers());
QSlider::mousePressEvent(&ev2);
} else if (e->button() == Qt::MidButton) {
QMouseEvent ev2(QEvent::MouseButtonRelease, e->pos(), e->globalPos(), Qt::LeftButton, Qt::LeftButton, e->modifiers());
QSlider::mousePressEvent(&ev2);
}
else {
QSlider::mousePressEvent(e);
}
}
#endif // CODE_FOR_CLICK == 2
#if CODE_FOR_CLICK == 0
void Slider::mousePressEvent(QMouseEvent *e)
{
// FIXME:
// The code doesn't work well with right to left layout,
// so it's disabled.
if (qApp->isRightToLeft()) {
QSlider::mousePressEvent(e);
return;
}
int range = maximum()-minimum();
int pos = (e->x() * range) / width();
//qDebug( "width: %d x: %d", width(), e->x());
//qDebug( "range: %d pos: %d value: %d", range, pos, value());
// Calculate how many positions takes the slider handle
int metric = qApp->style()->pixelMetric(QStyle::PM_SliderLength);
double one_tick_pixels = (double)width() / range;
int slider_handle_positions = (int)(metric / one_tick_pixels);
/*
qDebug("metric: %d", metric );
qDebug("one_tick_pixels :%f", one_tick_pixels);
qDebug("width() :%d", width());
qDebug("slider_handle_positions: %d", slider_handle_positions);
*/
if (abs(pos - value()) > slider_handle_positions) {
setValue(pos);
emit sliderMoved(pos);
} else {
QSlider::mousePressEvent(e);
}
}
#endif
mainwindow.cpp
#include "mainwindow.h"
#include <QTimer>
const qreal kVolumeInterval = 0.04;
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent),mpPlayer(0),mpVo(0),mpTempRenderer(0)
{
setWindowTitle("QtAV Player");
setupUi();
}
MainWindow::~MainWindow()
{
if (m_preview) {
m_preview->close();
delete m_preview;
}
if (mpVolumeSlider && !mpVolumeSlider->parentWidget()) {
mpVolumeSlider->close();
delete mpVolumeSlider;
mpVolumeSlider = 0;
}
}
void MainWindow::setupUi()
{
mpPlayer = new AVPlayer(this);
mainLayout = new QVBoxLayout();
mainLayout->setSpacing(0);
mainLayout->setMargin(0);
setLayout(mainLayout);
mpControl = new QWidget(this);
mpControl->setMaximumHeight(30);
mpTimeSlider = new Slider(mpControl);
mpTimeSlider->setDisabled(true);
mpTimeSlider->setTracking(true);
mpTimeSlider->setOrientation(Qt::Horizontal);
mpTimeSlider->setMinimum(0);
mpCurrent = new QLabel(mpControl);
mpCurrent->setToolTip(tr("Current time"));
mpCurrent->setMargin(2);
mpCurrent->setText(QString::fromLatin1("00:00:00"));
mpEnd = new QLabel(mpControl);
mpEnd->setToolTip(tr("Duration"));
mpEnd->setMargin(2);
mpEnd->setText(QString::fromLatin1("00:00:00"));
mpTitle = new QLabel(mpControl);
mpTitle->setToolTip(tr("Author"));
mpTitle->setText(QString::fromLatin1("YangShuJie"));
mpTitle->setIndent(8);
mpPlayPauseBtn = new QToolButton(mpControl);
mpPlayPauseBtn->setToolTip(tr("Play"));
mpPlayPauseBtn->setIcon(QIcon(QString::fromLatin1("./image/play.png")));
mpStopBtn = new QToolButton(mpControl);
mpStopBtn->setToolTip(tr("Stop"));
mpStopBtn->setIcon(QIcon(QString::fromLatin1("./image/stop.png")));
mpBackwardBtn = new QToolButton(mpControl);
mpBackwardBtn->setToolTip(tr("Backward"));
mpBackwardBtn->setIcon(QIcon(QString::fromLatin1("./image/backward.png")));
mpForwardBtn = new QToolButton(mpControl);
mpForwardBtn->setToolTip(tr("Forward"));
mpForwardBtn->setIcon(QIcon(QString::fromLatin1("./image/forward.png")));
mpOpenBtn = new QToolButton(mpControl);
mpOpenBtn->setToolTip(tr("Open"));
mpOpenBtn->setIcon(QIcon(QString::fromLatin1("./image/open.png")));
mpVolumeBtn = new QToolButton();
mpVolumeBtn->setToolTip(tr("Volume"));
mpVolumeBtn->setIcon(QIcon(QString::fromLatin1("./image/sound.png")));
mpVolumeSlider = new Slider();
mpVolumeSlider->hide();
mpVolumeSlider->setOrientation(Qt::Horizontal);
mpVolumeSlider->setMinimum(0);
const int kVolumeSliderMax = 100;
mpVolumeSlider->setMaximum(kVolumeSliderMax);
//mpVolumeSlider->setMaximumHeight(12);
mpVolumeSlider->setMaximumWidth(88);
mpVolumeSlider->setValue(int(1.0/kVolumeInterval*qreal(kVolumeSliderMax)/100.0));
setVolume();
QWidgetAction *pWA = 0;
// QLabel *pRepeatLabel = new QLabel(tr("Times"));
QHBoxLayout *hb = new QHBoxLayout;
// hb->addWidget(pRepeatLabel);
hb->addWidget(mpRepeatBox);
QVBoxLayout *vb = new QVBoxLayout;
vb->addLayout(hb);
// pRepeatLabel = new QLabel(tr("From"));
mpRepeatA = new QTimeEdit();
mpRepeatA->setDisplayFormat(QString::fromLatin1("HH:mm:ss"));
mpRepeatA->setToolTip(tr("negative value means from the end"));
connect(mpRepeatA, SIGNAL(timeChanged(QTime)), SLOT(repeatAChanged(QTime)));
hb = new QHBoxLayout;
// hb->addWidget(pRepeatLabel);
hb->addWidget(mpRepeatA);
vb->addLayout(hb);
// pRepeatLabel = new QLabel(tr("To"));
mpRepeatB = new QTimeEdit();
mpRepeatB->setDisplayFormat(QString::fromLatin1("HH:mm:ss"));
mpRepeatB->setToolTip(tr("negative value means from the end"));
connect(mpRepeatB, SIGNAL(timeChanged(QTime)), SLOT(repeatBChanged(QTime)));
hb = new QHBoxLayout;
// hb->addWidget(pRepeatLabel);
hb->addWidget(mpRepeatB);
vb->addLayout(hb);
QWidget *wgt = new QWidget;
wgt->setLayout(vb);
pWA = new QWidgetAction(0);
pWA->setDefaultWidget(wgt);
pWA->defaultWidget()->setEnabled(false);
mpRepeatAction = pWA;
mpVo = new VideoOutput(this);
if (!mpVo->widget()) {
QMessageBox::warning(0, QString::fromLatin1("QtAV error"), tr("Can not create video renderer"));
return;
}
mpPlayer->setRenderer(mpVo);
mainLayout->addWidget(mpVo->widget());
mainLayout->addWidget(mpTimeSlider);
mainLayout->addWidget(mpControl);
QHBoxLayout *controlLayout = new QHBoxLayout();
controlLayout->setSpacing(0);
controlLayout->setMargin(1);
mpControl->setLayout(controlLayout);
controlLayout->addWidget(mpCurrent);
controlLayout->addWidget(mpTitle);
QSpacerItem *space = new QSpacerItem(mpPlayPauseBtn->width(), mpPlayPauseBtn->height(), QSizePolicy::MinimumExpanding);
controlLayout->addSpacerItem(space);
controlLayout->addWidget(mpVolumeSlider);
controlLayout->addWidget(mpVolumeBtn);
controlLayout->addWidget(mpStopBtn);
controlLayout->addWidget(mpBackwardBtn);
controlLayout->addWidget(mpPlayPauseBtn);
controlLayout->addWidget(mpForwardBtn);
controlLayout->addWidget(mpOpenBtn);
controlLayout->addWidget(mpEnd);
connect(mpOpenBtn, SIGNAL(clicked()), SLOT(openFile()));
connect(mpPlayPauseBtn, SIGNAL(clicked()), SLOT(togglePlayPause()));
mIsReady = true;
// connect(mpTimeSlider, SIGNAL(sliderMoved(int)), SLOT(seek(int)));
connect(mpTimeSlider, SIGNAL(sliderPressed()), SLOT(seek()));
connect(mpTimeSlider, SIGNAL(sliderReleased()), SLOT(seek()));
connect(mpTimeSlider, SIGNAL(onLeave()), SLOT(onTimeSliderLeave()));
connect(mpTimeSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int)));
QTimer::singleShot(0, this, SLOT(initPlayer()));
}
void MainWindow::initPlayer()
{
connect(mpVolumeBtn, SIGNAL(clicked()), SLOT(showHideVolumeBar()));
connect(mpVolumeSlider, SIGNAL(sliderPressed()), SLOT(setVolume()));
connect(mpVolumeSlider, SIGNAL(valueChanged(int)), SLOT(setVolume()));
connect(mpStopBtn, SIGNAL(clicked()), this, SLOT(stopUnload()));
connect(mpForwardBtn, SIGNAL(clicked()), mpPlayer, SLOT(seekForward()));
connect(mpBackwardBtn, SIGNAL(clicked()), mpPlayer, SLOT(seekBackward()));
connect(mpPlayer, SIGNAL(seekFinished()), SLOT(onSeekFinished()));
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(speedChanged(qreal)), this, SLOT(onSpeedChange(qreal)));
connect(mpPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64)));
}
void MainWindow::stopUnload()
{
mpPlayer->stop();
mpPlayer->unload();
}
void MainWindow::handleError(const AVError &e)
{
QMessageBox::warning(0, tr("Player error"), e.string());
}
void MainWindow::onStartPlay()
{
mFile = mpPlayer->file(); //open from EventFilter's menu
mTitle = mFile;
if (!mFile.contains(QLatin1String("://")) || mFile.startsWith(QLatin1String("file://")))
mTitle = QFileInfo(mFile).fileName();
setWindowTitle(mTitle);
mpPlayPauseBtn->setIcon(QIcon(QString::fromLatin1("./image/pause.png")));
mpTimeSlider->setMinimum(mpPlayer->mediaStartPosition());
mpTimeSlider->setMaximum(mpPlayer->mediaStopPosition());
mpTimeSlider->setValue(0);
mpTimeSlider->setEnabled(mpPlayer->isSeekable());
mpEnd->setText(QTime(0, 0, 0).addMSecs(mpPlayer->mediaStopPosition()).toString(QString::fromLatin1("HH:mm:ss")));
setVolume();
QTimer::singleShot(3000, this, SLOT(tryHideControlBar()));
mpRepeatA->setMinimumTime(QTime(0, 0, 0).addMSecs(mpPlayer->mediaStartPosition()));
mpRepeatA->setMaximumTime(QTime(0, 0, 0).addMSecs(mpPlayer->mediaStopPosition()));
mpRepeatB->setMinimumTime(QTime(0, 0, 0).addMSecs(mpPlayer->mediaStartPosition()));
mpRepeatB->setMaximumTime(QTime(0, 0, 0).addMSecs(mpPlayer->mediaStopPosition()));
mpRepeatA->setTime(QTime(0, 0, 0).addMSecs(mpPlayer->startPosition()));
mpRepeatB->setTime(QTime(0, 0, 0).addMSecs(mpPlayer->stopPosition()));
mCursorTimer = startTimer(3000);
}
void MainWindow::onStopPlay()
{
if (mpPlayer->currentRepeat() < mpPlayer->repeat())
return;
mpPlayPauseBtn->setIcon(QIcon(QString::fromLatin1("./image/play.png")));
mpTimeSlider->setValue(0);
qDebug(">>>>>>>>>>>>>>disable slider");
mpTimeSlider->setDisabled(true);
mpTimeSlider->setMinimum(0);
mpTimeSlider->setMaximum(0);
mpCurrent->setText(QString::fromLatin1("00:00:00"));
mpEnd->setText(QString::fromLatin1("00:00:00"));
tryShowControlBar();
toggleRepeat(false);
// mRepeateMax = 0;
killTimer(mCursorTimer);
unsetCursor();
if (m_preview)
m_preview->setFile(QString());
}
void MainWindow::seek()
{
mpPlayer->setSeekType(AccurateSeek);
mpPlayer->seek((qint64)mpTimeSlider->value());
}
void MainWindow::onTimeSliderLeave()
{
if (m_preview && m_preview->isVisible())
m_preview->hide();
}
void MainWindow::onTimeSliderHover(int pos, int value)
{
QPoint gpos = mapToGlobal(mpTimeSlider->pos() + QPoint(pos, 0));
QToolTip::showText(gpos, QTime(0, 0, 0).addMSecs(value).toString(QString::fromLatin1("HH:mm:ss")));
if (!m_preview)
m_preview = new VideoPreviewWidget();
m_preview->setFile(mpPlayer->file());
m_preview->setTimestamp(value);
m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
}
void MainWindow::onPaused(bool p)
{
if (p) {
qDebug("start pausing...");
mpPlayPauseBtn->setIcon(QIcon(QString::fromLatin1("./image/play.png")));
} else {
qDebug("stop pausing...");
mpPlayPauseBtn->setIcon(QIcon(QString::fromLatin1("./image/pause.png")));
}
}
void MainWindow::showHideVolumeBar()
{
if (mpVolumeSlider->isHidden()) {
mpVolumeSlider->show();
} else {
mpVolumeSlider->hide();
}
}
void MainWindow::tryShowControlBar()
{
unsetCursor();
if (mpTimeSlider && mpTimeSlider->isHidden())
mpTimeSlider->show();
if (mpControl && mpControl->isHidden())
mpControl->show();
}
void MainWindow::toggleRepeat(bool r)
{
mpRepeatAction->defaultWidget()->setEnabled(r); //why need defaultWidget?
if (r) {
mRepeateMax = mpRepeatBox->value();
} else {
mRepeateMax = 0;
}
if (mpPlayer) {
mpPlayer->setRepeat(mRepeateMax);
}
}
void MainWindow::setVolume()
{
AudioOutput *ao = mpPlayer ? mpPlayer->audio() : 0;
qreal v = qreal(mpVolumeSlider->value())*kVolumeInterval;
if (ao) {
if (qAbs(int(ao->volume()/kVolumeInterval) - mpVolumeSlider->value()) >= int(0.1/kVolumeInterval)) {
ao->setVolume(v);
}
}
mpVolumeSlider->setToolTip(QString::number(v));
mpVolumeBtn->setToolTip(QString::number(v));
}
void MainWindow::openFile()
{
QString file = QFileDialog::getOpenFileName(0, tr("Open a media file"));
if (file.isEmpty())
return;
play(file);
}
void MainWindow::onPositionChange(qint64 pos)
{
if (mpPlayer->isSeekable())
mpTimeSlider->setValue(pos);
mpCurrent->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss")));
}
void MainWindow::togglePlayPause()
{
if (mpPlayer->isPlaying()) {
qDebug("isPaused = %d", mpPlayer->isPaused());
mpPlayer->pause(!mpPlayer->isPaused());
} else {
if (mFile.isEmpty())
return;
if (!mpPlayer->isPlaying()){
play(mFile);
}
else{
// qDebug()<<"111111111111111111111111111111111111111\n";
mpPlayer->play();
mpPlayPauseBtn->setIcon(QIcon(QString::fromLatin1("./image/pause.png")));
}
}
}
void MainWindow::play(const QString &name)
{
mFile = name;
if (!mIsReady) {
mHasPendingPlay = true;
return;
}
mTitle = mFile;
if (!mFile.contains(QLatin1String("://")) || mFile.startsWith(QLatin1String("file://"))) {
mTitle = QFileInfo(mFile).fileName();
}
setWindowTitle(mTitle);
mpPlayer->play(name);
}
void MainWindow::onSeekFinished()
{
qDebug("seek finished at %lld", mpPlayer->position());
}
void MainWindow::setRepeateMax(int m)
{
mRepeateMax = m;
if (mpPlayer) {
mpPlayer->setRepeat(m);
}
}
void MainWindow::repeatAChanged(const QTime& t)
{
if (!mpPlayer)
return;
mpPlayer->setStartPosition(QTime(0, 0, 0).msecsTo(t));
}
void MainWindow::repeatBChanged(const QTime& t)
{
if (!mpPlayer)
return;
// when this slot is called? even if only range is set?
if (t <= mpRepeatA->time())
return;
mpPlayer->setStopPosition(QTime(0, 0, 0).msecsTo(t));
}
说明下:Slider.h和Slider.cpp这个类所有代码我没动过,从QtAV代码中截取出来,有些槽函数未使用到(主要是是因为我怕以后可能要进行扩展,所以全部保存了下来),这个播放器我大概花了2~3天左右,包括搭环境、写代码、调试等,有不好的地方见谅,希望能帮到很多人!!!
我已将代码上传CSDN,欢迎下载!!!
链接:基于QtAV的简易播放器代码
基于QtAV的简易播放器(开源)的更多相关文章
- 基于ffmpeg的C++播放器1
基于ffmpeg的C++播放器 (1) 2011年12月份的时候发了这篇博客 http://blog.csdn.net/qq316293804/article/details/7107049 ,博文最 ...
- 基于FFMPEG的跨平台播放器实现
基于FFMPEG的跨平台播放器实现 一.背景介绍 FFmpeg是一款超级强大的开源多媒体编解码框架,提供了录制.转换以及流化音视频的完整解决方案,包含了libavcodec.libavformat等多 ...
- 仿迅雷播放器教程 -- 基于VLC的MFC播放器 (6)
代码下载:http://download.csdn.net/detail/qq316293804/6409417 昨天的教程里写着预计MFC播放器会隔得久一点,但是今晚仔细看了下VLC的常 ...
- FFmpeg简易播放器的实现-视频播放
本文为作者原创:https://www.cnblogs.com/leisure_chn/p/10047035.html,转载请注明出处 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- FFmpeg简易播放器的实现-音视频同步
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- FFmpeg简易播放器的实现-音视频播放
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10235926.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- FFmpeg简易播放器的实现-音频播放
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10068490.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- FFmpeg简易播放器的实现-最简版
本文为作者原创:https://www.cnblogs.com/leisure_chn/p/10040202.html,转载请注明出处 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- GitHub上最著名的Android播放器开源项目大全
GitHub上最著名的Android播放器开源项目大全 ...
- <Win32_17>集音频和视频播放功能于一身的简易播放器
前段时间,在学习中科院杨老师的教学视频时,他说了一句话: "我很反对百八十行的教学程序,要来就来一个完整的程序" 对此,我很是赞同.所谓真刀真枪的做了,你才会发现其中的奥秘——然而 ...
随机推荐
- C Ⅸ
数组例子:统计个数 #include <stdio.h> int main(void) { int x; int count[10]; int i; ...
- 2---JVM启动参数有哪些?
也要以说JVM启动的时候可以调整哪些参数,来进行调优.JVM 为垃圾收集器.堆大小和运行时编译器提供与平台相关的默认选择. 性能取决于堆的大小.应用程序维护的实时数据量以及可用处理器的数量和速度.. ...
- nginx 代理路径
反向代理被代理url没有截取 /report/api/ /report/api/bussinessRisk/zhucai/creditInquiry 应该是/bussinessRisk/zhucai/ ...
- vsftpd2.3.4 后门笑脸漏洞
漏洞概要 在vsftpd 2.3.4版本中,在登录输入用户名时输入:)类似于笑脸的符号,会导致服务处理开启6200后门端口,直接执行系统命令 漏洞利用 攻击机:kali 2022 msfconsole ...
- MySQL学习(五)事务
参考博客:https://www.cnblogs.com/kismetv/p/10331633.html 0.提交和回滚 注:mysql默认自动开启了事务. -- 手动开启事务 start trans ...
- Apollo 分布式配置中心理论到实践
携程开源的配置管理中心(统一管理各种应用配置的基础服务组件),能够集中化管理应用的不同环境,不同集群的配置,配置修改后能够实时推送到应用端,适合微服务配置管理场景.Apollo包括服务端和客户端. 在 ...
- Windows7卡在正在关机
据我的分析,Windows系统卡在正在关机的原因很大可能性是破解过系统主题.解决方法就是还原成主题未被破解时候的状态.但是这种情况是随机性的,但是可以确定的是,只要是破解过系统主题,都有一定概率关不了 ...
- Django笔记八之model中Meta参数的使用
前面介绍了 model 的字段属性,字段类型,这篇笔记介绍一下 model 的 Meta 选项. 这个选项提供了一些参数,比如排序(ordering),表名(db_table)等. 但这都不是必需的, ...
- 一些随笔No.3
1.开发应以业务为导向,技术只是手段 2.视觉上和程序上不一定是完全符合 比如,我所说的阻塞是视觉层面,或者是对用户而言的阻塞,而不是程序意义上的.我也许会传完参的同时销毁原组件,生成一个看起来一模一 ...
- 二进制安装k8s v1.25.4 IPv4/IPv6双栈
二进制安装k8s v1.25.4 IPv4/IPv6双栈 https://github.com/cby-chen/Kubernetes 开源不易,帮忙点个star,谢谢了 介绍 kubernetes( ...