QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsmediawidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmediawidget.cpp
3
4 ---------------------
5 begin : 2023.01.24
6 copyright : (C) 2023 by Mathieu Pellerin
7 email : mathieu at opengis dot ch
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include "qgsmediawidget.h"
18#include "moc_qgsmediawidget.cpp"
19#include "qgsapplication.h"
20
21#include <QLabel>
22#include <QHBoxLayout>
23#include <QVBoxLayout>
24#include <QPushButton>
25#include <QSlider>
26#include <QVideoWidget>
27
28
30 : QWidget( parent )
31{
32 mLayout = new QVBoxLayout();
33 mLayout->setContentsMargins( 0, 0, 0, 0 );
34
35 mVideoWidget = new QVideoWidget( this );
36 const int vHeight = QFontMetrics( font() ).height() * 12;
37 mVideoWidget->setMinimumHeight( vHeight );
38 mVideoWidget->setMaximumHeight( vHeight );
39 mLayout->addWidget( mVideoWidget );
40
41 QHBoxLayout *controlsLayout = new QHBoxLayout();
42 controlsLayout->setContentsMargins( 0, 0, 0, 0 );
43
44 mPlayButton = new QPushButton( this );
45 mPlayButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
46 mPlayButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionPlay.svg" ) ) );
47 mPlayButton->setCheckable( true );
48 controlsLayout->addWidget( mPlayButton );
49
50 mPositionSlider = new QSlider( this );
51 mPositionSlider->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
52 mPositionSlider->setOrientation( Qt::Horizontal );
53 controlsLayout->addWidget( mPositionSlider );
54
55 mDurationLabel = new QLabel( this );
56 mDurationLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
57 mDurationLabel->setAlignment( Qt::AlignHCenter );
58 mDurationLabel->setText( QStringLiteral( "-" ) );
59 QFontMetrics fm( mDurationLabel->font() );
60 mDurationLabel->setMinimumWidth( fm.boundingRect( QStringLiteral( "00:00:00" ) ).width() );
61 controlsLayout->addWidget( mDurationLabel );
62
63 QWidget *controls = new QWidget();
64 controls->setLayout( controlsLayout );
65
66 mLayout->addWidget( controls );
67 setLayout( mLayout );
68
69 adjustControls();
70 setControlsEnabled( false );
71
72 mMediaPlayer.setVideoOutput( mVideoWidget );
73
74 connect( &mMediaPlayer, &QMediaPlayer::mediaStatusChanged, this, &QgsMediaWidget::mediaStatusChanged );
75 connect( &mMediaPlayer, &QMediaPlayer::positionChanged, this, [=]() {
76 mPositionSlider->setValue( static_cast<int>( mMediaPlayer.position() / 1000 ) );
77 } );
78
79 connect( mPlayButton, &QAbstractButton::clicked, this, [=]() {
80#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
81 if ( mMediaPlayer.playbackState() == QMediaPlayer::PlayingState )
82#else
83 if ( mMediaPlayer.state() == QMediaPlayer::PlayingState )
84#endif
85 {
86 mMediaPlayer.pause();
87 }
88 else
89 {
90 mMediaPlayer.play();
91 }
92 } );
93 connect( mPositionSlider, &QAbstractSlider::sliderReleased, this, [=]() {
94 mMediaPlayer.setPosition( static_cast<qint64>( mPositionSlider->value() ) * 1000 );
95 } );
96}
97
98void QgsMediaWidget::setMediaPath( const QString &path )
99{
100 if ( mMediaPath == path )
101 return;
102
103 mMediaPath = path;
104#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
105 mMediaPlayer.setSource( QUrl::fromLocalFile( path ) );
106#else
107 mMediaPlayer.setMedia( QUrl::fromLocalFile( path ) );
108#endif
109}
110
112{
113 if ( mMode == mode )
114 return;
115
116 mMode = mode;
117 adjustControls();
118}
119
121{
122 return mVideoWidget->minimumHeight();
123}
124
126{
127 const int vHeight = height > 0 ? height : QFontMetrics( font() ).height() * 12;
128 mVideoWidget->setMinimumHeight( vHeight );
129 mVideoWidget->setMaximumHeight( vHeight );
130}
131
132void QgsMediaWidget::adjustControls()
133{
134 switch ( mMode )
135 {
136 case Audio:
137 {
138 mVideoWidget->setVisible( false );
139 break;
140 }
141 case Video:
142 {
143 mVideoWidget->setVisible( true );
144 break;
145 }
146 }
147}
148
149void QgsMediaWidget::setControlsEnabled( bool enabled )
150{
151 mPlayButton->setEnabled( enabled );
152 mPositionSlider->setEnabled( enabled );
153}
154
155void QgsMediaWidget::mediaStatusChanged( QMediaPlayer::MediaStatus status )
156{
157 switch ( status )
158 {
159 case QMediaPlayer::LoadedMedia:
160 {
161 setControlsEnabled( true );
162 mPositionSlider->setMinimum( 0 );
163 mPositionSlider->setMaximum( static_cast<int>( mMediaPlayer.duration() / 1000 ) );
164 mPositionSlider->setValue( 0 );
165 int seconds = std::floor( mMediaPlayer.duration() / 1000 );
166 const int hours = std::floor( seconds / 3600 );
167 seconds -= hours * 3600;
168 const int minutes = std::floor( seconds / 60 );
169 seconds -= minutes * 60;
170 mDurationLabel->setText( QStringLiteral( "%1:%2:%3" ).arg( QString::number( hours ), 2, '0' ).arg( QString::number( minutes ), 2, '0' ).arg( QString::number( seconds ), 2, '0' ) );
171 break;
172 }
173
174 case QMediaPlayer::EndOfMedia:
175 {
176 mPlayButton->setChecked( false );
177 break;
178 }
179
180 case QMediaPlayer::LoadingMedia:
181 case QMediaPlayer::StalledMedia:
182 case QMediaPlayer::BufferingMedia:
183 case QMediaPlayer::BufferedMedia:
184 {
185 break;
186 }
187
188 case QMediaPlayer::InvalidMedia:
189 {
190 setControlsEnabled( false );
191 mDurationLabel->setText( tr( "invalid" ) );
192 break;
193 }
194
195 case QMediaPlayer::NoMedia:
196#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
197 case QMediaPlayer::UnknownMediaStatus:
198#endif
199 {
200 setControlsEnabled( false );
201 mDurationLabel->setText( QStringLiteral( "-" ) );
202 break;
203 }
204 }
205}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
QgsMediaWidget(QWidget *parent=nullptr)
Constructor.
Mode mode() const
Returns the media widget mode.
int videoHeight() const
Returns the video frame height.
Mode
The mode determines the user interface elements visible within the widget.
@ Video
Video-centric user interface.
@ Audio
Audio-centric user interface.
void setMode(Mode mode)
Sets the media widget mode.
void setVideoHeight(int height)
Sets the video frame height.
void setMediaPath(const QString &path)
Sets the media path.