Stefan
Stefan

Reputation: 418

QVideoWidget: Video is cut off

I want to play a video in a Qt Application. This is my code so far:

#include <QApplication>
#include <QWidget>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QUrl>

#include <iostream>

using namespace std;

const int WIDTH = 1280;
const int HEIGHT = 720;

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget window;
    window.resize(WIDTH, HEIGHT);
    window.setWindowTitle("Video Test");
    window.show();

    QMediaPlayer *player = new QMediaPlayer();
    player->setMedia(QUrl::fromLocalFile("/Path/To/Video.mp4"));

    QVideoWidget *videoWidget = new QVideoWidget(&window);
    player->setVideoOutput(videoWidget);

    videoWidget->resize(WIDTH, HEIGHT);

    videoWidget->show();
    player->play();


    return app.exec();
}

The problem: The video is shown and plays back normally, but the video does not resize to fit in the QVideoWidget. The part of the video that is bigger than the widget is cut off.

Thanks in advance!

EDIT: I reduced the code and noticed, that when the application starts the video is cut off, but when I resize the window using the mouse it actually fits to the size:

#include <QApplication>
#include <QWidget>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QUrl>

#include <iostream>

using namespace std;

const int WIDTH = 1280;
const int HEIGHT = 720;

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QMediaPlayer *player = new QMediaPlayer();
    QVideoWidget *videoWidget = new QVideoWidget();

    player->setVideoOutput(videoWidget);

    player->setMedia(QUrl::fromLocalFile("/Path/To/Video.mp4"));
    player->play();

    videoWidget->resize(WIDTH/3, HEIGHT/3);

    videoWidget->show();

    return app.exec();
}

Upvotes: 2

Views: 3841

Answers (6)

INeed ADollar
INeed ADollar

Reputation: 56

If you still searching for a solution to this, QVideoWidget class has setAspectRatioMode method. Use this to scale frames of video to fit your widget area.

Upvotes: 0

user3057006
user3057006

Reputation: 81

After playing, I resized the QVideoWidget by 1 and then resized to original size. Definitely "fudge", but this works for me until I find a real solution: (working with PyQt5 and High Sierra)

s1 = self.MediaFrame.size() # QVideoWidget
s2 = s1 + QSize(1, 1)
self.MediaPlayer.play() # QMediaPlayer
self.MediaFrame.resize(s2) # enlarge by one pixel
self.MediaFrame.resize(s1) # return to original size

Upvotes: 1

Skotastic
Skotastic

Reputation: 56

I ran into a similar problem in PyQt5. I worked around it by setting the geometry of the QVideoWidget to its current geometry before playing the video. I am guessing something in the resizeEvent signal must handle the scaling of the media and isn't triggered when initialized.

Upvotes: 2

KP99
KP99

Reputation: 396

For anyone in 2016, QVideoWidget is still busted. However, use a QGraphicsView widget, which holds a scene graph, and add a single QGraphicsVideoItem to the scene graph. Seems to work...

well, except that it's not exactly centered. and there's a 1px border on the left. and it hangs going into full screen most of the time. and I get errors like "updateVideoFrame called without AVPlayerLayer (which shouldn't happen". Progress!

.. oh, and it takes up about 10x the cpu too.

You know what does work, and works great? GStreamer. Thank you, gstreamer. Even integrating it in python/qt works fabulously.

Upvotes: 2

Stefan
Stefan

Reputation: 418

After many hours of looking for the error, I think this is a bug in Qt on OSX, as I watched this YouTube video https://www.youtube.com/watch?v=tGKmQy-VBX0 and tried out the code.

In the video scaling works fine, but on my machine not.

Upvotes: 1

Exa
Exa

Reputation: 4110

Usually the scale mode dictates how the video fills the widget. The scale mode FitInView will force the video to fill the view keeping aspect ratio.

However, this scale mode should be the default. You can try to set it manually:

QVideoWidget *videoWidget = new QVideoWidget(&window);
videoWidget->setScaleMode(Phonon::VideoWidget::FitInView);
player->setVideoOutput(videoWidget);

Upvotes: 0

Related Questions