Reputation: 418
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
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
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
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
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
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
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