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

缺点

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

相关推荐
雨田嘟嘟42 分钟前
QML ChartView 崩溃
qt
Aevget2 小时前
从复杂到高效:QtitanNavigation助力金融系统界面优化升级
c++·qt·金融·界面控件·ui开发
Jay Chou why did3 小时前
0. Qt 安装及源码及报错
qt
nianniannnn10 小时前
Qt布局管理停靠窗口QDockWidget类
开发语言·数据库·c++·qt·qt5·qt6.3
牵牛老人13 小时前
Qt 中如何操作 Excel 表格:主流开源库说明介绍与 QXlsx 库应用全解析
qt·开源·excel
牵牛老人14 小时前
QXlsx操作Excel深度解析:核心类接口与 Qt C++ 功能解析
qt
长沙红胖子Qt16 小时前
关于 Qt5.x版本离线安装可以跳过登录但是实际离线仍需要登录 的解决方法
qt·离线安装·离线无法skip
友友马16 小时前
『 QT 』QT控件属性全解析 (二)
开发语言·数据库·qt
大米粥哥哥1 天前
Qt QProcess基于Linux的命令管道符号无效问题【已解决】
linux·qt·shell·qprocess·1024程序员节·管道符号
mengzhi啊1 天前
QT实现消息未读提示
qt