admin 发表于 2022-10-15 20:27:17

基于Qt的视频播放器

#include "mainwindow.h"
#include <QCoreApplication>
#include <QFileInfoList>
#include <QDir>
#include <QTextEdit>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    Delay(1000);
    videoLayout();                      //视频播放器布局初始化

    mediaPlayerInit();                  //媒体初始化

    scanVideoFiles();                   //扫描本地视频

    pushButton->setCheckable(true);//设置播放、全屏按钮初始状态
    pushButton->setCheckable(true);

    connect(pushButton, &QPushButton::clicked,
            this,
            &MainWindow::btn_play_clicked);         //播放按钮槽函数
    connect(pushButton, &QPushButton::clicked,
            this,
            &MainWindow::btn_next_clicked);         //切换按钮槽函数
    connect(pushButton, &QPushButton::clicked,
            this,
            &MainWindow::btn_volmedown_clicked);    //音量减按钮槽函数
    connect(pushButton, &QPushButton::clicked,
            this,
            &MainWindow::btn_volmeup_clicked);      //音量加按钮槽函数
    connect(pushButton, &QPushButton::clicked,
            this,
            &MainWindow::btn_fullscreen_clicked);   //全屏按钮槽函数

    connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)),
            this,
            SLOT(listWidgetCliked(QListWidgetItem*)));          //播放列表项目被选中

    connect(videoPlayer, SIGNAL(stateChanged(QMediaPlayer::State)),
            this,
            SLOT(mediaPlayerStateChanged(QMediaPlayer::State)));//播放器状态改变

    connect(mediaPlaylist, SIGNAL(currentIndexChanged(int)),
            this,
            SLOT(mediaPlaylistCurrentIndexChanged(int)));       //媒体改变,更新播放列表的选中行

    connect(videoPlayer, SIGNAL(durationChanged(qint64)),
            this,
            SLOT(musicPlayerDurationChanged(qint64)));          //(总时间)

    connect(videoPlayer, SIGNAL(positionChanged(qint64)),
            this,
            SLOT(mediaPlayerPositionChanged(qint64)));          //(当前时间)

    connect(durationSlider, &QSlider::sliderReleased,
            this,
            &MainWindow::durationSliderReleased);               //滑块移动时更新视频显示位置

    connect(volumeSlider, &QSlider::sliderReleased,
            this,
            &MainWindow::volumeSliderReleased);               //滑块移动时更新音量
}

void MainWindow::Delay(int msec)
{   // 这个最准
    /*非阻塞方式延时,现在很多人推荐的方法*/
    QEventLoop loop;
    QTimer::singleShot(msec, &loop, SLOT(quit()));
    loop.exec();
}

MainWindow::~MainWindow()
{
}

void MainWindow::videoLayout()
{
    this->setGeometry(0, 0, 800, 480);
    //this->setMinimumSize(800, 480);
    //this->setMaximumSize(800, 480);
    QPalette pal;                               //设置调色板格式
    pal.setColor(QPalette::WindowText, Qt::white);

    for (int i = 0; i < 3; i++) {               //水平容器初始化
      hWidget = new QWidget();
      hWidget->setAutoFillBackground(true);
      hBoxLayout = new QHBoxLayout();
    }

    for (int i = 0; i < 2; i++) {               //垂直容器初始化
      vWidget = new QWidget();
      vWidget->setAutoFillBackground(true);
      vBoxLayout = new QVBoxLayout();
    }

    for (int i = 0; i < 2; i++) {               //Label
      label = new QLabel();
    }

    for (int i = 0; i < 5; i++) {               //按钮初始化
      pushButton = new QPushButton();
      pushButton->setMaximumSize(44, 44);
      pushButton->setMinimumSize(44, 44);
    }

    vWidget->setObjectName("vWidget0");      //设置对象名称
    vWidget->setObjectName("vWidget1");
    hWidget->setObjectName("hWidget1");
    hWidget->setObjectName("hWidget2");
    pushButton->setObjectName("btn_play");
    pushButton->setObjectName("btn_next");
    pushButton->setObjectName("btn_volumedown");
    pushButton->setObjectName("btn_volumeup");
    pushButton->setObjectName("btn_screen");

    QFont font;
    font.setPixelSize(18);

    label->setFont(font);                        //Label初始化(播放时间)
    label->setFont(font);

    //pal.setColor(QPalette::WindowText, Qt::white);
    label->setPalette(pal);
    label->setPalette(pal);

    label->setText("00:00");
    label->setText("/00:00");

    durationSlider = new QSlider(Qt::Horizontal);   //Slider初始化(播放时间条)
    durationSlider->setMaximumHeight(15);
    durationSlider->setObjectName("durationSlider");

    volumeSlider = new QSlider(Qt::Horizontal);   //Slider初始化(音量条)
    volumeSlider->setRange(0, 100);
    volumeSlider->setMaximumWidth(80);
    volumeSlider->setObjectName("volumeSlider");
    volumeSlider->setValue(50);

    listWidget = new QListWidget();               //ListWidget初始化(播放列表)
    listWidget->setObjectName("listWidget");
    listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);      //内容太大无法装下时,显示滚动条,否则不显示
    listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //listWidget->setFocusPolicy(Qt::NoFocus);
    videoWidget = new QVideoWidget();               //视频显示窗口
    videoWidget->setStyleSheet("border-image: none;"
                               "background: transparent;"
                               "border:none");

    /**************************视频区域布局*****************************/

    vWidget->setMinimumSize(300, 480);
    vWidget->setMaximumWidth(300);
    videoWidget->setMinimumSize(500, 480);

    hBoxLayout->addWidget(videoWidget);
    hBoxLayout->addWidget(vWidget);

    hWidget->setLayout(hBoxLayout);
    hBoxLayout->setContentsMargins(0, 0, 0, 0);

    setCentralWidget(hWidget);

    /**************************播放列表区域布局*****************************/

    QSpacerItem *vSpacer0 = new QSpacerItem(0, 80,
                                          QSizePolicy::Minimum,
                                          QSizePolicy::Maximum);
    vBoxLayout->addWidget(listWidget);
    vBoxLayout->addSpacerItem(vSpacer0);
    vBoxLayout->setContentsMargins(0, 0, 0, 0);//页边空白

    vWidget->setLayout(vBoxLayout);

    hWidget->setMaximumHeight(15);
    hWidget->setMinimumHeight(65);
    vBoxLayout->addWidget(hWidget);
    vBoxLayout->addWidget(hWidget);
    vBoxLayout->setAlignment(Qt::AlignCenter);//对齐方式

    vWidget->setLayout(vBoxLayout);
    vWidget->setParent(this);
    vWidget->setGeometry(0, this->height() - 80, this->width(), 80);
    vBoxLayout->setContentsMargins(0, 0, 0, 0);

    vWidget->raise();    //位于最上层

    /**************************滑块区域布局*****************************/

    hBoxLayout->addWidget(durationSlider);
    hBoxLayout->setContentsMargins(0, 0, 0, 0);
    hWidget->setLayout(hBoxLayout);

    /* H2布局 */    QSpacerItem *hSpacer0 = new QSpacerItem(300, 80,
                                          QSizePolicy::Expanding,
                                          QSizePolicy::Maximum);
    hBoxLayout->addSpacing(20);
    hBoxLayout->addWidget(pushButton);
    hBoxLayout->addSpacing(10);
    hBoxLayout->addWidget(pushButton);
    hBoxLayout->addSpacing(10);
    hBoxLayout->addWidget(pushButton);
    hBoxLayout->addWidget(volumeSlider);
    hBoxLayout->addWidget(pushButton);
    hBoxLayout->addWidget(label);
    hBoxLayout->addWidget(label);
    hBoxLayout->addSpacerItem(hSpacer0);
    hBoxLayout->addWidget(pushButton);
    hBoxLayout->addSpacing(20);
    hBoxLayout->setContentsMargins(0, 0, 0, 0);
    hBoxLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    hWidget->setLayout(hBoxLayout);
}

void MainWindow::mediaPlayerInit()            //媒体初始化
{
    videoPlayer = new QMediaPlayer(this);
    mediaPlaylist = new QMediaPlaylist(this);
    mediaPlaylist->clear();
    videoPlayer->setPlaylist(mediaPlaylist);                //设置视频播放器的列表为mediaPlaylist
    videoPlayer->setVideoOutput(videoWidget);               //设置视频输出窗口
    mediaPlaylist->setPlaybackMode(QMediaPlaylist::Loop);   //设置播放模式,Loop是列循环
    videoPlayer->setVolume(50);                           //设置默认软件音量为50%
}

void MainWindow::scanVideoFiles()               //扫描视频文件
{
    QDir dir(QCoreApplication::applicationDirPath() + "/myVideo");
    QDir dirbsolutePath(dir.absolutePath());
    /* 如果目录存在 */
    if (dirbsolutePath.exists()) {
      /* 定义过滤器 */
      QStringList filter;
      /* 包含所有xx后缀的文件 */
      filter << "*.mp4" << "*.mkv" << "*.wmv" << "*.avi" << "*.ts";
      /* 获取该目录下的所有文件 */
      QFileInfoList files = dirbsolutePath.entryInfoList(filter, QDir::Files);
      /* 遍历 */
      for (int i = 0; i < files.count(); i++) {
            MediaObjectInfo info;
            /* 使用utf-8编码 */
            info.fileName = QString::fromUtf8(files.at(i).fileName().toUtf8().data());
            info.filePath = QString::fromUtf8(files.at(i).filePath().toUtf8().data());
            /* 媒体列表添加视频 */
            if (mediaPlaylist->addMedia( QUrl::fromLocalFile(info.filePath))) {
                /* 添加到容器数组里储存 */
                mediaObjectInfo.append(info);
                /* 添加视频名字至列表 */
                listWidget->addItem(info.fileName);
            } else {
                qDebug()<< mediaPlaylist->errorString().toUtf8().data() << endl;
                qDebug()<< "Error number:" << mediaPlaylist->error() << endl;
            }
      }
    }
}

void MainWindow::btn_play_clicked()   /* 播放按钮 */
{
    int state = videoPlayer->state();   //获取视频播放状态
    switch (state) {
    case QMediaPlayer::StoppedState:    //视频状态如果为:停止
      videoPlayer->play();            //播放
      break;

    case QMediaPlayer::PlayingState:    //视频状态如果为:正在播放
      videoPlayer->pause();         //停止播放
      break;

    case QMediaPlayer::PausedState:   //视频状态如果为:暂停
      videoPlayer->play();            //播放
      break;
    }
}

void MainWindow::btn_next_clicked()         /* 切换按钮 */
{
    videoPlayer->stop();                  //停止播放
    int count = mediaPlaylist->mediaCount();//获取播放列表的视频数
    if (0 == count)                         //如果视频数为0
      return;                           //中断函数执行,返回调用函数处

    mediaPlaylist->next();
    videoPlayer->play();
}

void MainWindow::btn_volmedown_clicked()    /* 音量减按钮 */
{
    volumeSlider->setValue(volumeSlider->value() - 5);      //点击每次音量-5
    videoPlayer->setVolume(volumeSlider->value());
}

void MainWindow::btn_volmeup_clicked()      /* 音量加按钮 */
{
    volumeSlider->setValue(volumeSlider->value() + 5);      //点击每次音量+5
    videoPlayer->setVolume(volumeSlider->value());
}

void MainWindow::btn_fullscreen_clicked()   /* 全屏按钮 */
{
    vWidget->setVisible(!pushButton->isChecked());    //全屏/非全屏操作
}

void MainWindow::listWidgetCliked(QListWidgetItem *item)    //播放列表点击
{
    videoPlayer->stop();
    mediaPlaylist->setCurrentIndex(listWidget->row(item));
    videoPlayer->play();
}

void MainWindow::mediaPlayerStateChanged(QMediaPlayer::State state) //播放器状态改变
{
    switch (state) {
    case QMediaPlayer::StoppedState:
      pushButton->setChecked(false);
      break;

    case QMediaPlayer::PlayingState:
      pushButton->setChecked(true);
      break;

    case QMediaPlayer::PausedState:
      pushButton->setChecked(false);
      break;
    }
}

void MainWindow::mediaPlaylistCurrentIndexChanged(int index)    //媒体改变,更新播放列表的选中行
{
    if (-1 == index)
      return;
    listWidget->setCurrentRow(index);    //设置列表正在播放的项
}

void MainWindow::musicPlayerDurationChanged(qint64 duration)      //视频时间滑块(总时间)
{
    durationSlider->setRange(0, duration / 1000);
    int second= duration / 1000;
    int minute = second / 60;
    second %= 60;

    QString mediaDuration;
    mediaDuration.clear();

    if (minute >= 10)
      mediaDuration = QString::number(minute, 10);
    else
      mediaDuration = "0" + QString::number(minute, 10);

    if (second >= 10)
      mediaDuration += ":" + QString::number(second, 10);
    else
      mediaDuration += ":0" + QString::number(second, 10);

    label->setText("/" + mediaDuration);               //显示媒体总长度时间
}

void MainWindow::mediaPlayerPositionChanged(qint64 position)      //视频时间滑块(当前时间)
{
    if (!durationSlider->isSliderDown())
      durationSlider->setValue(position / 1000);

    int second= position / 1000;
    int minute = second / 60;
    second %= 60;

    QString mediaPosition;
    mediaPosition.clear();

    if (minute >= 10)
      mediaPosition = QString::number(minute, 10);
    else
      mediaPosition = "0" + QString::number(minute, 10);

    if (second >= 10)
      mediaPosition += ":" + QString::number(second, 10);
    else
      mediaPosition += ":0" + QString::number(second, 10);

    label->setText(mediaPosition);                     //显示现在播放的时间
}

void MainWindow::durationSliderReleased()
{
    videoPlayer->setPosition(durationSlider->value() * 1000);   //设置媒体播放的位置
}

void MainWindow::volumeSliderReleased()
{

    videoPlayer->setVolume(volumeSlider->value());            //设置音量
}


void MainWindow::resizeEvent(QResizeEvent *event)//重写窗口大小设置事件
{
    Q_UNUSED(event);
    vWidget->setGeometry(0, this->height() - 80, this->width(), 80);
}
页: [1]
查看完整版本: 基于Qt的视频播放器