QGIS API Documentation 3.41.0-Master (3440c17df1d)
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 {
77 mPositionSlider->setValue( static_cast<int>( mMediaPlayer.position() / 1000 ) );
78 } );
79
80 connect( mPlayButton, &QAbstractButton::clicked, this, [ = ]()
81 {
82#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
83 if ( mMediaPlayer.playbackState() == QMediaPlayer::PlayingState )
84#else
85 if ( mMediaPlayer.state() == QMediaPlayer::PlayingState )
86#endif
87 {
88 mMediaPlayer.pause();
89 }
90 else
91 {
92 mMediaPlayer.play();
93 }
94 } );
95 connect( mPositionSlider, &QAbstractSlider::sliderReleased, this, [ = ]()
96 {
97 mMediaPlayer.setPosition( static_cast<qint64>( mPositionSlider->value() ) * 1000 );
98 } );
99}
100
101void QgsMediaWidget::setMediaPath( const QString &path )
102{
103 if ( mMediaPath == path )
104 return;
105
106 mMediaPath = path;
107#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
108 mMediaPlayer.setSource( QUrl::fromLocalFile( path ) );
109#else
110 mMediaPlayer.setMedia( QUrl::fromLocalFile( path ) );
111#endif
112}
113
115{
116 if ( mMode == mode )
117 return;
118
119 mMode = mode;
120 adjustControls();
121}
122
124{
125 return mVideoWidget->minimumHeight();
126}
127
129{
130 const int vHeight = height > 0 ? height : QFontMetrics( font() ).height() * 12;
131 mVideoWidget->setMinimumHeight( vHeight );
132 mVideoWidget->setMaximumHeight( vHeight );
133}
134
135void QgsMediaWidget::adjustControls()
136{
137 switch ( mMode )
138 {
139 case Audio:
140 {
141 mVideoWidget->setVisible( false );
142 break;
143 }
144 case Video:
145 {
146 mVideoWidget->setVisible( true );
147 break;
148 }
149 }
150}
151
152void QgsMediaWidget::setControlsEnabled( bool enabled )
153{
154 mPlayButton->setEnabled( enabled );
155 mPositionSlider->setEnabled( enabled );
156}
157
158void QgsMediaWidget::mediaStatusChanged( QMediaPlayer::MediaStatus status )
159{
160 switch ( status )
161 {
162 case QMediaPlayer::LoadedMedia:
163 {
164 setControlsEnabled( true );
165 mPositionSlider->setMinimum( 0 );
166 mPositionSlider->setMaximum( static_cast<int>( mMediaPlayer.duration() / 1000 ) );
167 mPositionSlider->setValue( 0 );
168 int seconds = std::floor( mMediaPlayer.duration() / 1000 );
169 const int hours = std::floor( seconds / 3600 );
170 seconds -= hours * 3600;
171 const int minutes = std::floor( seconds / 60 );
172 seconds -= minutes * 60;
173 mDurationLabel->setText( QStringLiteral( "%1:%2:%3" ).arg( QString::number( hours ), 2, '0' )
174 .arg( QString::number( minutes ), 2, '0' )
175 .arg( QString::number( seconds ), 2, '0' ) );
176 break;
177 }
178
179 case QMediaPlayer::EndOfMedia:
180 {
181 mPlayButton->setChecked( false );
182 break;
183 }
184
185 case QMediaPlayer::LoadingMedia:
186 case QMediaPlayer::StalledMedia:
187 case QMediaPlayer::BufferingMedia:
188 case QMediaPlayer::BufferedMedia:
189 {
190 break;
191 }
192
193 case QMediaPlayer::InvalidMedia:
194 {
195 setControlsEnabled( false );
196 mDurationLabel->setText( tr( "invalid" ) );
197 break;
198 }
199
200 case QMediaPlayer::NoMedia:
201#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
202 case QMediaPlayer::UnknownMediaStatus:
203#endif
204 {
205 setControlsEnabled( false );
206 mDurationLabel->setText( QStringLiteral( "-" ) );
207 break;
208 }
209 }
210}
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.