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