QT音视频

要在Qt项目中使用Qt多媒体模块,需要在项目配置文件中添加如下语句:Qt += multimedia,如果在项目中使用视频播放功能,还需要添加,Qt += multimediawidgets来使用QVideoWidget或QGraphicsVideoItem进行视频播放。

Qt多媒体模块包含多个类,下面是需要用到的主要类:

音频

相关的类

音频播放会使用如下两个类:

  • QMediaPlayer类:媒体播放器,主要用于播放歌曲、网络收音机等功能;

  • QMediaPlaylist类:专用于播放媒体内容的列表。

音频小项目

实现一个简易MP3播放器,功能如下:

  • 可以选择本地本地mp3格式文件;

  • 可以对设置播放、停止、暂停播放;

  • 调节音量大小、调整播放进度;

  • 显示播放时长以及总时长;

需要在.pro文件中加入QT += core gui multimedia

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

//前向声明
class QMediaPlayer;
class QSlider;
class QLabel;

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    //打开文件
    void openFile();
    //设置音量
    void setVolume(int value);
    //更新进度条的位置
    void updatePosition();
    //更新进度条的范围
    void updateDuration(qint64 duration);
    //设置进度条的位置
    void seekPosition();
private:
    QMediaPlayer *m_player;//媒体播放器
    QSlider *m_volumeSlider;//声音滑动条
    QSlider *m_positionSlider;//进度滑动条
    QLabel *m_timeLabel;//时间标签
};
#endif // WIDGET_H
cpp 复制代码
#include "widget.h"
#include <QMediaPlayer>
#include <QSlider>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QTimer>
#include <QTime>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("MP3音频播放器");
    resize(400, 300);

    //初始化播放器
    m_player = new QMediaPlayer(this);

    //创建四个按钮分别显示"打开文件"、"播放"、"暂停","停止"
    QPushButton *openButton = new QPushButton("打开文件");
    QPushButton *playButton = new QPushButton("播放");
    QPushButton *pauseButton = new QPushButton("暂停");
    QPushButton *stopButton = new QPushButton("停止");

    //声音滑动条
    m_volumeSlider = new QSlider(Qt::Horizontal);
    //进度滑动条
    m_positionSlider = new QSlider(Qt::Horizontal);
    //时间标签(当前播放时长/总时长)
    m_timeLabel = new QLabel("00:00/00:00");

    // 设置音量滑动条范围和初始值
    m_volumeSlider->setRange(0, 100);
    m_volumeSlider->setValue(50);

    //设置播放音量
    m_player->setVolume(30);

    //启用播放进度条
    m_positionSlider->setEnabled(true);
    //设置播放进度的范围
    m_positionSlider->setRange(0, 100);

    // 布局
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(openButton);
    layout->addWidget(playButton);
    layout->addWidget(pauseButton);
    layout->addWidget(stopButton);
    layout->addWidget(new QLabel("音量:"));
    layout->addWidget(m_volumeSlider);
    layout->addWidget(new QLabel("进度:"));
    layout->addWidget(m_positionSlider);
    layout->addWidget(m_timeLabel);
    setLayout(layout);

    // 连接信号与槽
    connect(openButton, &QPushButton::clicked, this, &Widget::openFile);
    connect(playButton, &QPushButton::clicked, m_player, &QMediaPlayer::play);
    connect(pauseButton, &QPushButton::clicked, m_player, &QMediaPlayer::pause);
    connect(stopButton, &QPushButton::clicked, m_player, &QMediaPlayer::stop);
    connect(m_volumeSlider, &QSlider::valueChanged, this, &Widget::setVolume);
    connect(m_player, &QMediaPlayer::positionChanged, this, &Widget::updatePosition);
    connect(m_player, &QMediaPlayer::durationChanged, this, &Widget::updateDuration);
    //连接进度条拖动信号
    connect(m_positionSlider, &QSlider::sliderReleased, this, &Widget::seekPosition);


    //定时器用于更新进度条
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &Widget::updatePosition);
    //每1秒更新一次
    timer->start(1000);
}

Widget::~Widget()
{
}

void Widget::openFile()
{
    QString filePath =
            QFileDialog::getOpenFileName(this, "打开mp3文件",
                                         "", "MP3文件(*.mp3)");
    if(!filePath.isEmpty())
    {
        m_player->setMedia(QUrl::fromLocalFile(filePath));
        //打开即播放
        m_player->play();
    }
}

void Widget::setVolume(int value)
{
    m_player->setVolume(value);
}

void Widget::updatePosition()
{
    // 如果用户正在拖动进度条,则跳过自动更新
    if(m_positionSlider->isSliderDown())
        return;

    if(m_player->duration() > 0)
    {
        //将播放进度转换为百分比形式,这是乘以100的作用,不然就是小数
        int position = (m_player->position() * 100)/m_player->duration();
        m_positionSlider->setValue(position);

        // 更新时间显示
        //当前时间,使用position获取
        QTime currentTime(0, 0);
        currentTime = currentTime.addMSecs(m_player->position());
        //总时间,使用duration获取
        QTime totalTime(0, 0);
        totalTime = totalTime.addMSecs(m_player->duration());
        m_timeLabel->setText(currentTime.toString("mm:ss")
                           + "/" + totalTime.toString("mm:ss"));
    }
}

void Widget::updateDuration(qint64 duration)
{
    Q_UNUSED(duration);
    m_positionSlider->setRange(0, 100);
}

void Widget::seekPosition()
{
    if(m_player->duration() > 0)
    {
        //计算目标位置(毫秒)= 进度条百分比 × 总时长/100
        qint64 targetPos =
                (m_positionSlider->value() * m_player->duration())/100;

        //设置播放位置
        m_player->setPosition(targetPos);
    }
}

测试结果

视频

相关的类

视频播放会使用如下两个类:

  • QMediaPlayer类:高级视频播放器综合应用;

  • QVideoWidget类:用于媒体对象生成的视频。

QMediaPlayer类介绍

不仅可以播放mp3音频文件,也可以播放视频文件(如 .mp4、.avi 等),但需要与QVideoWidget 配合使用以显示视频画面。

视频小项目

需要在.pro文件中加入QT += core gui multimedia multimediawidgets

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMediaPlayer>
#include <QVideoWidget>

class QPushButton;
class QSlider;
class QLabel;

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);

private slots:
    //打开文件
    void openFile();
    //更新进度条的位置
    void updatePosition(qint64 position);
    //更新进度条范围
    void updateDuration(qint64 duration);
    //设置进度条的位置
    void setPosition(int position);

private:
    QMediaPlayer *m_player;//视频播放器
    QVideoWidget *m_videoWidget;//视频输出组件
    QPushButton  *m_openButton;//打开文件按钮
    QPushButton  *m_playButton;//播放按钮
    QPushButton  *m_pauseButton;//暂停按钮
    QPushButton  *m_stopButton;//停止按钮
    QSlider      *m_positionSlider;//进度条
    QSlider      *m_volumeSlider;//声音条
    QLabel       *m_timeLabel;//进度时间标签
};

#endif // WIDGET_H
cpp 复制代码
#include "widget.h"

#include <QPushButton>
#include <QSlider>
#include <QLabel>
#include <QFileDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QTime>
#include <QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("MP4视频播放器");
    resize(800, 700);

    //初始化播放器组件
    m_player = new QMediaPlayer(this);
    m_videoWidget = new QVideoWidget(this);

    //设置视频输出
    m_player->setVideoOutput(m_videoWidget);

    // 创建控制按钮
    m_openButton = new QPushButton("打开文件");
    m_playButton = new QPushButton("播放");
    m_pauseButton = new QPushButton("暂停");
    m_stopButton = new QPushButton("停止");

    //进度条和音量控制
    m_positionSlider = new QSlider(Qt::Horizontal);
    m_volumeSlider = new QSlider(Qt::Horizontal);
    m_volumeSlider->setRange(0, 100);
    m_volumeSlider->setValue(50);
    m_timeLabel = new QLabel("00:00/00:00");

    //主布局
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(m_videoWidget);

    //控制按钮布局
    QGridLayout *gridLayout = new QGridLayout;
    gridLayout->addWidget(m_openButton, 0, 0, 1, 3);
    gridLayout->addWidget(m_playButton, 0, 3, 1, 3);
    gridLayout->addWidget(m_pauseButton, 0, 6, 1, 3);
    gridLayout->addWidget(m_stopButton, 0, 9, 1, 3);
    gridLayout->addWidget(new QLabel("音量:"), 0, 12);
    gridLayout->addWidget(m_volumeSlider, 0, 13, 1, 6);
    gridLayout->addWidget(new QLabel("进度:"), 1, 0);
    gridLayout->addWidget(m_positionSlider, 1, 1, 1, 18);
    gridLayout->addWidget(m_timeLabel, 2, 0, 1, 19);
    mainLayout->addLayout(gridLayout);

    m_timeLabel->setFixedHeight(50);
    m_timeLabel->setAlignment(Qt::AlignCenter); //保持文字居中

    setLayout(mainLayout);

    //信号槽连接
    connect(m_openButton, &QPushButton::clicked, this, &Widget::openFile);
    connect(m_playButton, &QPushButton::clicked, m_player, &QMediaPlayer::play);
    connect(m_pauseButton, &QPushButton::clicked, m_player, &QMediaPlayer::pause);
    connect(m_stopButton, &QPushButton::clicked, m_player, &QMediaPlayer::stop);
    connect(m_volumeSlider, &QSlider::valueChanged, m_player, &QMediaPlayer::setVolume);
    connect(m_positionSlider, &QSlider::sliderMoved, this, &Widget::setPosition);
    connect(m_player, &QMediaPlayer::positionChanged, this, &Widget::updatePosition);
    connect(m_player, &QMediaPlayer::durationChanged, this, &Widget::updateDuration);
}

// 打开视频文件
void Widget::openFile()
{
    QString fileName =
            QFileDialog::getOpenFileName(this
                                         , "选择视频文件"
                                         , QDir::homePath()
                                         , "视频文件 (*.mp4 *.avi *.mkv *.mov)");
    if (!fileName.isEmpty())
    {
        m_player->setMedia(QUrl::fromLocalFile(fileName));
        m_player->play();
    }
}

//更新播放进度显示
void Widget::updatePosition(qint64 position)
{
    m_positionSlider->setValue(position);

    // 更新时间标签
    QTime currentTime(0, 0, 0);
    currentTime = currentTime.addMSecs(position);
    QTime totalTime(0, 0, 0);
    totalTime = totalTime.addMSecs(m_player->duration());
    m_timeLabel->setText(currentTime.toString("hh:mm:ss")
                         + "/" + totalTime.toString("hh:mm:ss"));
}

// 更新总时长
void Widget::updateDuration(qint64 duration)
{
    m_positionSlider->setRange(0, duration);
}

//手动设置播放位置
void Widget::setPosition(int position)
{
    m_player->setPosition(position);
}

注意:部分同学使用上述代码后看不到视频播放,这里需要安装解码工具LAV Filters(lav解码器),不然看不到视频的播放功能,软件名avfilters_0.73.1.exe。直接网上搜就行

测试结果

相关推荐
二向箔reverse3 小时前
人脸特征可视化进阶:用 dlib+OpenCV 绘制面部轮廓与器官凸包
开发语言·python
非凡ghost3 小时前
MediaHuman YouTube to MP3 多语便携版:高效音频提取工具
windows·音视频·软件需求
寒月霜华3 小时前
java-File
java·开发语言
钱彬 (Qian Bin)3 小时前
企业级实战:构建基于Qt、C++与YOLOv8的模块化工业视觉检测系统(基于QML)
c++·qt·yolo·qml·工业质检·qt 5.15.2
会开花的二叉树3 小时前
上手 cpp-httplib:轻量级 C++ HTTP 库的安装与实战指南
开发语言·c++·http
周杰伦fans3 小时前
C# 集合框架完全指南:从IEnumerable到ObservableCollection的深度解析
开发语言·c#
秦禹辰3 小时前
开源多场景问答社区论坛Apache Answer本地部署并发布至公网使用
开发语言·后端·golang
代码村新手4 小时前
C语言-指针
c语言·开发语言·jvm
s9123601014 小时前
[rust] temporary value dropped while borrowed
开发语言·后端·rust