QT实现MP4播放器

1、实现功能

播放本地MP4文件。

1、可以将文件添加到列表中,双击列表中的歌曲进行播放。

2、实现视频的播放与暂停。

3、上一首和下一首的按钮选择功能。

4、视频名称的滚动显示。

5、当前的播放时长和总时长。

6、播放模式的选择:单曲循环、随机播放、顺序播放。

7、使用了水平和垂直布局。

8、视频音量的控制。

9、使用非UI界面实现。

2、项目环境

Qt Creator 5.0.2

3、widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>
#include <QListWidget>
#include <QVideoWidget>
#include <QMediaPlayer>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
#include <QMessageBox>
#include <QHBoxLayout>
#include <QFileDialog>
#include <QTime>
#include <QTimer>
#include <QResizeEvent>
#include <QSizePolicy>
#include <QListWidgetItem>
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void get_duration(qint64 duration);
    void update_playslidexvalue(qint64 position);
    void basic();

private slots:
    void on_select_btn_clicked();
    void on_pre_btn_clicked();
    void on_next_btn_clicked();
    void onComboBoxIndexChanged(int index);
    void on_itemDouble_clicked(QListWidgetItem *item);
    void on_play_btn_clicked();
    void on_play_slidex_sliderMoved(int position);
private:
   QListWidget *list;
   QVideoWidget *video;
   QLabel *name_lab;
   QLabel *time_lab;
   QSlider *slider1;
   QSlider *slider2;
   QPushButton *select_btn;
   QPushButton *play_btn;
   QPushButton *pre_btn;
   QPushButton *next_btn;
   QComboBox *combox;

    QHBoxLayout *hbox1;
    QHBoxLayout *hbox2;
    QHBoxLayout *hbox3;

    QVBoxLayout *vbox;

    QMediaPlayer *player;
    QTimer *timer;
    QString song_name;
    int index;
    int lon;
    int hua;
    int mode;
};
#endif // WIDGET_H

4、widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
        this->setGeometry(0, 0, 800, 600);
        /*------------------------------------*/
        this->list =new QListWidget(this);//设置视频展示列表
       /*------------------------------------*/
        this->video =new QVideoWidget(this);//设置视频播放
        this->video->setWindowTitle("视频播放器");
        this->video->setStyleSheet("border:2px solid black");



         /*------------------------------------*/
        this->name_lab =new QLabel(this);//设置视频名滚动
        this->name_lab->setGeometry(10,380,200,40);
        this->name_lab->setText("视频名");
        /*------------------------------------*/
       this->time_lab =new QLabel(this);//设置播放时间
        this->time_lab->setGeometry(500,380,200,40);
        this->time_lab->setText("     ");



         /*------------------------------------*/
        this->slider1 = new QSlider(this);//播放时间的滑块
        this->slider1->setOrientation(Qt::Horizontal);
        this->slider1->setGeometry(10,440, 780, 30);
         /*------------------------------------*/


        this->select_btn =new QPushButton(this);//添加到列表
        this->select_btn->setGeometry(10,520,100,40);
         this->select_btn->setText("添加到列表");
        /*------------------------------------*/
        this->play_btn =new QPushButton(this);//  播放/暂停
        this->play_btn->setGeometry(130,520,100,40);
         this->play_btn->setText("播放");
        /*------------------------------------*/
        this->pre_btn =new QPushButton(this);//
        this->pre_btn->setGeometry(250,520,100,40);
         this->pre_btn->setText("上一首");
        /*------------------------------------*/
        this->next_btn =new QPushButton(this);//
        this->next_btn->setGeometry(370,520,100,40);
         this->next_btn->setText("下一首");
        /*------------------------------------*/
        this->combox =new QComboBox(this);//
        this->combox->setGeometry(500,520,100,50);
        this->combox->addItem("单曲循环");
        this->combox->addItem("顺序播放");
        this->combox->addItem("随机播放");
         /*------------------------------------*/
        this->slider2 = new QSlider(this);//播放声音的滑块
        this->slider2->setOrientation(Qt::Horizontal);
        this->slider2->setGeometry(620,520, 130, 40);
        /*------------------------------------*/


        //准备一个水平布局
        //给水平布局添加组件对象
        this->hbox1 = new QHBoxLayout;
        this->hbox1->addWidget(this->list,1);
        this->hbox1->addStretch();
        this->hbox1->addWidget(this->video,3);
         /*------------------------------------*/
        this->hbox2 = new QHBoxLayout;
        this->hbox2->addWidget(this->name_lab);
        this->hbox2->addWidget(this->time_lab);
         /*------------------------------------*/
        this->hbox3 = new QHBoxLayout;
        this->hbox3->addWidget(this->select_btn);
        this->hbox3->addWidget(this->play_btn);
        this->hbox3->addWidget(this->pre_btn);
        this->hbox3->addWidget(this->next_btn);
        this->hbox3->addWidget(this->combox);
        this->hbox3->addWidget(this->slider2);
         /*------------------------------------*/
        //准备一个垂直布局
        this->vbox = new QVBoxLayout;
        //给垂直布局添加组件、添加布局
        this->vbox->addLayout(this->hbox1);
        this->vbox->addLayout(this->hbox2);
        this->vbox->addWidget(this->slider1);
        this->vbox->addLayout(this->hbox3);
         /*------------------------------------*/
        //给界面设置布局为垂直布局
        this->setLayout(this->vbox);
      /*------------------------------------*/
      //实例化播放器对象
       this->player=new QMediaPlayer(this);
      /*------------------------------------*/
      this->timer=new QTimer(this);//实例化定时器对象
     /*------------------------------------*/
       this->index=0;//实例化Index
      this->lon=0;//实例化lon
      this->hua=0;//实例化hua
      this->mode=0;//实例化mode  默认为单曲循环
       this->player->setVolume(0);//声音默认为0
     /*------------------------------------*/
      //槽函数与信号关联
    connect(this->select_btn,&QPushButton::clicked,this,&Widget::on_select_btn_clicked);
    // connect(this->select_btn,&QPushButton::clicked,this,&Widget::on_select_btn_clicked);
   connect(this->list, &QListWidget::itemDoubleClicked, this,&Widget::on_itemDouble_clicked);
   connect(this->play_btn,&QPushButton::clicked,this,&Widget::on_play_btn_clicked);
   connect(this->player,&QMediaPlayer::durationChanged,this,&Widget::get_duration);

    connect(this->player,&QMediaPlayer::positionChanged,this,&Widget::update_playslidexvalue);
                                    //  位置改变
   connect(this->slider1,&QSlider::sliderMoved,this,&Widget::on_play_slidex_sliderMoved);

   connect(this->pre_btn,&QPushButton::clicked,this,&Widget::on_pre_btn_clicked);
   connect(this->next_btn,&QPushButton::clicked,this,&Widget::on_next_btn_clicked);

    connect(this->combox, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboBoxIndexChanged(int)));


   connect(this->timer,&QTimer::timeout,this,[=]()
    {
         //获取当前的播放时长以及歌曲的总时长
        qint64 pos =this->player->position();
        qint64 dur =this->player->duration();
        QString str = QTime(0,0,0,0).addMSecs(pos).toString("mm:ss")+
                 "/"+ QTime(0,0,0,0).addMSecs(dur).toString("mm:ss");
               //设置给时间标签去显示
        this->time_lab->setText(str);

        //歌曲名称的滚动显示
        this->index++;
        if(this->index==this->song_name.size())
        {
            this->index=0;
        }
        QString name=this->song_name.mid(this->index);
        this->name_lab->setText(name);

        if(dur==pos)
        {
            if(this->mode==0)
            {
                this->player->stop();
                this->player->play();

            }else if(this->mode==1)
            {
                this->player->pause();
               if(this->hua<this->lon-1)
               {
                    this->hua++;
               }
               else
               {
                    this->hua=0;
               }
               basic();

            }else if(this->mode==2)
            {
                this->hua=rand()%this->lon;
                basic();
            }

        }


    });


connect(this->slider2, &QSlider::sliderMoved, this->player, [=](qint64 position)
{
        //改变音量滑块的位置,调节音量的大小
        this->player->setVolume(position);
});


}

Widget::~Widget()
{

}

void Widget::get_duration(qint64 duration)
{ //获取歌曲时长
    //给滑块设置取值范围
    this->slider1->setRange(0,duration);
}

//根据歌曲的播放位置变化改变滑块的位置
void Widget::update_playslidexvalue(qint64 position)
{
   // 改变滑块的值
   this->slider1->setValue(position);

}

void Widget::basic()
{
    //给播放器设置媒体资源
     QListWidgetItem *item = this->list->item(this->hua);
     QString filePath = item->data(Qt::UserRole).toString();
    this->player->setMedia(QMediaContent(QUrl(filePath)));
    //给播放器设置画面输出
    this->player->setVideoOutput(this->video);
    //给滑块设置取值范围
    this->slider1->setValue(0);
    //获取歌曲名称
    this->song_name="                          "+QFileInfo(filePath).fileName();
    this->timer->start(1000);
    this->player->play();
    this->play_btn->setText("暂停");
}


void Widget::on_select_btn_clicked()
{
    //选择歌曲资源
   QStringList filePaths = QFileDialog::getOpenFileNames(this,"选择","./","MP4(*.mp4)");
   for(int i=0;i<filePaths.size();i++)
   {
       QString filePath=filePaths.at(i);
       QString fileName = QFileInfo(filePaths.at(i)).fileName();
       QListWidgetItem *item = new QListWidgetItem(QIcon("./icon/opn.jfif"), fileName);
       //将文件的完整路径存储在 QListwidgetItem 的用户数据中
        item->setData(Qt::UserRole,filePath);
        item->setData(Qt::UserRole+1,this->lon);
        this->lon++;
        this->list->addItem(item);
   }
}



void Widget::on_itemDouble_clicked(QListWidgetItem *item)
{
    this->player->pause();
    QString filePath = item->data(Qt::UserRole).toString();
    this->hua= item->data(Qt::UserRole + 1).toInt();
    basic();
}


void Widget::on_play_btn_clicked()
{
    if(this->lon!=0)
    {
        if(this->play_btn->text()=="播放")
        {
            //启动定时器
            this->timer->start(1000);
            this->player->play();
            this->play_btn->setText("暂停");
        }
        else if(this->play_btn->text()=="暂停")
        {
            this->player->pause();
            this->timer->stop();
            this->play_btn->setText("播放");
        }
    }
    else
    {
        QMessageBox::information(this, "播放", "请先选择视频");
    }
}

void Widget::on_pre_btn_clicked()
{
     this->player->pause();
    if(this->hua>0)
    {
       this->hua--;
       basic();
    }else
    {
        QMessageBox::information(this, "上一首", "这是第一首了");
    }
}

void Widget::on_next_btn_clicked()
{
    this->player->pause();
   if(this->hua<this->lon-1)
   {
        this->hua++;
        basic();
   }else
   {
       QMessageBox::information(this, "下一首", "这是最后一首了");
   }
}

void Widget::onComboBoxIndexChanged(int index)
{
           this->mode=index;
           switch (index)
           {
           case 0:
               qDebug() << "单曲循环模式被选中";
               break;
           case 1:
               qDebug() << "顺序播放模式被选中";
               break;
           case 2:
               qDebug() << "随机播放模式被选中";
               break;
           default:
               break;
           }
}



//根据滑块的位置变化改变歌曲的播放位置
void Widget::on_play_slidex_sliderMoved(int position)
{
    //改变歌曲的播放位置
    this->player->setPosition(position);
}
相关推荐
用余生去守护37 分钟前
python报错系列(16)--pyinstaller ????????
开发语言·python
数据小爬虫@42 分钟前
利用Python爬虫快速获取商品历史价格信息
开发语言·爬虫·python
向宇it44 分钟前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
莫名其妙小饼干1 小时前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql
十年一梦实验室1 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
最爱番茄味1 小时前
Python实例之函数基础打卡篇
开发语言·python
Oneforlove_twoforjob2 小时前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言
engchina2 小时前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
诚丞成3 小时前
计算世界之安生:C++继承的文水和智慧(上)
开发语言·c++