QT多媒体编程(二)——视频编程知识详解及mp4视频播放器Demo

news2024/11/14 21:22:03

目录

引言

1. QMediaPlayer 类详解

1.1 基本用法

示例代码:

1.2 常用函数

2. QVideoWidget 类详解

2.1 基本用法

示例代码:

2.2 常用函数

3. 实际案例:视频播放器

UI界面

核心代码:

运行结果:

4. 总结


引言

在上一篇文章中,我们初步探索了QT多媒体框架的基础知识与音频处理的能力。今天,我们将深入QT的多媒体世界,专注于视频编程的奥秘。本文将深入解析QT多媒体编程中视频编程的核心知识,并通过实际案例展示如何使用QT多媒体库进行视频编程实现mp4视频播放器Demo。

1. QMediaPlayer 类详解

QMediaPlayer是QT多媒体框架中的一个核心组件,它专门用于播放音频和视频文件。该类使用跨平台的QT音频和视频后端,支持多种音频和视频格式,如MP3、WAV、OGG、AAC(音频格式)以及MPEG、AVI(视频格式)等。

1.1 基本用法

使用QMediaPlayer前,首先需要在Qt项目中包含相应的模块。在.pro文件中添加QT += multimedia以确保多媒体模块的可用性。

示例代码:
#include <QApplication>  
#include <QMediaPlayer>  
#include <QDebug>  
  
int main(int argc, char *argv[]) {  
    QApplication a(argc, argv);  
  
    QMediaPlayer *player = new QMediaPlayer;  
    player->setMedia(QUrl::fromLocalFile("path/to/your/video/file"));  
    player->setVolume(50); // 设置音量为50%  
    player->play(); // 开始播放  
  
    // 监听播放结束事件  
    connect(player, &QMediaPlayer::stateChanged, [=](QMediaPlayer::State state) {  
        if (state == QMediaPlayer::StoppedState) {  
            qDebug() << "Video playback finished!";  
        }  
    });  
  
    return a.exec();  
}
1.2 常用函数
  • setMedia(const QMediaContent &media): 设置要播放的媒体内容。
  • play(): 开始播放媒体。
  • pause(): 暂停播放。
  • stop(): 停止播放。
  • setVolume(int volume): 设置音量,volume参数范围为0到100。
  • volume(): 获取当前音量。
  • stateChanged(QMediaPlayer::State state): 播放状态改变信号,用于监听播放状态的变化。

2. QVideoWidget 类详解

QVideoWidget是QT框架中用于显示视频的组件。它可以嵌入到任何QWidget布局中,并与QMediaPlayer结合使用,以在自定义界面中显示视频内容。

2.1 基本用法

QVideoWidget的使用非常简单,首先创建其实例,然后将其与QMediaPlayer关联即可。在.pro文件中添加QT += multimediawidgets以确保多媒体模块的可用性。

示例代码:
#include <QApplication>  
#include <QMediaPlayer>  
#include <QVideoWidget>  
#include <QVBoxLayout>  
#include <QWidget>  
  
int main(int argc, char *argv[]) {  
    QApplication a(argc, argv);  
  
    QWidget window;  
    QVBoxLayout *layout = new QVBoxLayout(&window);  
  
    QMediaPlayer *player = new QMediaPlayer;  
    QVideoWidget *videoWidget = new QVideoWidget;  
  
    player->setVideoOutput(videoWidget); // 将视频输出到videoWidget  
    player->setMedia(QUrl::fromLocalFile("path/to/your/video/file"));  
  
    layout->addWidget(videoWidget);  
    window.show();  
  
    player->play();  
  
    return a.exec();  
}
2.2 常用函数
  • setAspectRatioMode(Qt::AspectRatioMode mode): 设置视频的宽高比模式,如Qt::IgnoreAspectRatio(忽略宽高比)、Qt::KeepAspectRatio(保持宽高比)等。
  • setBrightness(int brightness): 设置视频的亮度。
  • setContrast(int contrast): 设置视频的对比度。
  • setHue(int hue): 设置视频的色调。
  • setSaturation(int saturation): 设置视频的饱和度。

通过本文的介绍,相信读者已经对QT多媒体编程中的视频编程有了更深入的了解。无论是使用QMediaPlayer进行视频播放,还是使用QVideoWidget进行视频显示,QT都提供了丰富的API和强大的功能支持。希望本文能对正在从事QT多媒体开发的开发者们有所帮助。

3. 实际案例:视频播放器

UI界面

核心代码:

自定义控件实现鼠标单击暂停、播放还有按ESC键退出全屏。

QMyselfVideoWidget.h

#ifndef QMYSELFVIDEOWIDGET_H
#define QMYSELFVIDEOWIDGET_H

#include <QWidget>
#include <QObject>
#include <QVideoWidget>
#include <QMediaPlayer>
#include <QKeyEvent>
#include <QMouseEvent>

class QMyselfVideoWidget : public QVideoWidget
{
public:
    QMyselfVideoWidget(QWidget *parent = Q_NULLPTR);

    void setMediaPlayer(QMediaPlayer *player);

private:
    QMediaPlayer *theplayer;

protected:
    void keyPressEvent(QKeyEvent *event);   // 键盘按键事件,用户按ESC键退出全屏状态
    void mousePressEvent(QMouseEvent *event);// 鼠标按键事件,当用户单击屏幕暂停、继续

};

#endif // QMYSELFVIDEOWIDGET_H

QMyselfVideoWidget .cpp

#include "qmyselfvideowidget.h"

QMyselfVideoWidget::QMyselfVideoWidget(QWidget *parent):QVideoWidget(parent)
{

}

void QMyselfVideoWidget::setMediaPlayer(QMediaPlayer *player)
{
    // 设置播放器操作
    theplayer=player;

}

void QMyselfVideoWidget::keyPressEvent(QKeyEvent *event)   // 键盘按键事件,用户按ESC键退出全屏状态
{
    if((event->key()==Qt::Key_Escape) && (isFullScreen()))
    {
        setFullScreen(false);
        event->accept();
        QVideoWidget::keyPressEvent(event);
    }
}

void QMyselfVideoWidget::mousePressEvent(QMouseEvent *event)// 鼠标按键事件,当用户单击屏幕暂停、继续
{
    if(event->button()==Qt::LeftButton)
    {
        if(theplayer->state()==QMediaPlayer::PlayingState)
            theplayer->pause();
        else
            theplayer->play();
    }
    QVideoWidget::mousePressEvent(event);
}

QMainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "qmyselfvideowidget.h"
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QVideoWidget>
#include <QFileDialog>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;

    QMediaPlayer *player;
    QString drtTime;    // 视频文件时长
    QString pstTime;    // 当前播放位置
private slots:

    void onstatechanged(QMediaPlayer::State state); // 按钮切换状态
    void ondrtchanged(qint64 drt);  // 歌曲总时长
    void onpstchanged(qint64 pos);  // 播放歌曲当前位置
    void on_pushButton_open_clicked();
    void on_pushButton_play_clicked();
    void on_pushButton_pause_clicked();
    void on_pushButton_stop_clicked();
    void on_pushButton_volumn_clicked();

    void on_horizontalSlider_volumn_valueChanged(int value);
    void on_horizontalSlider_speed_valueChanged(int value);
};
#endif // MAINWINDOW_H

QMainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    player = new QMediaPlayer(this);
    player->setNotifyInterval(1000);    // 信息更新周期
    player->setVideoOutput(ui->graphicsView);   // 视频输出组件
    ui->graphicsView->setMediaPlayer(player);   // 设置显示组件的关联播放器

    connect(player, SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(onstatechanged(QMediaPlayer::State)));

    connect(player, SIGNAL(positionChanged(qint64)),this,SLOT(onpstchanged(qint64)));

    connect(player, SIGNAL(durationChanged(qint64)),this,SLOT(ondrtchanged(qint64)));






}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::onstatechanged(QMediaPlayer::State state) // 按钮切换状态
{
    ui->pushButton_play->setEnabled(!(state==QMediaPlayer::PlayingState));
    ui->pushButton_pause->setEnabled(state==QMediaPlayer::PlayingState);
    ui->pushButton_stop->setEnabled(state==QMediaPlayer::PlayingState);
}

void MainWindow::ondrtchanged(qint64 drt)  // 歌曲总时长
{
    ui->horizontalSlider_speed->setMaximum(drt);
    int sec = drt/1000; //总秒
    int min = sec/60;   //总分
    int hour = min/60;//总小时
    min = min%60;   // 余分
    sec = sec%60;   //余秒

    drtTime = QString::asprintf("%02d:%02d:%02d",hour,min,sec);
    ui->label_time->setText(drtTime);
}

void MainWindow::onpstchanged(qint64 pos)  // 播放歌曲当前位置
{
    if(ui->horizontalSlider_speed->isSliderDown())
        return;
    ui->horizontalSlider_speed->setSliderPosition(pos);
    int sec = pos/1000; //总秒
    int min = sec/60;   //总分
    int hour = min/60;//总小时
    min = min%60;   // 余分
    sec = sec%60;   //余秒

    pstTime = QString::asprintf("%02d:%02d:%02d",hour,min,sec);
    ui->label_speed->setText(pstTime);
}

void MainWindow::on_pushButton_open_clicked()
{
    QString currentpath = QDir::homePath(); // 获取系统当前目录
    QString dlgtitle = "请选择视频文件";
    QString strfilter = "所有文件(*.*);;mp4文件(*.mp4)";  // 文件过滤器

    QString strfile = QFileDialog::getOpenFileName(this,dlgtitle,currentpath,strfilter);

    if(strfile.isEmpty())
        return;

    QFileInfo fileinfo(strfile);
    ui->label_name->setText("正在播放:"+fileinfo.fileName());
    player->setMedia(QUrl::fromLocalFile(strfile));
    player->play();
}

void MainWindow::on_pushButton_play_clicked()
{
    player->play();
}

void MainWindow::on_pushButton_pause_clicked()
{
    player->pause();
}

void MainWindow::on_pushButton_stop_clicked()
{
    player->stop();
}

void MainWindow::on_pushButton_volumn_clicked()
{
    // 控制静音状态
    bool mutex = player->isMuted();
    player->setMuted(!mutex);
    if(mutex)
    {
        ui->pushButton_volumn->setIcon(QIcon(":/images/1.PNG"));
    }
    else
        ui->pushButton_volumn->setIcon(QIcon(":/images/2.PNG"));
}


void MainWindow::on_horizontalSlider_volumn_valueChanged(int value)
{
    player->setVolume(value);
}

void MainWindow::on_horizontalSlider_speed_valueChanged(int value)
{
    player->setPosition(value);
}

运行结果:

全屏功能还未实现!

4. 总结

QT多媒体编程中的视频编程功能强大且灵活,通过QMediaPlayerQVideoWidget等核心类,开发者可以轻松实现视频的播放、暂停、停止以及显示等功能。本文深入解析了这些核心类的使用方法和相关函数的调用,并通过实际案例展示了如何在QT应用程序中集成视频功能。希望这篇文章能够帮助到正在学习QT多媒体编程的开发者们。

传送门:QT多媒体编程(一)——音频编程知识详解及MP3音频播放器Demo

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

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

相关文章

NodeJS凉山地区特色农产品团购平台-计算机毕业设计源码72936

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 用户登录流程 2.2.2 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4用例分析 2.5本章小结 3 系统总体设计 3…

【LeetCode每日一题】2024年8月第一周(上)

2024.7.30 中等 链接&#xff1a;2961. 双模幂运算 &#xff08;1&#xff09;题目描述&#xff1a; &#xff08;2&#xff09;示例&#xff1a; &#xff08;3&#xff09;分析&#xff1a; ① 在计算中&#xff0c;反复用到了%10&#xff0c;说明返回的只要取个位即可&…

SEO之网站结构优化(八)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、新手上云 8、URL静态化 URL静态化一直以来都是最基本的SEO要求之一&#xff0c;但近一两年 SEO 行业对是否一定要做静…

科普文:万字细说微服务及其框架Netflix,Spring Cloud,Spring Cloud Alibaba梳理

概叙 微服务&#xff08;Microservices&#xff09;是一种软件架构风格&#xff0c;它将单一的应用程序拆分为多个小的服务&#xff0c;每个服务都是独立运行和部署的。每个微服务通常只专注于一个业务功能&#xff0c;具有自己的数据存储&#xff0c;并且通过轻量级的通信机制…

多无人机协同机间通信技术详解

随着无人机技术的飞速发展&#xff0c;多无人机系统&#xff08;Multi-Unmanned Aerial Vehicle, Multi-UAV&#xff09;在军事侦察、环境监测、目标跟踪、物流配送等多个领域展现出巨大潜力。多无人机协同作业的核心在于高效的机间通信技术&#xff0c;它能够实现无人机之间的…

npm install 巨慢,导致Jenkins编译报错问题解决——基础积累

今天在弄后台系统的服务器编译时&#xff0c;一直报错。报错信息为&#xff1a;系统找不到指定的路径。 最后进入到服务器中&#xff0c;找到E:/Jenkins/WorkSpace/JiePeiAiMomsAdmin_FenZhi这个路径&#xff0c;然后通过cmd进入到命令提示符中。 然后通过npm i进行安装&#…

简单的docker学习 第4章docker容器

第4章 Docker容器 4.1 容器基础 4.1.1 容器启动流程 通过 docker run 命令可以启动运行一个容器。该命令在执行时首先会在本地查找指定的镜像&#xff0c;如果找到了&#xff0c;则直接启动&#xff0c;否则会到镜像中心查找。如果镜像中心存在该镜像&#xff0c;则会下载到…

外贸建站:WordPress搭建外贸独立站零基础小白保姆级教程

凡做外贸的&#xff0c;我相信在过去几年中通过亚马逊、速卖通等电商平台上都取得了一定的成功。然而&#xff0c;近年来电商平台上的竞争激烈&#xff0c;利润空间有限&#xff0c;流量获取困难和昂贵&#xff0c;这对许多外贸从业者造成了困扰。因此&#xff0c;为了减少对平…

易境通散货集拼系统是如何让散拼效率提高80%的?

散货集拼为什么必须要有靠谱的系统才行&#xff1f;因为散拼很容易出现各种问题&#xff0c;而且会连带着影响不同的环节。货物整箱利用空间不充足&#xff0c;会导致集装箱数量增加&#xff0c;运费成本激增&#xff0c;返工整理会耽误发货&#xff0c;延长送货时间&#xff0…

【JavaEE】线程状态

目录 前言 一.线程状态图 二.线程状态 1.初始状态(NEW) 2.运行状态(RUNNING) 3.等待状态&#xff08;WAITING) 4.超时等待&#xff08;TIMED_WAITING) 5.阻塞状态&#xff08;BLOCKED) 6.终止状态(TERMINATED) 三.线程状态间的转换 四.总结 前言 线程状态及其状态转换…

mindspore框架下Pix2Pix模型实现真实图到线稿图的转换|(三)Pix2Pix模型训练与模型推理

mindspore框架下Pix2Pix模型实现真实图到线稿图的转换 mindspore框架下Pix2Pix模型实现真实图到线稿图的转换|&#xff08;一&#xff09;dataset_pix2pix数据集准备mindspore框架下Pix2Pix模型实现真实图到线稿图的转换|&#xff08;二&#xff09;Pix2Pix模型构建mindspore框…

Google Gemma2 2B:语言模型的“小时代”到来?

北京时间8月1日凌晨&#xff08;当地时间7月31日下午&#xff09;&#xff0c;Google发布了其Gemma系列开源语言模型的更新&#xff0c;在AI领域引发了巨大的震动。Google Developer的官方博客宣布&#xff0c;与6月发布的27B和9B参数版本相比&#xff0c;新的2B参数模型在保持…

python实现consul的服务注册与注销

我在使用consul的时候主要用于prometheus的consul服务发现&#xff0c;把数据库、虚拟机信息发布到consul&#xff0c;prometheus通过consul拿到数据库、虚拟机信息去采集指标信息。 此篇文章前提是已经安装好consul服务以后&#xff0c;安装consul请参考二进制方式部署consul…

Nat网络地址转换实验

一、实验拓扑 二、实验要求 三、实验思路 四、实验展示 1.接口IP配置 telnet路由器 r1 r2 r3 pc2 2.全网可达&#xff08;给边界路由器&#xff0c;私家路由器写上缺省 &#xff0c;还要用到nat地址转换&#xff0c;多对多一对多&#xff0c;端口映射&#xff09;因为左右…

第22集《大佛顶首楞严经》

请大家打开讲义第四十九页&#xff0c;“寅三、大众茫然”。 我们要是读《金刚经》&#xff0c;就知道整个修学的方向。《金刚经》就是讲到&#xff0c;一个菩萨发了菩提心&#xff0c;心中有目标&#xff0c;要能够上求佛道&#xff0c;下化众生&#xff0c;但是他不知道“云…

探索味蕾新境界:嘴尚绝卤味,一口难忘的美味传奇

在美食的浩瀚星空中&#xff0c;总有一些味道能够穿越时光的长河&#xff0c;直击人心最柔软的部分&#xff0c;让人回味无穷。今天&#xff0c;就让我们一起走进“嘴尚绝”卤味的世界&#xff0c;感受那份独特而令人难以忘怀的口感之美。 一、卤味之魂&#xff0c;匠心独运 “…

CTF web bibibi题型

CTF web bibibi题型 1.进入网站 在kali中使用Dirsearch对地址进行目录扫描&#xff0c;发现robots.txt 网址内加入 /robots.txt 进入网址 /fl4gi5Here.php 找到flag

未来五年,网络安全有没有发展前途,零基础转行难不难?

在被新冠疫情常态化影响的今天&#xff0c;职场当中呈现出了严重的两极分化现象&#xff0c;具体的表现形式为&#xff1a; 一些人薪资翻倍、愈加繁忙&#xff0c;另一些人则加入了失业大军、不知所措&#xff1b;一些行业实现了井喷式增长&#xff0c;一些行业却不断裁员、随…

Apache解析漏洞

一、apache_parsing 在Apache1.x/2.x中Apache 解析文件的规则是从右到左开始判断解析&#xff0c;如果后缀名为不可识别文件解析&#xff0c;就再往左判断。如1.php.xxxxx 1、进入Vulhub靶场并执行以下命令启动靶场 2、只要一个文件含有.php后缀的文件即将被识别成PHP文件&am…

即时通讯和即时通信,即时通讯和实时通信

在当今数字化时代&#xff0c;即时通讯和实时通信已成为人们日常生活和工作中不可或缺的一部分。尽管这两个概念经常被混淆使用&#xff0c;但它们在本质和应用上存在一些区别和联系。同时&#xff0c;企业级即时通讯平台WorkPlus对于提升企业内部沟通和协作也有着重要的作用。…