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

news2024/9/28 1:25:39

文章目录

  • 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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASP.NET进销存系统源码

ASP.NET进销存系统源码 功能介绍&#xff1a; 财务 销售清单&#xff0c;填写销售单&#xff0c;客户管理&#xff0c;添加客户资料 销售 销售清单&#xff0c;填写销售单&#xff0c;客户管理&#xff0c;添加客户资料 仓库 仓库结存&#xff0c;仓库盘点&#xff0c;盘点结…

App在线封装的革命性创新

随着移动互联网的蓬勃发展&#xff0c;App已经成为我们日常生活中不可或缺的一部分。从购物、交通、社交到娱乐&#xff0c;几乎每个人的智能手机都装载着数十个应用程序&#xff0c;以满足各式各样的需求。然而&#xff0c;对于许多非技术背景的企业家和小型企业而言&#xff…

【JAVA基础--计算机网络】--TCP三次握手+四次挥手

三次握手四次挥手 写在前面1. 三次握手1.1 作用&#xff1a; 为了在不可靠的信道上建立起可靠的连接&#xff1b;1.2 建立过程1.3 面试提问 2. 四次挥手2.1 作用&#xff1a;为了在不可靠的网络信道中进行可靠的连接断开确认2.2 断开过程2.3 面试提问 写在前面 三次握手建立连…

2.4G无线遥控器方案开发,稳定性强,可用于多种应用

2.4G遥控器是一种使用2.4GHz频段的无线遥控器&#xff0c;常用于遥控玩具、航模和家电等电子设备上。相比于传统的红外线遥控器&#xff0c;2.4G遥控器具有更强的穿透力和稳定性&#xff0c;可以在较远的距离内实现遥控操作&#xff0c;并且不会受到光线干扰。它由遥控器和接收…

【Leetcode】2182. 构造限制重复的字符串

文章目录 题目思路代码 题目 2182. 构造限制重复的字符串 问题&#xff1a;给你一个字符串 s 和一个整数 repeatLimit &#xff0c;用 s 中的字符构造一个新字符串 repeatLimitedString &#xff0c;使任何字母 连续 出现的次数都不超过 repeatLimit 次。你不必使用 s 中的全…

汽车专业翻译,如何选择好的翻译公司?

随着中国汽车市场的不断壮大和国际化的步伐加快&#xff0c;众多外国汽车品牌纷纷进军中国市场&#xff0c;与此同时&#xff0c;国内汽车企业也在积极拓展海外版图。在此背景下&#xff0c;汽车企业与国际客户、供应商和合作伙伴的交流日益频繁。因此&#xff0c;拥有一支专业…

个人的感悟观点,即将毕业的应届生的对自己未来方向的思考和认识

目录 复习历程思考 为什么我选择了考研 考完后我的状态 考完后我的做法 我对方向的看法&#xff08;拙见&#xff09; 复习历程思考 自我决定考研复习一刻开始。停更半年之久&#xff0c;甚至更长。没有分享自己的学习。在时常半年多的考研复习的过程中。我决定它带给我希…

传奇手游详细图文架设教程

开始架设 1. 架设条件 传世手游架设需要准备&#xff1a; linux 服务器&#xff0c;建议 CentOs 7.6 版本&#xff0c;游戏源码&#xff0c; 游戏运行大约占 2.5G 左右内存。 2. 安装宝塔及环境 宝塔是一个服务器运维管理软件&#xff0c;安装命令&#xff1a; yum inst…

步进电机相关知识 以及 TMC2660 步进电机驱动芯片驱动步进电机

步进电机相关知识 以及 TMC2660 步进电机驱动芯片驱动步进电机 前言一、步进电机基础知识1、电机常用概念2、步进电机小知识3、步进电机分类4、步进电机工作原理细分驱动步进电机 5、使用的步进电机型号以及相关参数 二、步进电机驱动芯片 TMC2660 和MCU端步进电机驱动芯片TMC2…

jenkins忘记admin密码

jenkins忘记admin密码&#xff0c;重置密码&#xff1a; 1.找打jenkins目录下面的config.xml [rootVM-0-15-centos .jenkins]# find ./* -name config.xml ./config.xml [rootVM-0-15-centos .jenkins]# pwd /root/.jenkins删除下面的这部分内容&#xff1a; [rootVM-0-15-c…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-8 可观测性与分离原理

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-8 可观测性与分离原理

前端远原生js爬取数据的小案例

使用方法 注意分页的字段需要在代码里面定制化修改&#xff0c;根据你爬取的接口&#xff0c;他的业务规则改代码中的字段。比如我这里总条数叫total&#xff0c;人家的不一定。返回的数据我这里是data.rows&#xff0c;看看人家的是叫什么字段&#xff0c;改改代码。再比如我这…

Rust-语句和表达式

if-else Rust中if-else表达式的作用是实现条件分支。if-else表达式的构成方式为&#xff1a;以if关键字开头&#xff0c;后面跟上条件表达式&#xff0c;后续是结果语句块&#xff0c;最后是可选的else块。条件表达式的类型必须是bool。 if-else结构还可以当表达式使用 loop …

JavaScript-3

Web API 基本认知 作用和分类 作用&#xff1a;就是使用 JS 去操作 html 和 浏览器分类&#xff1a;DOM ( 文档对象模型 )、BOM ( 浏览器对象模型 ) DOM 是什么 DOM ( Document Object Model —— 文档对象模型 )它是用来呈现以及与任意 HTML 或 XML 文档交互的 API通俗的说…

数据分析求职-知识脑图

今天和大家聊聊数据分析求职常见面试题&#xff0c;这是这个系列的第一篇文章&#xff0c;但是我不想开始就直接罗列题目&#xff0c;因为这样的文章实在太多了&#xff0c;同学们的兴趣程度肯定一般。所以&#xff0c;我想先和大家聊聊在准备面试题时候通常遇到的困扰&#xf…

部署 LVS-DR 群集

本章内容&#xff1a; -了解LVS-DR群集的工作原理 -会构建LVS-DR负载均衡群集 2.1 LVS-DR 集群 LVS-DR &#xff08; Linux Virtual Server Director Server &#xff09;工作模式&#xff0c;是生产环境中最常用的一 种工作模式。 2.1.1 &#xff0e; LVS-DR 工作原理 …

【C++】基础:STL字符串库string

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍STL字符串库string。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&am…

【Maven】004-基于 IDEA 构建 Maven 工程

【Maven】004-基于 IDEA 构建 Maven 工程 文章目录 【Maven】004-基于 IDEA 构建 Maven 工程一、概述1、项目构建2、命令方式项目构建命令war 包打包插件和 jdk 版本不匹配 二、项目构建1、命令方式2、IDEA 可视化方式3、构建产物 一、概述 1、项目构建 项目构建是将软件开发…

数据结构初探:揭开数据结构奥秘

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、算法模板、汇编语言 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 数组结构起源二. 基本概念和术语2.1 数据2.2 数据元素2.3 数据项2.4 …

点的旋转变换

情形一&#xff08;active or alibi transformation主动变换&#xff09; 在坐标系 x − y x-y x−y中&#xff0c;点 p 1 p_1 p1​逆时针旋转 α \alpha α后到达点 p 2 p_2 p2​。 p 1 p_1 p1​在 x − y x-y x−y中的表示与 p 2 p_2 p2​在 x ′ − y ′ x-y x′−y′中的表…