QT播放视频保持视频宽高比消除黑边

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

缺点

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

相关推荐
秋已杰爱32 分钟前
Qt显示一个hello world
开发语言·qt
追烽少年x11 小时前
Qt 中signals和slots、Q_SIGNAL和Q_LOT、Q_SIGNALS和Q_SLOTS的区别和使用
qt
吃面不喝汤6611 小时前
Qt 的 Lambda 捕获局部变量导致 UI 更新异常的分析与解决
c++·qt
码农葫芦侠13 小时前
解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
c++·qt·ssl
m0_7482510815 小时前
使用 Qt 插件和 SQLCipher 实现 SQLite 数据库加密与解密
数据库·qt·sqlite
A星空1231 天前
二、QT和驱动模块实现智能家居-----4、编译Qt程序并运行
开发语言·qt·智能家居
A星空1231 天前
二、QT和驱动模块实现智能家居-----3、安装并配置QT
开发语言·qt·智能家居
m0_687399841 天前
C++ Qt login an https server, no use connect
c++·qt·https
寒页_2 天前
【PyQt5项目实战分享】基于YOLOv8的车辆轨迹识别与目标检测研究分析软件
python·qt·yolo·目标检测·pyqt