QT播放视频保持视频宽高比消除黑边
1、问题
在播放视频的时候,由于框架的大小发生变化,导致视频出现黑边很不好看。
因此需要像一种方法消除黑边
2、处理
1、读取视频的宽高比
2、设置视频的Widget的大小固定,Widget的宽高比和视频宽高比相同。
- cpp文件
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMediaMetaData>
void MainWindow::playVideo()
{
player->play();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout* qs = new QVBoxLayout();
ui->centralwidget->setLayout (qs);
// 创建播放器和视频窗口
player = new QMediaPlayer;
QVideoWidget *videoWidget = new QVideoWidget;
// 监听媒体加载完成状态
QObject::connect(player, &QMediaPlayer::mediaStatusChanged, [=](QMediaPlayer::MediaStatus status) {
if (status == QMediaPlayer::LoadedMedia) { // 媒体已加载完成
// 获取视频分辨率元数据
QSize resolution = player->metaData().value(QMediaMetaData::Resolution).toSize();
if (!resolution.isEmpty()) {
qDebug() << "视频宽高:" << resolution;
} else {
qDebug() << "未获取到分辨率信息";
}
int w = resolution.width ();
int h = resolution.height ();
double r = 1.0 * w / h;
int ww = 800;
int hh = int(ww / r);
qDebug() << ww << " " << hh << " s " << w << " " << h;
// 固定宽高比
videoWidget->setFixedSize (QSize(ww, hh));
}
});
// 强制拉伸填充窗口(可能变形)
videoWidget->setAspectRatioMode(Qt::IgnoreAspectRatio);
// 隐藏黑边(设置背景色透明)
videoWidget->setStyleSheet("background-color: transparent;");
player->setVideoOutput(videoWidget);
videoWidget->show();
// 加载视频文件(支持 MP4、AVI 等常见格式)
player->setSource (QUrl::fromLocalFile("/Users/xiaolixi/Desktop/录屏2025-03-01 11.03.06.mov"));
// 设置循环播放
player->setLoops (-1);
QPushButton* start = new QPushButton("start");
// 设置视频水平居中
qs->addWidget (videoWidget, 0, Qt::AlignHCenter); // 关键:对齐方式
qs->addWidget (start);
QObject::connect(start, SIGNAL(pressed()), this, SLOT(playVideo()));
}
MainWindow::~MainWindow()
{
delete ui;
}
- h文件
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMediaPlayer>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void playVideo();
private:
Ui::MainWindow *ui;
QMediaPlayer *player;
};
#endif // MAINWINDOW_H
- pro文件
shell
QT += core gui
QT += multimediawidgets
QT += multimedia
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

缺点
视频大小固定了。但是在我的场景中这个确定不影响。