【Qt 学习之路】关于C++ Vlc视频播放

文章目录

  • 1、简介
  • 2、效果
    • 2.1、视频
    • 2.2、动态图
  • 3、核心代码
    • 3.1、判断视频
    • 3.2、视频核心类调用
    • 3.3、视频核心类
      • 3.3.1、头文件
      • 3.3.2、源文件

1、简介

最近有童鞋咨询VLC相关的问题,公布一个 5年前 编写的 VLC示例 代码供参考学习。包括正常对视频各种常用的操作:播放/暂停、进度显示、进度调整、声音调整、视频切换等。也包括一些动画效果:显隐动画、加载动画、多视频切换动画等。

2、效果

2.1、视频

VLC+Qt效果

2.2、动态图

  • 进度调整
    在这里插入图片描述
  • 声音调整
    在这里插入图片描述
  • 显隐动画
    在这里插入图片描述

3、核心代码

3.1、判断视频

    // 检测是否是视频文件
    bool isVideo(QString path) {
        QStringList strList = {"mp4", "video/mp4",
                               "qt", "video/quicktime",
                               "mov", "video/quicktime",
                               "3gp", "video/3gpp",
                               "wmv", "video/x-ms-wmv",
                               "avi", "video/x-msvideo",
                               "mpe", "video/mpeg",
                               "mpeg", "video/mpeg",
                               "mpg", "video/mpeg",
                               "mkv", "video/mkv",
                               "mpv2", "video/mpeg",
                               "lsf", "video/x-la-asf",
                               "lsx", "video/x-la-asf",
                               "asf", "video/x-ms-asf",
                               "asr", "video/x-ms-asf",
                               "asx", "video/x-ms-asf",
                               "movie", "video/x-sgi-movie",
                               "rmvb", "video/vnd.rn-realvideo",
                               "rm", "video/vnd.rn-realvideo",
                               "viv", "video/vnd.vivo",
                               "vivo", "video/vnd.vivo",
                               "3g2", "video/3g2",
                               "3gp2", "video/3gp2",
                               "3gpp", "video/3gpp",
                               "amv", "video/amv",
                               "divx", "video/divx",
                               "drc", "video/drc",
                               "dv", "video/dv",
                               "f4v", "video/f4v",
                               "gvi", "video/gvi",
                               "gxf", "video/gxf",
                               "h264", "video/h264",
                               "h265", "video/h265",
                               "m1v", "video/m1v",
                               "m2v", "video/m2v",
                               "m2t", "video/m2t",
                               "m2ts", "video/m2ts",
                               "m4v", "video/m4v",
                               "mp2v", "video/mp2v",
                               "mp4v", "video/mp4v",
                               "mpeg1", "video/mpeg",
                               "mpeg2", "video/mpeg",
                               "mpeg4", "video/mpeg",
                               "mts", "video/mts",
                               "mtv", "video/mtv",
                               "mxf", "video/mxf",
                               "mxg", "video/mxg",
                               "nsv", "video/nsv",
                               "nuv", "video/nuv",
                               "ogm", "video/ogm",
                               "ogv", "video/ogv",
                               "ogx", "video/ogx",
                               "rec", "video/rec",
                               "tod", "video/tod",
                               "ts", "video/ts",
                               "tts", "video/tts",
                               "vob", "video/vob",
                               "vro", "video/vro",
                               "webm", "video/webm",
                               "wm", "video/wm",
                               "wtv", "video/wtv",
                               "swf", "application/x-shockwave-flash",
                               "flv", "video/x-flv",
                               "xesc", "video/xesc"};

        if(path.contains(".")) {
            QString last_str = path.split(".").last().toLower();
            if(strList.contains(last_str)) {
                return true;
            }
        }
        return false;
    }

3.2、视频核心类调用

qDebug() << "list:" << QDateTime::currentDateTime().toString("hh:mm:ss zzz");
    switch (type) {
    case Video:{    // 0 - 视频
        QList<SMultiMediaVideo::VideoList> vList;
        foreach(STableWidget::DataList curV, list) {
            SMultiMediaVideo::VideoList newV;
            if(curV.deviceType == STableWidget::DEVICE_WIN) {
                if(!isVideo(curV.f_id)) {
                    continue;
                }
            } else {
                if(!isVideo(curV.title)) {
                    continue;
                }
            }
            newV.f_id = curV.f_id;
            newV.icon = curV.icon;
            newV.isNet = curV.deviceType != STableWidget::DEVICE_WIN;
            newV.root = curV.root;
            newV.title = curV.title;
            vList.append(newV);
        }
        m_multiMediaVideo->setList(vList);
    }break;
    case Audio:{    // 1 - 音频
    	...
    }break;
    case picture:{    // 2 - 图片
    	...
    }break;
    ...

3.3、视频核心类

3.3.1、头文件

#ifndef SMULTIMEDIAVIDEO_H
#define SMULTIMEDIAVIDEO_H
/****************************************
 * pro:视频浏览器
 * time:2018-8
 * author:沙振宇
 */
#include <QWidget>
#include <QTimer>
#include <QPushButton>
#include <QPropertyAnimation>
#include "sys/smultimediathread.h"
#ifdef Q_OS_WIN
#include <windows.h>
#endif

namespace Ui {
class SMultiMediaVideo;
}

class SMultiMediaVideo : public QWidget
{
    Q_OBJECT

public:
    explicit SMultiMediaVideo(QWidget *parent = nullptr);
    ~SMultiMediaVideo();

    // 播放列表
    struct VideoList{
        QString title;
        QIcon icon;
        QString root;
        QString f_id;
        bool isNet;
    };

    void setText(QString title, QIcon icon);
    void setUrl(QString path, bool isNet);
    void setList(QList<VideoList> list);
    void freeVlc();
signals:
    void sigChange(QString root, QString pid);
public slots:
    void onTranslate();
protected:
    // 快捷键
    void keyPressEvent(QKeyEvent *event);
    //显示
    void showEvent(QShowEvent *event);
    //重新设置尺寸
    void resizeEvent(QResizeEvent *event);
    // 八角拖动
    bool nativeEvent(const QByteArray &eventType, void *message, long *result);
private slots:
    void on_pushButton_back_clicked();
    void on_pushButton_play_clicked();
    void on_pushButton_go_clicked();
    void on_pushButton_vol_clicked();
    void on_pushButton_screen_clicked();
    void on_pushButton_reload_clicked();
    void on_pushButton_ok_clicked();    // 透明层

    void onMinClicked();
    void onMaxClicked();
    void onCloseClicked();

    void onPlaying();
    void onGetTimer();
    void onCheckMouseTimer();
    void onError();

    void on_pushButton_left_clicked();
    void on_pushButton_right_clicked();
    void on_horizontalSlider_sliderMoved(int position);
    void on_horizontalSlider_vol_sliderMoved(int position);

private:
    void initUI();
    void setMoveAnimation(bool isShow);
    void moveAllItem();
    int getCurrentRow();    // 获取当前
    void setVideoChange(int index); // 切换列表
private:
    Ui::SMultiMediaVideo *ui;
    int m_boundaryWidth = 4; // 边框缩放范围的宽度
    bool m_playing = false;
    QTimer* m_checkMouseTimer = Q_NULLPTR;
    QTimer* m_loadingTimer = Q_NULLPTR;
    SMultiMediaThread* m_thread = Q_NULLPTR;
    LASTINPUTINFO m_lpi;
    bool m_isNet = false;
    QString m_path;
    QPoint m_pressPos;
    QList<VideoList> m_videoList;

    // 动画效果
    QPropertyAnimation *m_upAnimation;
    QPropertyAnimation *m_downAnimation;

    // 加载动画播放到第几个了
    QString m_movie_index;
};

#endif // SMULTIMEDIAVIDEO_H

3.3.2、源文件

#include "smultimediavideo.h"
#include "ui_smultimediavideo.h"
#include <QMouseEvent>
#include <QDir>
#include <QFile>
#include <QDateTime>
#include <QDebug>
#ifdef Q_OS_WIN
#include <windowsx.h>
#include <qt_windows.h>
#endif

SMultiMediaVideo::SMultiMediaVideo(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SMultiMediaVideo)
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":/sqrc/title/logo2x.png")); //设置窗口图标,会发生窗口图标改变事件,随之自定义标题栏的图标会更新
    setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
    setWindowModality(Qt::WindowModal);

    ui->pushButton_ok->setAttribute(Qt::WA_TranslucentBackground, true);
    ui->pushButton_ok->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    ui->pushButton_ok->hide();
    ui->widget_down->setAttribute(Qt::WA_TranslucentBackground, true);
    ui->widget_down->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    ui->widget_down->hide();
    ui->widget_up->setAttribute(Qt::WA_TranslucentBackground, true);
    ui->widget_up->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    ui->widget_up->hide();
    ui->pushButton_left->setAttribute(Qt::WA_TranslucentBackground, true);
    ui->pushButton_left->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    ui->pushButton_left->hide();
    ui->pushButton_right->setAttribute(Qt::WA_TranslucentBackground, true);
    ui->pushButton_right->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    ui->pushButton_right->hide();

    m_thread = new SMultiMediaThread();
    m_thread->setWidget(ui->label_video);
    connect(m_thread, &SMultiMediaThread::sigPlaying, this, &SMultiMediaVideo::onPlaying);
    connect(m_thread, &SMultiMediaThread::sigGetTimer, this, &SMultiMediaVideo::onGetTimer);
    connect(m_thread, &SMultiMediaThread::sigEncounteredError, this, &SMultiMediaVideo::onError);
    connect(m_thread, &SMultiMediaThread::sigEnding, this, [=](){
        qDebug() << "sigEnding";
//        on_horizontalSlider_sliderMoved(0);
    });
    connect(ui->pushButton_ok, &SMultimediaVideoBtn::sigDoubleClick, this, [=](){
        on_pushButton_screen_clicked();
        on_pushButton_play_clicked();
        this->activateWindow();
    });
    connect(ui->widget_up, &SMultiMediaVideoTitle::sigMin, this, &SMultiMediaVideo::onMinClicked);
    connect(ui->widget_up, &SMultiMediaVideoTitle::sigMax, this, &SMultiMediaVideo::onMaxClicked);
    connect(ui->widget_up, &SMultiMediaVideoTitle::sigClose, this, &SMultiMediaVideo::onCloseClicked);
    connect(ui->widget_up, &SMultiMediaVideoTitle::sigMove, this, [=](int x, int y) {
        if(!this->isFullScreen()) {
            this->move(x, y);
            this->moveAllItem();
        }
    });

    m_thread->start();

    m_checkMouseTimer = new QTimer(this);
    connect(m_checkMouseTimer, &QTimer::timeout, this, &SMultiMediaVideo::onCheckMouseTimer);
    m_checkMouseTimer->setInterval(300);
    m_checkMouseTimer->stop();
    m_upAnimation = new QPropertyAnimation(ui->widget_up,"windowOpacity");
    m_downAnimation  = new QPropertyAnimation(ui->widget_down,"windowOpacity");

    m_loadingTimer = new QTimer(this);
    m_loadingTimer->setInterval(40);
    connect(m_loadingTimer, &QTimer::timeout, this, [=](){
        if(m_movie_index.isNull()) {
            m_movie_index = ":/sqrc/video/gif/video_loading_00.png";
            ui->label_loading_img->setStyleSheet("");
        } else {
            int cur = m_movie_index.split(":/sqrc/video/gif/video_loading_").last().split(".png").first().toInt();
            cur++;
            QString nb_c = QString::number(cur);
            if(cur < 10) {
                nb_c.prepend("0");
            } else if (cur > 25) {
                nb_c = "00";
            }
            m_movie_index = ":/sqrc/video/gif/video_loading_" + nb_c + ".png";
        }
        QImage tmpP(m_movie_index);
        tmpP = tmpP.scaled(ui->label_loading_img->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
        ui->label_loading_img->setPixmap(QPixmap::fromImage(tmpP));
    });

    int duration = 300;
    m_upAnimation->setDuration(duration);
    m_downAnimation->setDuration(duration);
    m_upAnimation->setEasingCurve(QEasingCurve::InOutCirc);
    m_downAnimation->setEasingCurve(QEasingCurve::InOutCirc);
    connect(m_upAnimation, &QPropertyAnimation::finished, this, [=](){
        ui->widget_up->setVisible(!ui->widget_up->isVisible());
        ui->widget_down->setVisible(!ui->widget_down->isVisible());
        ui->pushButton_left->setVisible(!ui->pushButton_left->isVisible());
        ui->pushButton_right->setVisible(!ui->pushButton_right->isVisible());
    });

    m_lpi.cbSize = sizeof(m_lpi);

    onTranslate();
    this->setFocusPolicy(Qt::StrongFocus);
    this->resize(1000, 600);
}

SMultiMediaVideo::~SMultiMediaVideo()
{
    if(m_thread) {
        delete m_thread;
        m_thread = Q_NULLPTR;
    }
    delete ui;
}

void SMultiMediaVideo::setText(QString title, QIcon icon)
{
    this->freeVlc();
    ui->widget_up->setText(title);
    if(icon.isNull()){
        ui->label_thum->setPixmap(QPixmap::fromImage(QImage()));
    } else {
        ui->label_thum->setPixmap(icon.pixmap(120,120));
    }
    ui->stackedWidget->show();
    ui->stackedWidget->setCurrentIndex(0);  // 加载页
    m_loadingTimer->start();
    ui->horizontalSlider->setValue(0);
    ui->label_start->setText("");
    ui->label_end->setText("");
    if(m_playing) {
        on_pushButton_play_clicked();
    }
}

void SMultiMediaVideo::setUrl(QString path, bool isNet)
{
    qDebug() << "m_path:" << path << isNet << QDateTime::currentDateTime().toString("hh:mm:ss");

    m_path = path;
    m_isNet = isNet;
    if(path == "") {
        ui->pushButton_ok->hide();
        ui->stackedWidget->setCurrentIndex(1);  // 失败
        m_loadingTimer->stop();
    }
    ui->widget_down->show();
    ui->widget_up->show();
    ui->pushButton_left->show();
    ui->pushButton_right->show();

    bool isok = m_thread->load(path, isNet);
    if(isok) {
        qDebug() << "Video setUrl is load OK";
        on_pushButton_play_clicked();
        this->moveAllItem();
        ui->pushButton_ok->show();
    } else {
        qDebug() << "Video setUrl is load error";
        ui->pushButton_ok->hide();
        ui->stackedWidget->setCurrentIndex(1);  // 失败
        m_loadingTimer->stop();
    }
}

void SMultiMediaVideo::setList(QList<VideoList> list)
{
    m_videoList.clear();
    m_videoList = list;
}

void SMultiMediaVideo::freeVlc()
{
    m_thread->stop();
    m_thread->freeVlc();
}

void SMultiMediaVideo::onTranslate()
{
    ui->widget_up->onTranslate(this->window()->isMaximized());
    ui->retranslateUi(this);
}

void SMultiMediaVideo::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Escape:
        qDebug() << "SMultiMediaVideo keyPressEvent Key_Escape";
        if(this->isFullScreen()) {
            // 如果是全屏,则normal
            this->showNormal();
            ui->pushButton_screen->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/big.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/big.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/big.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
        }
        break;
    case Qt::Key_Left:
        qDebug() << "SMultiMediaVideo keyPressEvent Key_Left";
        on_pushButton_back_clicked();
        break;
    case Qt::Key_Right:
        qDebug() << "SMultiMediaVideo keyPressEvent Key_Right";
        on_pushButton_go_clicked();
        break;
    case Qt::Key_Enter:
        qDebug() << "SMultiMediaVideo keyPressEvent Enter"; // 大回车
        on_pushButton_screen_clicked();
        break;
    case Qt::Key_Return:
        qDebug() << "SMultiMediaVideo keyPressEvent Return"; // 小回车
        on_pushButton_screen_clicked();
        break;
    case Qt::Key_Space:
        qDebug() << "SMultiMediaVideo keyPressEvent Key_Space";
        on_pushButton_play_clicked();
        break;
    }
    return QWidget::keyPressEvent(event);
}

void SMultiMediaVideo::showEvent(QShowEvent *event)
{
    Q_UNUSED(event); //没有实质性的作用,只是用来允许event可以不使用,用来避免编译器警告

    // 检测各种状态
    initUI();
}

void SMultiMediaVideo::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event)
    int wid = this->width() - 2;
    int hei = this->height() - 2;

    ui->stackedWidget->move(wid/2 - ui->stackedWidget->width()/2 - 10, hei/2-ui->stackedWidget->height()/2);

    ui->horizontalSlider->resize(wid - 40, ui->horizontalSlider->height());
    ui->horizontalSlider->move(20, 20);

    ui->label_start->move(20, 20 + ui->horizontalSlider->height());
    ui->label_end->move(wid - 20 - ui->label_end->width(), ui->label_start->y());

    ui->widget_play->move(wid/2 - ui->widget_play->width()/2 - 10, ui->label_start->y() + ui->label_start->height());
    ui->widget_vol->move(wid - ui->widget_vol->width(), ui->widget_play->y());

    ui->label_video->resize(wid, hei);
    ui->label_video->move(1, 1);

    this->moveAllItem();
}

bool SMultiMediaVideo::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG *msg = static_cast<MSG *>(message);
    if(msg->message == WM_NCHITTEST && (!this->isFullScreen()) && (!this->window()->isMaximized())) {
        int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
        int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
        if(xPos < m_boundaryWidth && yPos<m_boundaryWidth)                    //左上角
            *result = HTTOPLEFT;
        else if(xPos>=width()-m_boundaryWidth&&yPos<m_boundaryWidth)          //右上角
            *result = HTTOPRIGHT;
        else if(xPos<m_boundaryWidth&&yPos>=height()-m_boundaryWidth)         //左下角
            *result = HTBOTTOMLEFT;
        else if(xPos>=width()-m_boundaryWidth&&yPos>=height()-m_boundaryWidth)//右下角
            *result = HTBOTTOMRIGHT;
        else if(xPos < m_boundaryWidth)                                     //左边
            *result =  HTLEFT;
        else if(xPos>=width()-m_boundaryWidth)                              //右边
            *result = HTRIGHT;
        else if(yPos<m_boundaryWidth)                                       //上边
            *result = HTTOP;
        else if(yPos>=height()-m_boundaryWidth)                             //下边
            *result = HTBOTTOM;
        else              //其他部分不做处理,返回false,留给其他事件处理器处理
            return QWidget::nativeEvent(eventType, message, result);
        return true;
    }
    return QWidget::nativeEvent(eventType, message, result);
}

void SMultiMediaVideo::on_pushButton_back_clicked()
{
    int pos = ui->horizontalSlider->value();
    if(pos > 0) {
        int newP = pos - 1;
        m_thread->setPosition(newP);
        ui->horizontalSlider->setValue(newP);
    }
}

void SMultiMediaVideo::on_pushButton_play_clicked()
{
    if(m_playing) {
        m_thread->pause();
        m_playing = false;
        // 暂停中,播放按钮
        ui->pushButton_play->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/play.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/play.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/play.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
    } else {
        m_thread->play();
        m_playing = true;
        // 播放中,暂停按钮
        ui->pushButton_play->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/pause.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/pause.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/pause.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
    }
}

void SMultiMediaVideo::on_pushButton_go_clicked()
{
    int pos = ui->horizontalSlider->value();
    if(pos < 99) {
        int newP = pos + 1;
        m_thread->setPosition(newP);
        ui->horizontalSlider->setValue(newP);
    }
}

void SMultiMediaVideo::on_pushButton_vol_clicked()
{
    if(ui->horizontalSlider_vol->value() == 0) {
        // 已经是静音,点击按钮变成播放声音
        ui->horizontalSlider_vol->setValue(80);
        ui->pushButton_vol->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/vol.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/vol.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/vol.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");

    } else {
        // 点击静音
        ui->horizontalSlider_vol->setValue(0);
        ui->pushButton_vol->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/vol0.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/vol0.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/vol0.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
    }
}

void SMultiMediaVideo::on_pushButton_screen_clicked()
{
    if(this->isFullScreen()) {
        // 如果是全屏,则normal
        this->showNormal();
        ui->pushButton_screen->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/big.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/big.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/big.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
    } else {
        // 如果normal则全屏
        this->showFullScreen();
        ui->pushButton_screen->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/scale.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/scale.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/scale.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
    }
}

void SMultiMediaVideo::onMinClicked()
{
    QWidget *pWindow = this->window(); //获得标题栏所在的窗口
    pWindow->showMinimized(); //最小化
}

void SMultiMediaVideo::onMaxClicked()
{
    qDebug() << "onMaxClicked";
    QWidget *pWindow = this->window(); //获得标题栏所在的窗口

    if(this->isFullScreen()) {
        qDebug() << "isFullScreen";
        on_pushButton_screen_clicked();
        return;
    }
    bool bMaximize = pWindow->isMaximized(); //判断窗口是不是最大化状态,是则返回true,否则返回false
    qDebug() << "bMaximize" << bMaximize;
    if (bMaximize) {
        pWindow->showNormal();
    } else {
        pWindow->showMaximized();
    }
}

void SMultiMediaVideo::onCloseClicked()
{
    ui->widget_up->hide();
    ui->widget_down->hide();
    ui->pushButton_ok->hide();
    ui->pushButton_left->hide();
    ui->pushButton_right->hide();
    m_thread->stop();
    m_checkMouseTimer->stop();
    m_loadingTimer->stop();
    QWidget *pWindow = this->window(); //获得标题栏所在的窗口
    pWindow->hide(); //窗口关闭
}

void SMultiMediaVideo::on_pushButton_reload_clicked()
{
    qDebug() << "on_pushButton_reload_clicked OK";
    ui->stackedWidget->setCurrentIndex(0);
    m_loadingTimer->start();
    ui->pushButton_ok->show();
//    m_thread->stop();
//    m_thread->freeVlc();

    if(m_playing) {
        on_pushButton_play_clicked();
    }
    QTimer::singleShot(1000, this, [=](){
        bool isok = m_thread->load(m_path, m_isNet);
        if(isok) {
            qDebug() << "setUrl on_pushButton_reload_clicked OK";
            on_pushButton_play_clicked();
            ui->pushButton_ok->show();
        } else {
            qDebug() << "setUrl on_pushButton_reload_clicked error";
            ui->pushButton_ok->hide();
            ui->stackedWidget->setCurrentIndex(1);
            m_loadingTimer->stop();
        }
    });
}

void SMultiMediaVideo::onPlaying()
{
    qDebug() << m_thread->getLength();
    qDebug() << "onPlaying:" << QDateTime::currentDateTime().toString("hh:mm:ss");
    QString str = QDateTime::fromTime_t(m_thread->getLength()).toUTC().toString("hh:mm:ss");
    ui->label_end->setText(str);
    ui->horizontalSlider_vol->setValue(m_thread->getVolume());
    ui->stackedWidget->hide();
    m_loadingTimer->stop();
    m_checkMouseTimer->start();
}

void SMultiMediaVideo::onGetTimer()
{
    QString str = QDateTime::fromTime_t(m_thread->getTime()).toUTC().toString("hh:mm:ss");
    ui->label_start->setText(str);
    ui->horizontalSlider->setValue(m_thread->getPosition());
}

void SMultiMediaVideo::onCheckMouseTimer()
{
//    1. BOOL GetInputState(VOID);
//    函数功能:该函数确定在当前线程的消息队列中是否有要处理的鼠标,键盘消息.如果检测到输入的话,则返回值为非零值,否则返回值为零

//    2.BOOL WINAPI GetLastInputInfo( __out PLASTINPUTINFO lpi);
//    函数功能:获取上次输入操作的时间
//    bool isUp = ui->widget_up->geometry().contains(this->mapFromGlobal(QCursor::pos()));
//    bool isDown = ui->widget_down->geometry().contains(this->mapFromGlobal(QCursor::pos()));
//    if(isUp || isDown) {
//        // 再焦点上,不移动
//    } else {
    if(ui->stackedWidget->isVisible()) {
        ui->widget_up->show();
        ui->widget_down->show();
        return;
    }
        uint gap = 0;
        if(GetLastInputInfo(&m_lpi)) {
            gap = (GetTickCount() - m_lpi.dwTime);
        }
        uint gap2 = 500;
        setMoveAnimation(gap < gap2);
//    }
}

void SMultiMediaVideo::onError()
{
    qDebug() << "setUrl is load error";

    ui->stackedWidget->setCurrentIndex(1);  // 失败
    m_loadingTimer->stop();
    ui->pushButton_ok->hide();
    qDebug() << "update";
    this->update();
}

void SMultiMediaVideo::initUI()
{
    QFont f;
    f.setFamily("微软雅黑");
    f.setPixelSize(15);
    f.setBold(false);
    ui->label_start->setFont(f);
    ui->label_end->setFont(f);
    ui->label_failed->setFont(f);
    ui->label_loading->setFont(f);
    ui->pushButton_reload->setFont(f);
}

void SMultiMediaVideo::setMoveAnimation(bool isShow)
{
    if((isShow && ui->widget_up->isVisible()) || (!isShow && !ui->widget_up->isVisible())) {
        return;
    }
    int wid = this->width() - 2;
    ui->widget_up->resize(wid, ui->widget_up->height());
    ui->widget_down->resize(wid, ui->widget_down->height());
    if(isShow) {
        m_upAnimation->setStartValue(0);
        m_upAnimation->setEndValue(1);
        m_downAnimation->setStartValue(0);
        m_downAnimation->setEndValue(1);
    } else {
        m_upAnimation->setStartValue(1);
        m_upAnimation->setEndValue(0);
        m_downAnimation->setStartValue(1);
        m_downAnimation->setEndValue(0);
    }
    m_upAnimation->start();
    m_downAnimation->start();
}

void SMultiMediaVideo::moveAllItem()
{
    // 透明层-负责点击屏幕做出各种事件
    ui->pushButton_ok->resize(this->width() - 2, this->height() - 2 - ui->widget_up->height() - ui->widget_down->height());
    ui->pushButton_ok->move(this->mapToGlobal(QPoint(1, 1 + ui->widget_up->height())));

    // 底部操作栏
    ui->widget_down->resize(this->width() - 2, ui->widget_down->height());
    ui->widget_down->move(this->mapToGlobal(QPoint(1, this->height() - 2 - ui->widget_down->height())));
    ui->label_downbg->resize(ui->widget_down->size());
    ui->label_downbg->move(0,0);

    // 顶部操作栏
    ui->widget_up->resize(this->width() - 2, ui->widget_up->height());
    ui->widget_up->move(this->mapToGlobal(QPoint(1, 1)));

    // 左右两侧按钮
    ui->pushButton_left->move(this->mapToGlobal(QPoint(24, this->height()/2 -1 - ui->pushButton_left->height()/2)));
    ui->pushButton_right->move(this->mapToGlobal(QPoint(this->width() - 2 - 24 - ui->pushButton_right->width(), this->height()/2 -1 - ui->pushButton_left->height()/2)));
}

int SMultiMediaVideo::getCurrentRow()
{
    int cur_i = 0;
    for(int i = 0; i < m_videoList.count(); i++) {
        VideoList curV = m_videoList.at(i);
        QString tmp = m_path;   // win
        if(curV.isNet) {
            if(m_path.contains("file_id=")) {   // nas
                tmp = m_path.split("file_id=").last();
            }
        }
        if(curV.f_id == tmp) {
            cur_i = i;
            break;
        }
    }
    return cur_i;
}

void SMultiMediaVideo::setVideoChange(int index)
{
    VideoList curV = m_videoList.at(index);
    this->freeVlc();
    this->setText(curV.title, curV.icon);
    if(m_isNet) {
        qDebug() << "sigChange" << curV.root << curV.f_id;
        emit sigChange(curV.root, curV.f_id);
    } else {
        this->show();
        this->setUrl(curV.f_id, false);
        this->activateWindow();
    }
}

void SMultiMediaVideo::on_pushButton_ok_clicked()
{
    on_pushButton_play_clicked();
    this->activateWindow();
    ui->pushButton_left->raise();
    ui->pushButton_right->raise();
}

void SMultiMediaVideo::on_pushButton_left_clicked()
{
    qDebug() << "on_pushButton_left_clicked" << m_videoList.count();
    int cur_i = this->getCurrentRow();
    qDebug() << "cur_i" << cur_i;

    if(cur_i < 1) {
        cur_i = 1;
        return;
    }
    cur_i--;

    this->setVideoChange(cur_i);
}

void SMultiMediaVideo::on_pushButton_right_clicked()
{
    qDebug() << "on_pushButton_right_clicked" << m_videoList.count();
    int cur_i = this->getCurrentRow();
    qDebug() << "cur_i" << cur_i;

    if(cur_i > m_videoList.count() - 2) {
        cur_i = m_videoList.count() - 2;
        return;
    }
    cur_i++;

    this->setVideoChange(cur_i);
}

void SMultiMediaVideo::on_horizontalSlider_sliderMoved(int position)
{
    m_thread->setPosition(position);
}

void SMultiMediaVideo::on_horizontalSlider_vol_sliderMoved(int position)
{
    if(position == 0) {
        ui->pushButton_vol->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/vol0.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/vol0.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/vol0.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
    } else {
        ui->pushButton_vol->setStyleSheet("QPushButton{  \n	background-color: rgba(255,255,255,3);\n	image: url(:/sqrc/video/vol.png);\n    border-radius:2px;  \n    padding:0 0px;  \n    margin:0 0px;  \n	border:0px solid rgb(207,207,207);\n}\nQPushButton:hover{     \n	background-color: rgba(255,255,255,150);\n	image: url(:/sqrc/video/vol.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:0px solid rgb(220,220,220);\n} \nQPushButton:pressed{  \n	background-color: rgba(255,255,255,200);\n	image: url(:/sqrc/video/vol.png);\n    border-style: solid;  \n    border-radius:2px;  \n    padding:0 0px;  \n	border:1px solid rgb(220,220,220);\n}");
    }
    m_thread->setVolume(position);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/327079.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序快速入门03

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java项目分享》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、生命周期生…

【Java数据结构】04-图(Prim,Kruskal,Dijkstra,topo)

5 图 推荐辅助理解 【视频讲解】bilibili Dijkstra Prim 【手动可视化】Algorithm Visualizer &#xff08;https://algorithm-visualizer.org/&#xff09; 【手动可视化】Data Structure Visualizations (https://www.cs.usfca.edu/~galles/visualization/Algorithms.ht…

基于k8s Deployment的弹性扩缩容及滚动发布机制详解

k8s第一个重要设计思想&#xff1a;控制器模式。k8s里第一个控制器模式的完整实现&#xff1a;Deployment。它实现了k8s一大重要功能&#xff1a;Pod的“水平扩展/收缩”&#xff08;horizontal scaling out/in&#xff09;。该功能从PaaS时代开始就是一个平台级项目必备编排能…

cookie和session的工作过程和作用:弥补http无状态的不足

cookie是客户端浏览器保存服务端数据的一种机制。当通过浏览器去访问服务端时&#xff0c;服务端可以把状态数据以key-value的形式写入到cookie中&#xff0c;存储到浏览器。浏览器下次去服务服务端时&#xff0c;就可以把这些状态数据携带给服务器端&#xff0c;服务器端可以根…

OceanBase架构概览

了解一个系统或软件&#xff0c;比较好的一种方式是了解其架构&#xff0c;下图是官网上的架构图&#xff0c;基于V 4.2.1版本 OceanBase 使用通用服务器硬件&#xff0c;依赖本地存储&#xff0c;分布式部署在多个服务器上&#xff0c;每个服务器都是对等的&#xff0c;数据库…

如何画出优秀的系统架构图-架构师系列-学习总结

--- 后之视今&#xff0c;亦犹今之视昔&#xff01; 目录 早期系统架构图 早期系统架构视图 41视图解读 41架构视图缺点 现代系统架构图的指导实践 业务架构 例子 使用场景 画图技巧 客户端架构、前端架构 例子 使用场景 画图技巧 系统架构 例子 定义 使用场…

Keepalived 双机热备

本章主要内容&#xff1a; Keepalived 双机热备基础知识学会构建双机热备系统学会构建LVSHA 高可用群集 简介 在这个高度信息化的IT时代&#xff0c;企业的生产系统&#xff0c;业务运营&#xff0c;销售和支持&#xff0c;以及日常管理等环节越来越依赖于计算机和服务&#…

class_1:qt的安装及基本使用方式

一、选择组件&#xff1a; 1、windows编译工具&#xff1a;MinGW 7.30 32-bit MinGW 7.30 64-bit 2、QT源代码&#xff1a;sources 3、QT的绘图模块&#xff1a;QT charts 4、QT虚拟键盘&#xff1a;QT Virtual Keyboard 5、QT Creational 4.12.2 GDB 二、新建QT项目 文…

【MATLAB】 HANTS滤波算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 1 基本定义 HANTS滤波算法是一种时间序列谐波分析方法&#xff0c;它综合了平滑和滤波两种方法&#xff0c;能够充分利用遥感图像存在时间性和空间性的特点&#xff0c;将其空间上的分布规律和时间上的变化规律联系起来…

构建 Maven 项目时可能遇到的问题

文章目录 构建 Maven 项目时可能遇到的问题1. Maven 自动下载依赖后&#xff0c;在本地仓库中找不到2. 运行时报错如下&#xff1a;Error: java 不支持发行版本 53. 创建 Maven 项目后 pom.xml 文件为空4. 在 Settings 中 Update 了阿里云远程仓库&#xff0c;导致整个项目不能…

美国智库发布《用人工智能展望网络未来》的解析

文章目录 前言一、人工智能未来可能改善网络安全的方式二、人工智能可能损害网络安全的方式三、人工智能使用的七条建议四、人工智能的应用和有效使用AI五、安全有效地使用人工智能制定具体建议六、展望网络未来的人工智能&#xff08;一&#xff09;提高防御者的效率&#xff…

数据结构学习 jz29 顺时针打印矩阵

关键词&#xff1a;模拟 题目&#xff1a;螺旋遍历二维数组 简单题做了超过40分钟 调了很久 不好 方法一&#xff1a; 我自己做的。 思路&#xff1a; xy_t&#xff1a; 记录xy的方向&#xff0c;往右走&#xff0c;往下走&#xff0c;往左走&#xff0c;往上走 t控制方…

算法第十八天-打家劫舍Ⅱ

打家劫舍Ⅱ 题目要求 解题思路 [打家劫舍Ⅱ]是说两个相邻的房间不能同时偷&#xff0c;并且首尾两个房间是相邻的&#xff08;不能同时偷首尾房间&#xff09;明显是基于[打家劫舍Ⅰ]做的升级。[打家劫舍Ⅰ]也是说两个相邻的房间不能同时偷&#xff0c;但是首尾房间不是相邻的…

Java多线程基础:虚拟线程与平台线程解析

在这篇文章中&#xff0c;主要总结一些关于线程的概念&#xff0c;以及更近期的名为虚拟线程的特性。将了解平台线程和虚拟线程在性质上的区别&#xff0c;以及它们如何促进应用程序性能的改进 经典线程背景&#xff1a; 让我们以调用外部API或某些数据库交互的场景为例&…

JVM篇--Java内存区域高频面试题

java内存区域 1 Java 堆空间及 GC&#xff1f; 首先我们要知道java堆空间的产生过程&#xff1a; 即当通过java命令启动java进程的时候&#xff0c;就会为它分配内存&#xff0c;而分配内存的一部分就会用于创建堆空间&#xff0c;而当程序中创建对象的时候 就会从堆空间来分…

918. 环形子数组的最大和

参考题解&#xff1a;https://leetcode.cn/problems/maximum-sum-circular-subarray/solutions/1152143/wo-hua-yi-bian-jiu-kan-dong-de-ti-jie-ni-892u/ class Solution {public int maxSubarraySumCircular(int[] nums) {int n nums.length;int sum nums[0], minSum nums…

【目标跟踪】跨相机如何匹配像素

文章目录 前言一、计算思路二、代码三、结果 前言 本本篇博客介绍一种非常简单粗暴的方法&#xff0c;做到跨相机像素匹配。已知各相机内外参&#xff0c;计算共视区域像素投影&#xff08;不需要计算图像特征&#xff09;。废话不多说&#xff0c;直接来&#xff0c;见下图。…

快速入门Java NIO(Not I/O)的网络通信框架--Netty

Netty 入门 了解netty前需要对nio有一定认识,该笔记基础来自bilinbili黑马,在此基础上自己学习的笔记,添加了一些自己的理解 了解java 非阻塞io编程 1. 概述 1.1 Netty 是什么&#xff1f; Netty is an asynchronous event-driven network application framework for rapid …

掌握这些测试开发技能,从容应对工作难题!

各位小伙伴, 大家好, 本期为大家分享一些测试开发工程师在企业中通过哪些测试开发技能解决难题。 一.如何定位缺陷 在企业中, 小伙伴们在发现bug后, 需要定位到具体产生bug的原因, 在这种情况下, 我们可以通过以下几种方案: 1.通过代理抓包来分析 常用的抓包工具有: Charles…

R语言【paleobioDB】——pbdb_subtaxa():统计指定类群下的子类群数量

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_subtaxa (data, do.plot, col) Arguments…