QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
19#include "qgsapplication.h"
20
21#include <QHBoxLayout>
22#include <QLabel>
23#include <QPushButton>
24#include <QSlider>
25#include <QVBoxLayout>
26#include <QVideoWidget>
27
28#include "moc_qgsmediawidget.cpp"
29
31 : QWidget( parent )
32{
33 mLayout = new QVBoxLayout();
34 mLayout->setContentsMargins( 0, 0, 0, 0 );
35
36 mVideoWidget = new QVideoWidget( this );
37 const int vHeight = QFontMetrics( font() ).height() * 12;
38 mVideoWidget->setMinimumHeight( vHeight );
39 mVideoWidget->setMaximumHeight( vHeight );
40 mLayout->addWidget( mVideoWidget );
41
42 QHBoxLayout *controlsLayout = new QHBoxLayout();
43 controlsLayout->setContentsMargins( 0, 0, 0, 0 );
44
45 mPlayButton = new QPushButton( this );
46 mPlayButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
47 mPlayButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionPlay.svg" ) ) );
48 mPlayButton->setCheckable( true );
49 controlsLayout->addWidget( mPlayButton );
50
51 mPositionSlider = new QSlider( this );
52 mPositionSlider->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
53 mPositionSlider->setOrientation( Qt::Horizontal );
54 controlsLayout->addWidget( mPositionSlider );
55
56 mDurationLabel = new QLabel( this );
57 mDurationLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
58 mDurationLabel->setAlignment( Qt::AlignHCenter );
59 mDurationLabel->setText( QStringLiteral( "-" ) );
60 QFontMetrics fm( mDurationLabel->font() );
61 mDurationLabel->setMinimumWidth( fm.boundingRect( QStringLiteral( "00:00:00" ) ).width() );
62 controlsLayout->addWidget( mDurationLabel );
63
64 QWidget *controls = new QWidget();
65 controls->setLayout( controlsLayout );
66
67 mLayout->addWidget( controls );
68 setLayout( mLayout );
69
70 adjustControls();
71 setControlsEnabled( false );
72
73 mMediaPlayer.setVideoOutput( mVideoWidget );
74
75 connect( &mMediaPlayer, &QMediaPlayer::mediaStatusChanged, this, &QgsMediaWidget::mediaStatusChanged );
76 connect( &mMediaPlayer, &QMediaPlayer::positionChanged, this, [this]() {
77 mPositionSlider->setValue( static_cast<int>( mMediaPlayer.position() / 1000 ) );
78 } );
79
80 connect( mPlayButton, &QAbstractButton::clicked, this, [this]() {
81#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
82 if ( mMediaPlayer.playbackState() == QMediaPlayer::PlayingState )
83#else
84 if ( mMediaPlayer.state() == QMediaPlayer::PlayingState )
85#endif
86 {
87 mMediaPlayer.pause();
88 }
89 else
90 {
91 mMediaPlayer.play();
92 }
93 } );
94 connect( mPositionSlider, &QAbstractSlider::sliderReleased, this, [this]() {
95 mMediaPlayer.setPosition( static_cast<qint64>( mPositionSlider->value() ) * 1000 );
96 } );
97}
98
99void QgsMediaWidget::setMediaPath( const QString &path )
100{
101 if ( mMediaPath == path )
102 return;
103
104 mMediaPath = path;
105#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
106 mMediaPlayer.setSource( QUrl::fromLocalFile( path ) );
107#else
108 mMediaPlayer.setMedia( QUrl::fromLocalFile( path ) );
109#endif
110}
111
113{
114 if ( mMode == mode )
115 return;
116
117 mMode = mode;
118 adjustControls();
119}
120
122{
123 return mVideoWidget->minimumHeight();
124}
125
127{
128 const int vHeight = height > 0 ? height : QFontMetrics( font() ).height() * 12;
129 mVideoWidget->setMinimumHeight( vHeight );
130 mVideoWidget->setMaximumHeight( vHeight );
131}
132
133void QgsMediaWidget::adjustControls()
134{
135 switch ( mMode )
136 {
137 case Audio:
138 {
139 mVideoWidget->setVisible( false );
140 break;
141 }
142 case Video:
143 {
144 mVideoWidget->setVisible( true );
145 break;
146 }
147 }
148}
149
150void QgsMediaWidget::setControlsEnabled( bool enabled )
151{
152 mPlayButton->setEnabled( enabled );
153 mPositionSlider->setEnabled( enabled );
154}
155
156void QgsMediaWidget::mediaStatusChanged( QMediaPlayer::MediaStatus status )
157{
158 switch ( status )
159 {
160 case QMediaPlayer::LoadedMedia:
161 {
162 setControlsEnabled( true );
163 mPositionSlider->setMinimum( 0 );
164 mPositionSlider->setMaximum( static_cast<int>( mMediaPlayer.duration() / 1000 ) );
165 mPositionSlider->setValue( 0 );
166 int seconds = std::floor( mMediaPlayer.duration() / 1000 );
167 const int hours = std::floor( seconds / 3600 );
168 seconds -= hours * 3600;
169 const int minutes = std::floor( seconds / 60 );
170 seconds -= minutes * 60;
171 mDurationLabel->setText( QStringLiteral( "%1:%2:%3" ).arg( QString::number( hours ), 2, '0' ).arg( QString::number( minutes ), 2, '0' ).arg( QString::number( seconds ), 2, '0' ) );
172 break;
173 }
174
175 case QMediaPlayer::EndOfMedia:
176 {
177 mPlayButton->setChecked( false );
178 break;
179 }
180
181 case QMediaPlayer::LoadingMedia:
182 case QMediaPlayer::StalledMedia:
183 case QMediaPlayer::BufferingMedia:
184 case QMediaPlayer::BufferedMedia:
185 {
186 break;
187 }
188
189 case QMediaPlayer::InvalidMedia:
190 {
191 setControlsEnabled( false );
192 mDurationLabel->setText( tr( "invalid" ) );
193 break;
194 }
195
196 case QMediaPlayer::NoMedia:
197#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
198 case QMediaPlayer::UnknownMediaStatus:
199#endif
200 {
201 setControlsEnabled( false );
202 mDurationLabel->setText( QStringLiteral( "-" ) );
203 break;
204 }
205 }
206}
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.