1. 程式人生 > >基於QtAV的簡易播放器(開源)

基於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 <[email protected]>

    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的簡易播放器程式碼