【问题标题】:Displaying a video with an alpha channel using qt使用 qt 显示带有 alpha 通道的视频
【发布时间】:2020-01-27 12:14:55
【问题描述】:

我需要使用 qt 显示 RGBA 编码的视频(即具有透明背景的视频)。这个想法是实时合并视频。我通常使用 libmpv,但它似乎不允许渲染透明背景视频。 我正在尝试使用带有以下代码的 QMediaPlayer:

 QMainWindow w;
 w.resize(1920,1080);
 QVideoWidget videoWidget(&w);
 videoWidget.move(0,100);
 videoWidget.resize(1920,1080);
 QMediaPlayer *player = new QMediaPlayer(&w);
 w.resize(w.size());
 player->setMedia( QUrl::fromLocalFile(PATH+"video2.mov") );
 player->setVideoOutput(&videoWidget);
 w.show();
 player->play();

这会成功加载视频(这是一个 RGBA mov 视频),但会用黑色背景填充视频小部件,它应该是透明的,因此覆盖了视频播放器后面的任何项目。

有没有办法使用 QVideoPlayer/QVideoWidget 实际加载透明视频?如果没有,是否有有效的替代方案(我宁愿不使用 opencv 等较低级别的解决方案)。

非常感谢,

弗雷德

【问题讨论】:

    标签: qt video rgba qvideowidget


    【解决方案1】:

    这是我终于找到的解决方案:

    子类化 QAbstractVideoSurface:

    class alphaVideoDrawer : public QAbstractVideoSurface
    {
        Q_OBJECT
    public:
        alphaVideoDrawer(QLabel *displayLbl);
    private:
        QLabel *displayLbl;
    
    protected:
        bool present(const QVideoFrame &frame);
    
        QList<QVideoFrame::PixelFormat> supportedPixelFormats(
                QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const
        {
            Q_UNUSED(handleType);
            return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_ARGB32;
        }
    };
    

    表面将接收帧转换并将其转发到显示视频的qlabel。

    alphaVideoDrawer::alphaVideoDrawer(QLabel *displayLbl):displayLbl(displayLbl)
    {
    }
    
    extern QImage qt_imageFromVideoFrame(const QVideoFrame &f);
    
    
    bool alphaVideoDrawer::present(const QVideoFrame &frame)
    {
        QImage image = qt_imageFromVideoFrame(frame);
        displayLbl->setPixmap(QPixmap::fromImage(image));
        return true;
    }
    

    然后我们将 QLabel 子类化,这将是我们的视频输出:

    class alphaVideo : public QLabel
    {
        Q_OBJECT
    public:
        alphaVideo(QLabel *parent = nullptr);
    
    private:
        alphaVideoDrawer *videoDrawer;
        QMediaPlayer *videoPlayer;
        QMediaPlaylist *playlist;
    };
    

    它加载抽屉和播放器并开始播放/渲染视频:

        alphaVideo::alphaVideo(QLabel *parent): QLabel(parent)
    {
        setStyleSheet("QLabel { background-color : transparent; }");
        videoDrawer = new alphaVideoDrawer(this);
        videoPlayer = new QMediaPlayer(this);
        playlist = new QmediaPlaylist();
        videoPlayer->setPlaylist(playlist);
        videoPlayer->setVideoOutput(videoDrawer);
        playlist->addMedia( Qurl::fromLocalFile(“your RGBA video file.mp4”) );
        videoPlayer->play();
    }
    

    【讨论】:

    • 我仍然只得到黑色背景而不是透明。看来我错过了什么。可能您在系统上安装了一些特定的编解码器,或者您的视频具有某种特定的格式?我尝试使用 LAV 过滤器和内部带有 png-s 的 .mov 视频
    猜你喜欢
    • 1970-01-01
    • 2017-06-28
    • 2021-09-27
    • 1970-01-01
    • 2018-02-23
    • 2011-08-19
    • 1970-01-01
    • 2011-03-07
    • 2021-01-01
    相关资源
    最近更新 更多