Added Video Player page for MainWindow

This commit is contained in:
defnax 2020-01-27 19:45:43 +01:00
parent d35c244bcb
commit 558e80fa2f
9 changed files with 350 additions and 7 deletions

View File

@ -57,6 +57,7 @@
#include "chat/ChatDialog.h" #include "chat/ChatDialog.h"
#include "RetroShareLink.h" #include "RetroShareLink.h"
#include "SoundManager.h" #include "SoundManager.h"
#include "PlayerPage.h"
#include "notifyqt.h" #include "notifyqt.h"
#include "common/UserNotify.h" #include "common/UserNotify.h"
#include "gui/ServicePermissionDialog.h" #include "gui/ServicePermissionDialog.h"
@ -185,6 +186,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags)
gxschannelDialog=NULL; gxschannelDialog=NULL;
gxsforumDialog=NULL; gxsforumDialog=NULL;
postedDialog=NULL; postedDialog=NULL;
playerDialog=NULL;
/* Invoke the Qt Designer generated QObject setup routine */ /* Invoke the Qt Designer generated QObject setup routine */
ui->setupUi(this); ui->setupUi(this);
@ -412,6 +414,7 @@ void MainWindow::initStackedPage()
addPage(gxschannelDialog = new GxsChannelDialog(ui->stackPages), grp, &notify); addPage(gxschannelDialog = new GxsChannelDialog(ui->stackPages), grp, &notify);
addPage(gxsforumDialog = new GxsForumsDialog(ui->stackPages), grp, &notify); addPage(gxsforumDialog = new GxsForumsDialog(ui->stackPages), grp, &notify);
addPage(postedDialog = new PostedDialog(ui->stackPages), grp, &notify); addPage(postedDialog = new PostedDialog(ui->stackPages), grp, &notify);
addPage(playerDialog = new PlayerPage(ui->stackPages), grp, NULL);
#ifdef RS_USE_NEW_PEOPLE_DIALOG #ifdef RS_USE_NEW_PEOPLE_DIALOG
PeopleDialog *peopleDialog = NULL; PeopleDialog *peopleDialog = NULL;
@ -979,6 +982,9 @@ void SetForegroundWindowInternal(HWND hWnd)
case Posted: case Posted:
_instance->ui->stackPages->setCurrentPage( _instance->postedDialog ); _instance->ui->stackPages->setCurrentPage( _instance->postedDialog );
return true ; return true ;
case Player:
_instance->ui->stackPages->setCurrentPage( _instance->playerDialog );
return true ;
default: default:
std::cerr << "Show page called on value that is not handled yet. Please code it! (value = " << page << ")" << std::endl; std::cerr << "Show page called on value that is not handled yet. Please code it! (value = " << page << ")" << std::endl;
} }
@ -1061,6 +1067,8 @@ void SetForegroundWindowInternal(HWND hWnd)
return _instance->gxsforumDialog; return _instance->gxsforumDialog;
case Posted: case Posted:
return _instance->postedDialog; return _instance->postedDialog;
case Player:
return _instance->playerDialog;
} }
return NULL; return NULL;

View File

@ -61,7 +61,7 @@ class TransfersDialog;
class MessagesDialog; class MessagesDialog;
class PluginsPage; class PluginsPage;
class HomePage; class HomePage;
//class ChannelFeed; class PlayerPage;
class BandwidthGraph; class BandwidthGraph;
class MainPage; class MainPage;
class NewsFeed; class NewsFeed;
@ -92,8 +92,9 @@ public:
Forums = 7, /** Forums page. */ Forums = 7, /** Forums page. */
Search = 8, /** Search page. */ Search = 8, /** Search page. */
Posted = 11, /** Posted links */ Posted = 11, /** Posted links */
People = 12, /** People page. */ People = 12, /** People page. */
Options = 13 /** People page. */ Options = 13, /** People page. */
Player = 14 /** Player page. */
}; };
@ -153,6 +154,7 @@ public:
GxsChannelDialog *gxschannelDialog ; GxsChannelDialog *gxschannelDialog ;
GxsForumsDialog *gxsforumDialog ; GxsForumsDialog *gxsforumDialog ;
PostedDialog *postedDialog; PostedDialog *postedDialog;
PlayerPage *playerDialog;
// ForumsDialog *forumsDialog; // ForumsDialog *forumsDialog;
// ChannelFeed *channelFeed; // ChannelFeed *channelFeed;

View File

@ -0,0 +1,209 @@
/*******************************************************************************
* gui/PlayerPage.cpp *
* *
* Copyright (C) 2020 RetroShare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "PlayerPage.h"
#include "ui_PlayerPage.h"
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QUrlQuery>
#endif
#include <iostream>
#include <string>
#include <QtWidgets>
#include <QVideoWidget>
PlayerPage::PlayerPage(QWidget *parent) :
MainPage(parent),
ui(new Ui::PlayerPage)
{
ui->setupUi(this);
mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface);
videoWidget = new QVideoWidget;
videoWidget->show();
videoWidget->setStyleSheet("background-color: #1f1f1f;");
playButton = new QPushButton;
playButton->setEnabled(false);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
stopButton = new QPushButton;
stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));
stopButton->setEnabled(false);
fullScreenButton = new QPushButton(tr("FullScreen"));
fullScreenButton->setCheckable(true);
fullScreenButton->setEnabled(false);
positionSlider = new QSlider(Qt::Horizontal);
positionSlider->setRange(0, mediaPlayer->duration() / 1000);
labelDuration = new QLabel;
errorLabel = new QLabel;
errorLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
QBoxLayout *controlLayout = new QHBoxLayout;
controlLayout->setMargin(0);
controlLayout->addWidget(playButton);
controlLayout->addWidget(stopButton);
controlLayout->addWidget(positionSlider);
controlLayout->addWidget(labelDuration);
controlLayout->addWidget(fullScreenButton);
QBoxLayout *layout = new QVBoxLayout;
layout->addWidget(videoWidget);
layout->addLayout(controlLayout);
layout->addWidget(errorLabel);
ui->widget->setLayout(layout);
mediaPlayer->setVideoOutput(videoWidget);
connect(playButton, &QAbstractButton::clicked,this, &PlayerPage::play);
connect(stopButton, &QAbstractButton::clicked,this, &PlayerPage::stopVideo);
connect(mediaPlayer, &QMediaPlayer::stateChanged,this, &PlayerPage::mediaStateChanged);
connect(mediaPlayer, &QMediaPlayer::positionChanged, this, &PlayerPage::positionChanged);
connect(mediaPlayer, &QMediaPlayer::durationChanged, this, &PlayerPage::durationChanged);
connect(mediaPlayer, QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error),this, &PlayerPage::handleError);
connect(mediaPlayer, SIGNAL(videoAvailableChanged(bool)), this, SLOT(videoAvailableChanged(bool)));
connect(positionSlider, &QSlider::sliderMoved, this, &PlayerPage::seek);
}
PlayerPage::~PlayerPage()
{
delete ui;
}
void PlayerPage::setUrl(const QUrl &url)
{
errorLabel->setText(QString());
mediaPlayer->setMedia(url);
playButton->setEnabled(true);
play();
}
void PlayerPage::play()
{
switch (mediaPlayer->state()) {
//case QMediaPlayer::StoppedState:
case QMediaPlayer::PlayingState:
mediaPlayer->pause();
break;
default:
mediaPlayer->play();
break;
}
}
void PlayerPage::stopVideo()
{
mediaPlayer->stop();
}
void PlayerPage::mediaStateChanged(QMediaPlayer::State state)
{
switch (state) {
case QMediaPlayer::StoppedState:
stopButton->setEnabled(false);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
break;
case QMediaPlayer::PlayingState:
stopButton->setEnabled(true);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
break;
case QMediaPlayer::PausedState:
stopButton->setEnabled(true);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
break;
}
}
void PlayerPage::positionChanged(qint64 progress)
{
if (!positionSlider->isSliderDown())
positionSlider->setValue(progress / 1000);
updateDurationInfo(progress / 1000);
}
void PlayerPage::durationChanged(qint64 duration)
{
duration = duration / 1000;
positionSlider->setMaximum(duration);
}
void PlayerPage::seek(int seconds)
{
mediaPlayer->setPosition(seconds * 1000);
}
void PlayerPage::handleError()
{
playButton->setEnabled(false);
const QString errorString = mediaPlayer->errorString();
QString message = "Error: ";
if (errorString.isEmpty())
message += " #" + QString::number(int(mediaPlayer->error()));
else
message += errorString;
errorLabel->setText(message);
}
void PlayerPage::videoAvailableChanged(bool available)
{
if (!available) {
disconnect(fullScreenButton, SIGNAL(clicked(bool)),
videoWidget, SLOT(setFullScreen(bool)));
disconnect(videoWidget, SIGNAL(fullScreenChanged(bool)),
fullScreenButton, SLOT(setChecked(bool)));
videoWidget->setFullScreen(false);
} else {
connect(fullScreenButton, SIGNAL(clicked(bool)),
videoWidget, SLOT(setFullScreen(bool)));
connect(videoWidget, SIGNAL(fullScreenChanged(bool)),
fullScreenButton, SLOT(setChecked(bool)));
if (fullScreenButton->isChecked())
videoWidget->setFullScreen(true);
}
}
void PlayerPage::updateDurationInfo(qint64 currentInfo)
{
QString tStr;
if (currentInfo || duration) {
QTime currentTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60,
currentInfo % 60, (currentInfo * 1000) % 1000);
QTime totalTime((duration / 3600) % 60, (duration / 60) % 60,
duration % 60, (duration * 1000) % 1000);
QString format = "mm:ss";
if (duration > 3600)
format = "hh:mm:ss";
tStr = currentTime.toString(format) + " / " + totalTime.toString(format);
}
labelDuration->setText(tStr);
}

View File

@ -0,0 +1,91 @@
/*******************************************************************************
* gui/PlayerPage.h *
* *
* Copyright (C) 2020 RetroShare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef PLAYERPAGE_H
#define PLAYERPAGE_H
#include <retroshare-gui/mainpage.h>
#include <retroshare/rsfiles.h>
#include <retroshare/rspeers.h>
#include <QMediaPlayer>
#include <QWidget>
#include <QVideoWidget>
class QAbstractButton;
class QPushButton;
class QSlider;
class QLabel;
class QUrl;
namespace Ui {
class PlayerPage;
}
class PlayerPage : public MainPage
{
Q_OBJECT
public:
explicit PlayerPage(QWidget *parent);
~PlayerPage();
virtual QIcon iconPixmap() const { return QIcon(":/icons/png/video-camera.png") ; } //MainPage
virtual QString pageName() const { return tr("Player") ; } //MainPage
virtual QString helpText() const { return ""; } //MainPage
void setUrl(const QUrl &url);
protected:
//virtual void keyPressEvent(QKeyEvent *e) ;
public slots:
void play();
void stopVideo();
private slots:
void mediaStateChanged(QMediaPlayer::State state);
void positionChanged(qint64 position);
void durationChanged(qint64 duration);
void handleError();
void videoAvailableChanged(bool available);
void seek(int seconds);
private:
void updateDurationInfo(qint64 currentInfo);
QMediaPlayer* mediaPlayer;
QVideoWidget *videoWidget;
QPushButton *playButton;
QPushButton *fullScreenButton;
QPushButton *stopButton;
QSlider *positionSlider;
QLabel *errorLabel;
QLabel *labelDuration;
qint64 duration;
Ui::PlayerPage *ui;
};
#endif // PlayerPage_H

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PlayerPage</class>
<widget class="QWidget" name="PlayerPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>612</width>
<height>450</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QWidget" name="widget" native="true"/>
</item>
</layout>
</widget>
<resources>
<include location="icons.qrc"/>
<include location="images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -24,6 +24,8 @@
#include <QUrl> #include <QUrl>
#include "SubFileItem.h" #include "SubFileItem.h"
#include "gui/PlayerPage.h"
#include "gui/MainWindow.h"
#include <gui/common/RsUrlHandler.h> #include <gui/common/RsUrlHandler.h>
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
@ -587,9 +589,9 @@ void SubFileItem::play()
QFileInfo qinfo; QFileInfo qinfo;
qinfo.setFile(info.path.c_str()); qinfo.setFile(info.path.c_str());
if (qinfo.exists()) { if (qinfo.exists()) {
if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(qinfo.absoluteFilePath()))) { MainWindow::showWindow(MainWindow::Player);
std::cerr << "openTransfer(): can't open file " << info.path << std::endl; PlayerPage *Player = dynamic_cast<PlayerPage*>(MainWindow::getPage(MainWindow::Player));
} Player->setUrl(QUrl::fromLocalFile(qinfo.absoluteFilePath()));
}else{ }else{
QMessageBox::information(this, tr("Play File"), QMessageBox::information(this, tr("Play File"),
tr("File %1 does not exist at location.").arg(info.path.c_str())); tr("File %1 does not exist at location.").arg(info.path.c_str()));

View File

@ -136,6 +136,7 @@
<file>icons/png/thumbs-up.png</file> <file>icons/png/thumbs-up.png</file>
<file>icons/png/typing.png</file> <file>icons/png/typing.png</file>
<file>icons/png/video.png</file> <file>icons/png/video.png</file>
<file>icons/png/video-camera.png</file>
<file>icons/posted_128.png</file> <file>icons/posted_128.png</file>
<file>icons/posted_red_128.png</file> <file>icons/posted_red_128.png</file>
<file>icons/quit_128.png</file> <file>icons/quit_128.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -19,7 +19,7 @@
!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") !include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
TEMPLATE = app TEMPLATE = app
QT += network xml QT += network xml multimedia multimediawidgets
CONFIG += qt gui uic qrc resources idle CONFIG += qt gui uic qrc resources idle
CONFIG += console CONFIG += console
TARGET = retroshare TARGET = retroshare
@ -415,6 +415,7 @@ HEADERS += rshare.h \
gui/SoundManager.h \ gui/SoundManager.h \
gui/HelpDialog.h \ gui/HelpDialog.h \
gui/LogoBar.h \ gui/LogoBar.h \
gui/PlayerPage.h \
gui/common/AvatarDialog.h \ gui/common/AvatarDialog.h \
gui/FileTransfer/SearchDialog.h \ gui/FileTransfer/SearchDialog.h \
gui/FileTransfer/SharedFilesDialog.h \ gui/FileTransfer/SharedFilesDialog.h \
@ -668,6 +669,7 @@ FORMS += gui/StartDialog.ui \
# gui/ShareDialog.ui \ # gui/ShareDialog.ui \
gui/help/browser/helpbrowser.ui \ gui/help/browser/helpbrowser.ui \
gui/HelpDialog.ui \ gui/HelpDialog.ui \
gui/PlayerPage.ui \
gui/ServicePermissionDialog.ui \ gui/ServicePermissionDialog.ui \
gui/profile/ProfileWidget.ui \ gui/profile/ProfileWidget.ui \
gui/profile/StatusMessage.ui \ gui/profile/StatusMessage.ui \
@ -790,6 +792,7 @@ SOURCES += main.cpp \
# gui/ShareDialog.cpp \ # gui/ShareDialog.cpp \
# gui/SFListDelegate.cpp \ # gui/SFListDelegate.cpp \
gui/SoundManager.cpp \ gui/SoundManager.cpp \
gui/PlayerPage.cpp \
gui/im_history/ImHistoryBrowser.cpp \ gui/im_history/ImHistoryBrowser.cpp \
gui/im_history/IMHistoryItemDelegate.cpp \ gui/im_history/IMHistoryItemDelegate.cpp \
gui/im_history/IMHistoryItemPainter.cpp \ gui/im_history/IMHistoryItemPainter.cpp \