QVideoWidget does not display anything

10

I'm trying to use the QMediaPlayer and QVideoWidget to display a video on a system I'm producing. Except that these class rays do not work as expected. QVideoWidget simply does not appear, does not display the video, does nothing!

The MCVE

To exemplify the problem, I built a Minimum, Full, and Verifiable Example based in the Qt 5 documentation example itself . Below are the configuration files for CMake (for setting the environment - that is, creating the Visual Studio or Makefile project) and code :

CMakeLists.txt :

cmake_minimum_required(VERSION 2.8.11)
project (Teste)

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
    "MinSizeRel" "RelWithDebInfo")
endif()

# Configuração do Qt
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Multimedia REQUIRED)
find_package(Qt5MultimediaWidgets REQUIRED)

# Cria o executável
if(WIN32)
    add_executable(Teste WIN32 main.cpp)
else()
    add_executable(Teste main.cpp)
endif()

# Adiciona as bibliotecas necessárias
target_link_libraries(Teste Qt5::Widgets Qt5::Multimedia Qt5::MultimediaWidgets)

main.cpp :

#include <QApplication>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QMediaPlaylist>

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

    QMediaPlayer *player;
    QMediaPlaylist *playlist;
    QVideoWidget *videoWidget;

    // Código tirado do exemplo em: http://doc.qt.io/qt-5/qvideowidget.html#details
    // -------------------------
    player = new QMediaPlayer;

    playlist = new QMediaPlaylist(player);
    playlist->addMedia(QUrl("http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"));
    playlist->addMedia(QUrl("http://techslides.com/demos/sample-videos/small.mp4"));

    videoWidget = new QVideoWidget;
    player->setVideoOutput(videoWidget);

    videoWidget->show();
    playlist->setCurrentIndex(1);
    player->play();
    // -------------------------

    return app.exec();
}

The Problem

When I run the code, the component ( QVideoWidget ) apparently is not "created" (although it is displayed, since to ensure that the problem is not another I call show directly on the wretch), since window appears "shortened" (without any standard size):

ButevenifIusethemousetoresizethewindow,nothingisdisplayed:

Thecodegeneratesnoexceptionsorerrors.IntheminimalexampleIuseURLsofvideosjusttomaketestingeasier(andasitisinthedocumentation),butonmylocalsystemIreadlocalfilesandtheproblemisexactlythesame.

TheEnvironment

Mydevelopmentenvironmentis:

  • Windows1064-bit
  • CMake3.5.0-rc3
  • Qt5.6.032bit
  • VisualStudio2015

EDIT

IjusttestedinUbuntu(16.0464bit)withQt5.7(64bit)andtheproblemisexactlythesame:

    
asked by anonymous 23.06.2016 / 01:06

1 answer

4

I tested your example and it does not even try to run the file, by looking at the example it sent from the site it looks like this:

playlist = new QMediaPlaylist(player);

It seems that there are some errors in the documentation, QMediaPlaylist does not have the parameter to receive QMediaPlayer , but a QObject , that is, it should only be to define parent , create the player, it seems like an error of the tutorial of them, see how is the class QMediaPlaylist :

QMediaPlaylist(QObject *parent = 0);
virtual ~QMediaPlaylist();

Another thing I noticed is that by adding "media items" you have used QUrl , but I believe that the correct one is QMediaContent for both remote and local files.

Another thing I noticed is that it is necessary to set the minimum size of QVideoWidget , otherwise it will render as 0 , you can also add it within a QWidget or QMainWindow

@LuizViera also looked at a detail, QUrl does not add file:/// to local files, so you need to use QUrl::fromLocalFile .

The code for basic operation would look like this:

QMediaContent videoItem1(QUrl::fromLocalFile("C:/Users/Guilherme/exemplo.mp4"));
playlist->addMedia(videoItem1);

I believe the correct path is this:

player = new QMediaPlayer;

playlist = new QMediaPlaylist();

//Define o playlist no player
player->setPlaylist(playlist);

//item index 0
playlist->addMedia(QMediaContent(QUrl::fromLocalFile("http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4")));

//item index 1
playlist->addMedia(QMediaContent(QUrl::fromLocalFile("http://techslides.com/demos/sample-videos/small.mp4")));

videoWidget = new QVideoWidget;
player->setVideoOutput(videoWidget);

videoWidget->show();

//Define o minimo do tamanho do video
videoWidget->setMinimumSize(100, 100);

playlist->setCurrentIndex(1);
player->play();
  

Just a note: if a message similar to this appears in the Qt log (under Windows):

DirectShowPlayerService::doRender: Unresolved error code 80040266
     

This is due to the lack of CODECs for x86 / 32bit version (depending on your version)

One thing you can add is the events to check other errors (change [SUA CLASSE] to the class where you will organize the main, perhaps the custom window of a player):

  • Your file .h usually:

    public slots:
        void statusChanged(QMediaPlayer::MediaStatus status);
        void displayErrorMessage();
    
  • Your file .cpp usually:

    void [SUA CLASSE]::statusChanged(QMediaPlayer::MediaStatus status)
    {
        switch (status) {
        case QMediaPlayer::UnknownMediaStatus:
        case QMediaPlayer::NoMedia:
        case QMediaPlayer::LoadedMedia:
        case QMediaPlayer::BufferingMedia:
        case QMediaPlayer::BufferedMedia:
            qDebug() << status;
            break;
        case QMediaPlayer::LoadingMedia:
            qDebug() << "Loading...";
            break;
        case QMediaPlayer::StalledMedia:
            qDebug() << "Media Stalled";
            break;
        case QMediaPlayer::EndOfMedia:
            qDebug() << "Media end";
            break;
        case QMediaPlayer::InvalidMedia:
            displayErrorMessage();
            break;
        }
    }
    
    void [SUA CLASSE]::displayErrorMessage()
    {
        qDebug() << player->errorString();
    }
    
  • And add the signs to SLOTS :

    connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(displayErrorMessage()));
    connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(statusChanged(QMediaPlayer::MediaStatus)));
    

There is also a complete example in the documentation for studying:

A test run:

linkofthevideo: link

    
23.06.2016 / 16:56