Qt之简易音视频播放器设计(十五)
目录
前言
一、QMediaPlayer
二、实现方式
1.添加multimedia
2.创建类vedioplayer
3.UI设计
4.用户使用
5.效果演示
总结
前言
利用Qt进行音视频播放器设计,首先比较方便使用的是Qt自带的音视频播放器类QMediaPlayer,无需第三方插件库,支持多种音频和视频格式,具体支持的格式取决于底层操作系统提供的解码器。QMediaPlayer是Qt多媒体模块中的一个核心类,提供跨平台的音频和视频播放功能,并兼容多种音频和视频格式。本篇文章将使用QT来实现一个简易音视频播放器,下面就让我们一起来实现这个播放器吧。
一、QMediaPlayer
QMediaPlayer支持多种音频和视频格式,音频格式有MP3、WAV、OGG、AAC、FLAC ,视频格式有MPEG、AVI、MP4、WMV。
它不仅支持上述格式,还可以播放网络流媒体资源,如HTTP直播流(HLS)、RTSP流等。然而,QMediaPlayer本身只是一个框架,实际的媒体播放功能依赖于底层的解码器。在Windows平台上,QMediaPlayer依赖于DirectShow解码器。如果需要支持更多的格式,可能需要安装额外的解码器或插件,通过安装LAV Filters等DirectShow解码框架,可以支持更多的视频格式。
QMediaPlayer还提供了一系列的信号和槽函数,使得用户可以在媒体播放期间捕获和处理多种事件,使用这些信号和槽函数可以实现一些有趣和有用的功能。
二、实现方式
1.添加multimedia
在使用这个类时需要在.pro文件中,加上QT += multimedia模块,代码如下(示例)。
QT += multimedia multimediawidgets
2.创建类vedioplayer
在Qt项目上创建一个对象vedioplayer,具体实现如下。
#include <QWidget>
#include <QMediaPlayer>
#include <QVideoWidget>namespace Ui {
class vedioplayer;
}
class vedioplayer : public QWidget
{Q_OBJECT
public:explicit vedioplayer(QWidget *parent = nullptr);~vedioplayer();
private:Ui::vedioplayer *ui;QMediaPlayer *player;
};
创建的vedioplayer,其构造函数功能如下,主要完成对该类功能定义。
#include "vedioplayer.h"
#include "ui_vedioplayer.h"
#include "qfiledialog.h"vedioplayer::vedioplayer(QWidget *parent) :QWidget(parent),ui(new Ui::vedioplayer)
{ui->setupUi(this);player = new QMediaPlayer(this);player->setVideoOutput(ui->videowidget);//设置播放器connect(ui->pushButton,&QPushButton::clicked,[=](){if(ui->pushButton->text() == tr("开 始")){QString filepath = qApp->applicationDirPath() + "/";QString fileName = QFileDialog::getOpenFileName(this, "选择保存位置", filepath, "*.gif;;*.mp4;;*.mkv;;all(*)");if (fileName.isEmpty()) {return;}player->setMedia(QUrl::fromLocalFile(fileName));//设置播放对象player->play();//点击开始按钮,播放视频ui->pushButton->setText(tr("暂 停"));}else{player->pause();//点击暂停按钮,暂停视频ui->pushButton->setText(tr("开 始"));}});//亮度的设置ui->horizontalSlider->setValue(ui->videowidget->brightness());//设置初始亮度//当滑块移动,亮度也跟着移动connect(ui->horizontalSlider,&QSlider::sliderMoved,ui->videowidget,&QVideoWidget::setBrightness);//当亮度改变,滑块也跟着移动connect(ui->videowidget,&QVideoWidget::brightnessChanged,ui->horizontalSlider,&QSlider::setValue);//对比度的设置ui->horizontalSlider_2->setValue(ui->videowidget->saturation());//设置初始对比度connect(ui->horizontalSlider_2,&QSlider::sliderMoved,ui->videowidget,&QVideoWidget::setContrast);connect(ui->videowidget,&QVideoWidget::contrastChanged,ui->horizontalSlider_2,&QSlider::setValue);//饱和度的设置ui->horizontalSlider_3->setValue(ui->videowidget->contrast());//设置初始对比度connect(ui->horizontalSlider_3,&QSlider::sliderMoved,ui->videowidget,&QVideoWidget::setSaturation);connect(ui->videowidget,&QVideoWidget::saturationChanged,ui->horizontalSlider_3,&QSlider::setValue);//色相的设置ui->horizontalSlider_4->setValue(ui->videowidget->hue());//设置初始对比度connect(ui->horizontalSlider_4,&QSlider::sliderMoved,ui->videowidget,&QVideoWidget::setHue);connect(ui->videowidget,&QVideoWidget::hueChanged,ui->horizontalSlider_4,&QSlider::setValue);//音量的设置ui->horizontalSlider_5->setValue(player->volume());//设置初始音量connect(ui->horizontalSlider_5,&QSlider::sliderMoved,player,&QMediaPlayer::setVolume);connect(player,&QMediaPlayer::volumeChanged,ui->horizontalSlider_5,&QSlider::setValue);//倍速的设置ui->horizontalSlider_6->setValue(player->playbackRate());//设置初始音量connect(ui->horizontalSlider_6,&QSlider::sliderMoved,player,&QMediaPlayer::setPlaybackRate);connect(player,&QMediaPlayer::playbackRateChanged,ui->horizontalSlider_6,&QSlider::setValue);
}vedioplayer::~vedioplayer()
{delete player;player = nullptr;delete ui;
}
3.UI设计
上一步完成对vedioplayer对象的创建,这一步将实现其UI窗口设计。可视化界面如下。
在上图UI界面上,使用QWidget将其提升为QVideoWidget。QVideoWidget是Qt框架中的组件之一,它提供了一个用于显示视频的自定义窗口。您可以将QVideoWidget添加到应用程序的用户界面中,然后使用QMediaPlayer或其他支持Qt视频框架的组件将视频播放到该窗口中。使用QVideoWidget,可实现视频播放器的自定义UI,例如:显示视频标题和长度、调整播放音量、显示屏幕截图和元数据等。QVideoWidget还可以处理一些常见的视频操作,例如全屏模式、视频缩放和窗口大小更改。
4.用户使用
创建完上面的vedioplayer对象后,用户对象frmGifWidget需要调用/使用它,具体含义实现如下。
class frmGifWidget : public QWidget
{Q_OBJECT
public:explicit frmGifWidget(QWidget *parent = 0);~frmGifWidget();
private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();
private:Ui::frmGifWidget *ui;vedioplayer *v;
};#include "frmgifwidget.h"
#include "ui_frmgifwidget.h"
frmGifWidget::frmGifWidget(QWidget *parent) : QWidget(parent), ui(new Ui::frmGifWidget)
{ui->setupUi(this);v = new vedioplayer;
}
frmGifWidget::~frmGifWidget()
{if(nullptr != v){delete v;v = nullptr;}delete ui;
}
void frmGifWidget::on_pushButton_clicked()
{if(ui->pushButton->text() == tr("录 屏")){//设置截图窗口置顶显示GifWidget::Instance()->setWindowFlags(GifWidget::Instance()->windowFlags() | Qt::WindowStaysOnTopHint);GifWidget::Instance()->show();ui->pushButton->setText(tr("隐 藏"));}else if(ui->pushButton->text() == tr("隐 藏")){ui->pushButton->setText(tr("录 屏"));GifWidget::Instance()->hide();}
}
void frmGifWidget::on_pushButton_2_clicked()
{if(ui->pushButton_2->text() == tr("播 放")){v->show();ui->pushButton_2->setText(tr("隐 藏"));}else if(ui->pushButton_2->text() == tr("隐 藏")){ui->pushButton_2->setText(tr("播 放"));v->hide();}
}
5.效果演示
上述功能代码弄完后,编译运行,显示窗口如下。
在效果演示画面上,可以在视频软件界面看到,另一个录屏功能,这个下一章节进行讲解说明。
总结
本文采用Qt自带的音视频播放器类QMediaPlayer,设计了一款简易音视频播放器。如需要进行复杂的使用环境,如支持更为复杂的视频解码/编码、性能优化等等,可采用FFmpeg、mdk、mpv、vlc等三方编解码库来支持,这些后面章节将介绍。
博文中相应的工程代码Qt-Case.zip 利用Qt开发软件进行编的例程,为博文提供案例-CSDN文库。
相关文章:

Qt之简易音视频播放器设计(十五)
Qt开发 系列文章 - MediaPlayer(十五) 目录 前言 一、QMediaPlayer 二、实现方式 1.添加multimedia 2.创建类vedioplayer 3.UI设计 4.用户使用 5.效果演示 总结 前言 利用Qt进行音视频播放器设计,首先比较方便使用的是Qt自带的音视…...

ArrayList 和LinkedList的区别比较
前言 ArrayList和LinkedList的主要区别在于它们的底层数据结构、性能特点以及适用场景。ArrayList和LinkedList从名字分析,他们一个是Array(动态数组)的数据结构,一个是Linked(链表)的数据结构&#x…...

Wallpaper壁纸制作学习记录13
骨骼物理模拟 Wallpaper Engine还允许您为人偶变形骨骼配置某些物理模拟。选择骨骼时,点击编辑约束来配置骨骼这些属性。 警告 请记住,物理模拟可能会根据用户的最大FPS设置略微改变其行为。 Wallpaper Engine编辑器将始终以高帧速率渲染。您可以将壁纸…...

Visual Studio 2022安装教程
1、下载网址 Visual Studio 2022 IDE安装网址借助 Visual Studio 设计,具有自动完成、构建、调试、测试功能的代码将与 Git 管理和云部署融为一体。https://visualstudio.microsoft.com/zh-hans/vs/ 点击图片所示 双击运行 2、安装 点击C桌面开发(右边…...

std__invoke 的使用
std__invoke 的使用 文章目录 std__invoke 的使用1. std::invoke 的功能2. 语法3. 使用场景1. 调用普通函数2. 调用成员函数3. 调用成员函数(通过指针或引用)4. 调用函数对象(仿函数)5. 调用 Lambda 表达式 4. std::invoke 的优势…...

2501d,d.109
原文 2.109.0带来了15个主要更改和26个修复的Bugzilla问题.非常感谢39位贡献者,是他们使2.109.0变成可能. 更改编译器 1,[下一版]现在,为类型实例的成员设置别名是个错误 2,添加位字段内省功能 3,添加了从CTFE写入消息的__ctfeWrite 4,现在-verrors也限制弃用警告 5,dtoh为e…...

1、蓝牙打印机环境搭建
本项目采用stm32f103c8T6芯片,通过库函数实现打印功能,并配置有小程序蓝牙通信上位机。 1、创建文件夹目录 core文件夹存放核心库文件 LIB文件夹存放标准库函数文件 这里可以删减,用不到的可以不要。 obj存放编译后的文件 project存放项目…...

Axure RP11安装学习
安装: 官网下载地址:Axure RP - UX Prototypes, Specifications, and Diagrams in One Tool 设置自己的安装目录,一步步安装即可。 汉化: 汉化包下载地址: 链接: https://pan.baidu.com/s/1eIRoGkVqAY3u3I27lgDJ6A…...

axios和fetch的实现原理以及区别,与XMLHttpRequest的关系,并结合react封装统一请求示例
Axios 和 Fetch 对比及统一请求封装 1. Axios 基础用法 1.1 安装和引入 // 安装 npm install axios// 引入 import axios from axios;1.2 基本请求方法 // GET 请求 axios.get(/api/users).then(response > console.log(response.data)).catch(error > console.error…...

矩阵运算提速——玩转opencv::Mat
介绍:用Eigen或opencv::Mat进行矩阵的运算,比用cpp的vector或vector进行矩阵运算要快吗? 使用 Eigen 或 OpenCV 的 cv::Mat 进行矩阵运算通常比使用 std::vector<int> 或 std::vector<double> 更快。这主要有以下几个原因: 优化的底层实现…...

C++软件设计模式之模板方法模式
模板方法模式是面向对象软件设计模式之一,其主要意图是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。 动机 在软件开发中,常常会遇到这样的情…...
神经网络的初始化方式都有哪些?
一、概念 神经网络的初始化是深度学习中的一个关键步骤,它指的是在训练开始前为神经网络的权重和偏置设置初始值。合适的初始化方法可以加速模型的收敛,提高训练效果,甚至影响模型的最终性能。当然,目前我们使用Torch、TensorFlow…...

const成员函数
在c中经常看到这样的声明: class A{ ... int fun1() const; //const成员函数 int fun2() const; //const成员函数private: int a; //属于状态 static int b; //不属于状态,属于类 } 这个const关键字声明了这个函数是const成员函数,con…...

物理知识1——电流
说起电流,应该从电荷说起,而说起电荷,应该从原子说起。 1 原子及其结构 常见的物质是由分子构成的,而分子又是由原子构成的,有的分子是由多个原子构成,有的分子只由一个原子构成。而原子的构成如图1所示。…...

车载通信架构 --- 智能汽车通信前沿技术
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...

Flutter中添加全局防护水印的实现
随着版权意识的加强,越来越多的应用开始在应用内部增加各种各样的水印信息,防止核心信息泄露,便于朔源。 效果如下: 在Flutter中增加全局水印的方式,目前有两种实现。 方案一,在native层添加一个遮罩层&a…...

BGP(Border Gateway Protocol)路由收集器
全球 BGP(边界网关协议)路由收集器的分布情况以及相关数据。以下是主要的信息解读: 地图标记: 每个绿色点代表一个路由收集器的位置。路由收集器分布在全球不同的地区,覆盖了五大区域: ARIN(美…...

【DAGMM】直接跑tip
1.from sklearn.externals import joblib 版本高 joblib没有 直接pip install joblib,然后 import joblib 2.AttributeError: module ‘tensorflow’ has no attribute ‘set_random_seed’ # tf.set_random_seed(args.seed)#tf<2.0 tf.random.set_seed(args.s…...

vscode中调用deepseek实现AI辅助编程
来自 Python大数据分析 费弗里 1 简介 大家好我是费老师,最近国产大模型Deepseek v3新版本凭借其优秀的模型推理能力,讨论度非常之高🔥,且其官网提供的相关大模型API接口服务价格一直走的“价格屠夫”路线,性价比很高…...

AI大模型语音识别转文字
提取音频 本项目作用在于将常见的会议录音文件、各种语种音频文件进行转录成相应的文字,也可从特定视频中提取对应音频进行转录成文字保存在本地。最原始的从所给网址下载对应视频和音频进行处理。下载ffmpeg(https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-…...

可由 (5V) 单片机直接驱动的模块
可由 (5V) 单片机 直接驱动的模块 1. 传感器类 元器件描述温度传感器DS18B20(数字温度传感器)光强传感器光敏电阻(通过 ADC 读取)红外传感器红外接收模块(如 VS1838)超声波传感器HC…...

vue使用树形结构展示文件和文件夹
1. 树形结构显示 显示文件夹和文件:使用 el-tree 组件展示树形结构,文件夹和文件的图标通过 el-icon 进行动态显示。文件夹使用 Folder 图标,文件使用 Files 图标。节点点击:点击树形节点后,会将选中的节点保存到 sel…...

PHP框架+gatewayworker实现在线1对1聊天--聊天界面布局+创建websocket连接(5)
文章目录 聊天界面布局html代码 创建websocket连接为什么要绑定? 聊天界面布局 在View/Index目录下创建index.html html代码 <div id"chat"><div id"nbar"><div class"pull-left">与牛德胜正在聊天...</div…...

LinuxUbuntu打开VSCode白屏解决方案
解决方法是 以root权限打开VSCode sudo /usr/share/code/code --no-sandbox --unity-launch...

在 ESP 上运行 AWTK
AWTK 基于 esp 的移植。 测试硬件平台为 ESP32-S3-Touch-LCD-4.3,其它平台请根据实际平台自行调整。 安装下载工具 建议下载离线版本 ESP IDF v5.3.2 下载代码 git clone https://github.com/zlgopen/awtk-esp.git cd awtk-esp git clone https://github.com/zlg…...

硬件工程师面试题 21-30
把常见的硬件面试题进行总结,方便及时巩固复习。其中包括网络上的资源、大佬们的大厂面试题,其中可能会题目类似,加强印象即可。 更多硬件面试题:硬件工程师面试题 1-10硬件工程师面试题 11-20 21、单片机最小系统需要什么&#x…...

开源架构的容器化部署优化版
上三篇文章推荐: 开源架构的微服务架构实践优化版(New) 开源架构中的数据库选择优化版(New) 开源架构学习指南:文档与资源的智慧锦囊(New) 我管理的社区推荐:【青云交社区…...

Qt使用CMake编译项目时报错:#undefined reference to `vtable for MainView‘
博主将.h文件和.cpp文件放到了不同的文件目录下面,如下图所示: 于是构建项目的时候就报错了#undefined reference to vtable for MainView,这个是由于src/view目录下的CMake无法自动moc头文件导致的,需要手动moc include/view目录…...

python学习笔记—12—
1. 布尔类型 (1) 定义 (2) 比较运算符 (3) 代码演示 1. 手动定义 bool_1 True bool_2 False print(f"bool_1的内容是:{bool_1}, 类型是:{type(bool_1)}") print(f"bool_2的内容是:{bool_2}, 类型是:{type(bool…...

==和===的区别,被坑的一天
在 JavaScript 中, 和 都用于比较两个值,但它们有一个重要的区别: 1. (宽松相等运算符) 进行比较时,会 自动类型转换(也叫做强制类型转换),即如果比较的两个值的类型不同,JavaScr…...