Example #1
0
PlayerWin::PlayerWin(QWidget *parent) :
    QWidget(parent)
{
    setMinimumWidth(200);
    //setCursor(QCursor(Qt::UpArrowCursor));
    isFullScreen = false;
    state = 0;
    isWideModel = false;

    mainGLayout = new QGridLayout(this);
    mainGLayout->setMargin(0);
    mainGLayout->setSpacing(0);

    player= new  AVPlayer(this);
    renderer =  new GLWidgetRenderer(this);
    player->setRenderer(renderer);
    player->setAudioOutput(QtAV::AudioOutputFactory::create(QtAV::AudioOutputId_OpenAL));
    QVariantHash opt;
    opt["probesize"] = 14096;
    player->setOptionsForFormat(opt);

    mainGLayout->addWidget(renderer,0,0,1,1);

    //QImage img("://images/icon.png");

    //renderer->setOutAspectRatioMode(VideoRenderer::RendererAspectRatio);
//    QImage img(5,5,QImage::Format_ARGB32);
//    img.fill(Qt::black);
//    renderer->receive(VideoFrame(img));
    renderer->setVisible(false);

    playerMaskLbl = new QLabel;
    playerMaskLbl->setAlignment(Qt::AlignCenter);
    playerMaskLbl->setStyleSheet("background-color:rgba(0,0,0,255)");
    playerMaskLbl->setPixmap(QPixmap("://images/icon.png"));
    mainGLayout->addWidget(playerMaskLbl,1,0,1,1);


    connect(player, SIGNAL(mediaStatusChanged(QtAV::MediaStatus)),
            this, SLOT(handleMediaStatusChanged(QtAV::MediaStatus)));
    connect(player, SIGNAL(error(QtAV::AVError)), this, SLOT(handleError(QtAV::AVError)));
    updateProgressBarT = new QTimer;
    connect(updateProgressBarT, SIGNAL(timeout()), this, SLOT(setProgressbarPosition()));
    updateProgressBarT->start(500);

    subtitleWidget = new SubtitleWidget(this);
    EndOfMediaMark=0;

}
Example #2
0
void StelVideoMgr::loadVideo(const QString& filename, const QString& id, const float x, const float y, const bool show, const float alpha)
{
	if (videoObjects.contains(id))
	{
		qWarning() << "[StelVideoMgr] Video object with ID" << id << "already exists, dropping it";
		dropVideo(id);
	}

	videoObjects[id] = new VideoPlayer;
	videoObjects[id]->videoItem= new QGraphicsVideoItem();
	// This sets a tiny size so that if window should appear before proper resize, it should not disturb.
	videoObjects[id]->videoItem->setSize(QSizeF(1,1));

	videoObjects[id]->player = new QMediaPlayer(0, QMediaPlayer::VideoSurface);
	videoObjects[id]->duration=-1; // -1 to signal "unknown".
	videoObjects[id]->resolution=QSize(); // initialize with "invalid" empty resolution, we must detect this when player is starting!
	videoObjects[id]->keepVisible=false;
	videoObjects[id]->needResize=true; // resolution and target frame not yet known.
	videoObjects[id]->simplePlay=true;
	videoObjects[id]->targetFrameSize=QSizeF(); // start with invalid, depends on parameters given in playVideo(), playPopoutVideo() and resolution detected only after playing started.
	videoObjects[id]->popupOrigin=QPointF();
	videoObjects[id]->popupTargetCenter=QPointF();
	videoObjects[id]->player->setProperty("Stel_id", id); // allow tracking of log messages and access of members.
	videoObjects[id]->player->setVideoOutput(videoObjects[id]->videoItem);
	videoObjects[id]->videoItem->setOpacity(alpha);
#ifndef Q_OS_WIN
	// There is a notable difference: on Windows this causes a crash. On Linux, it is required, else the movie frame is visible before proper resize.
	videoObjects[id]->videoItem->setVisible(show);
#endif
	videoObjects[id]->lastPos=-1;

	// A few connections are not really needed, they are signals we don't use. TBD: Remove or keep commented out?
	connect(videoObjects[id]->player, SIGNAL(bufferStatusChanged(int)), this, SLOT(handleBufferStatusChanged(int)));
	connect(videoObjects[id]->player, SIGNAL(durationChanged(qint64)), this, SLOT(handleDurationChanged(qint64))); // (CRITICALLY IMPORTANT!)
	connect(videoObjects[id]->player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(handleError(QMediaPlayer::Error)));
	connect(videoObjects[id]->player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(handleMediaStatusChanged(QMediaPlayer::MediaStatus)));
	//connect(videoObjects[id]->player, SIGNAL(positionChanged(qint64)), this, SLOT(handlePositionChanged(qint64)));
	// we test isSeekable() where needed, so only debug log entry. --> And we may use the signal however now during blocking load below!
	connect(videoObjects[id]->player, SIGNAL(seekableChanged(bool)), this, SLOT(handleSeekableChanged(bool)));
	connect(videoObjects[id]->player, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(handleStateChanged(QMediaPlayer::State)));
	connect(videoObjects[id]->player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(handleVideoAvailableChanged(bool)));
	connect(videoObjects[id]->player, SIGNAL(audioAvailableChanged(bool)), this, SLOT(handleAudioAvailableChanged(bool)));
	connect(videoObjects[id]->player, SIGNAL(mutedChanged(bool)), this, SLOT(handleMutedChanged(bool)));
	connect(videoObjects[id]->player, SIGNAL(volumeChanged(int)), this, SLOT(handleVolumeChanged(int)));
	connect(videoObjects[id]->player, SIGNAL(availabilityChanged(bool)), this, SLOT(handleAvailabilityChanged(bool)));
	connect(videoObjects[id]->player, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)), this, SLOT(handleAvailabilityChanged(QMultimedia::AvailabilityStatus)));

	// Only this is triggered also on Windows. Lets us read resolution etc. (CRITICALLY IMPORTANT!)
	connect(videoObjects[id]->player, SIGNAL(metaDataChanged()), this, SLOT(handleMetaDataChanged()));
	// That signal would require less overhead, but is not triggered under Windows and apparently also not on MacOS X. (QTBUG-42034.)
	// If this becomes available/bugfixed, it should be preferred as being more elegant.
	// connect(videoObjects[id]->player, SIGNAL(metaDataChanged(QString,QVariant)), this, SLOT(handleMetaDataChanged(QString,QVariant)));

	// We need an absolute pathname here.
	QMediaContent content(QUrl::fromLocalFile(QFileInfo(filename).absoluteFilePath()));
	videoObjects[id]->player->setMedia(content);
	if (verbose)
	{
		qDebug() << "Loading " << content.canonicalUrl();
		qDebug() << "Media Resources queried from player:";
		qDebug() << "\tSTATUS:        " << videoObjects[id]->player->mediaStatus();
		qDebug() << "\tFile:          " << videoObjects[id]->player->currentMedia().canonicalUrl();
	}
//	qDebug() << "scene->addItem...";
	StelMainView::getInstance().scene()->addItem(videoObjects[id]->videoItem);
//	qDebug() << "scene->addItem OK";

	videoObjects[id]->videoItem->setPos(x, y);
	// DEFAULT SIZE: show a tiny frame. This gets updated to native resolution as soon as resolution becomes known. Needed?
	//videoObjects[id]->videoItem->setSize(QSizeF(1, 1));

	// after many troubles with incompletely loaded files we attempt a blocking load from https://wiki.qt.io/Seek_in_Sound_File
	// This may be no longer required. But please keep the block here for testing/reactivation if necessary.
//	if (! videoObjects[id]->player->isSeekable())
//	{
//		qDebug() << "Not Seekable!";
//		if (verbose)
//			qDebug() << "Blocking load ...";
//		QEventLoop loop;
//		QTimer timer;
//		qDebug() << "Not Seekable: setSingleShot";
//		timer.setSingleShot(true);
//		timer.setInterval(5000); // 5 seconds, may be too long?
//		qDebug() << "Not Seekable: connect...";
//		loop.connect(&timer, SIGNAL (timeout()), &loop, SLOT (quit()) );
//		loop.connect(videoObjects[id]->player, SIGNAL (seekableChanged(bool)), &loop, SLOT (quit()));
//		qDebug() << "Not Seekable: loop...";
//		loop.exec();
//		if (verbose)
//			qDebug() << "Blocking load finished, should be seekable now or 5s are over.";
//	}

	if (verbose)
		qDebug() << "Loaded video" << id << "for pos " << x << "/" << y << "Size" << videoObjects[id]->videoItem->size();
	videoObjects[id]->player->setPosition(0); // This should force triggering a metadataAvailable() with resolution update.
	if (show)
		videoObjects[id]->player->play();
	else
		videoObjects[id]->player->pause();
}