• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 9624594036

22 Jun 2024 09:48AM UTC coverage: 12.209%. First build
9624594036

Pull #3775

github

gzotti
Silence video sound on Qt5.
This may not circumvent problems with missing hardware,
just make sure no sound emits the speakers.
Pull Request #3775: Allow disabling StelAudioMgr at runtime

0 of 61 new or added lines in 3 files covered. (0.0%)

14429 of 118188 relevant lines covered (12.21%)

18945.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/core/StelVideoMgr.cpp
1
/*
2
 * Copyright (C) 2012 Sibi Antony (Phonon/QT4 implementation)
3
 * Copyright (C) 2015 Georg Zotti (Reactivated with QT5 classes)
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18
 */
19

20
#include "StelVideoMgr.hpp"
21
#include "StelMainView.hpp"
22
#include <QDebug>
23
#include <QDir>
24
#ifdef ENABLE_MEDIA
25
        #include <QGraphicsVideoItem>
26
        #include <QMediaPlayer>
27
        #include <QTimer>
28
        #include <QApplication>
29
#include "StelFader.hpp"
30
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
31
        #include <QMediaFormat>
32
        #include <QAudioOutput>
33
        #include <QVideoSink>
34
        #include <QMediaMetaData>
35
#endif
36
#endif
37

38

NEW
39
StelVideoMgr::StelVideoMgr(bool withAudio) : StelModule(), audioEnabled(withAudio)
×
40
{
41
        setObjectName("StelVideoMgr");
×
42
#ifdef ENABLE_MEDIA
43
        // in case the property has not been set, getProperty() returns invalid.
44
        verbose= (qApp->property("verbose") == true);
×
45
        #if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
46
        if (verbose)
×
47
        {
NEW
48
                QMediaFormat fmt=QMediaFormat();
×
49
                qDebug() << "StelVideoMgr: Supported file formats: " << fmt.supportedFileFormats(QMediaFormat::Decode);
×
50
                qDebug() << "StelVideoMgr: Supported video codecs: " << fmt.supportedVideoCodecs(QMediaFormat::Decode);
×
NEW
51
                if (audioEnabled)
×
NEW
52
                        qDebug() << "StelVideoMgr: Supported audio codecs: " << fmt.supportedAudioCodecs(QMediaFormat::Decode);
×
53
        }
×
54
        #endif
55
#endif
56
}
×
57

58
#ifdef ENABLE_MEDIA
59
StelVideoMgr::~StelVideoMgr()
×
60
{
61
        QMutableMapIterator<QString, StelVideoMgr::VideoPlayer*>it(videoObjects);
×
62
        while (it.hasNext())
×
63
        {
64
                it.next();
×
NEW
65
                if (it.value()!=nullptr)
×
66
                {
67
                        it.value()->player->stop();
×
68
                        StelMainView::getInstance().scene()->removeItem(it.value()->videoItem);
×
69
                        delete it.value()->player;
×
70
                        delete it.value()->videoItem;
×
71
                        #if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
72
                        delete it.value()->audioOutput;
×
73
                        #endif
74
                        it.remove();
×
75
                }
76
        }
77
}
×
78

79
void StelVideoMgr::loadVideo(const QString& filename, const QString& id, const float x, const float y, const bool show, const float alpha)
×
80
{
81
        if (videoObjects.contains(id))
×
82
        {
83
                qWarning() << "[StelVideoMgr] Video object with ID" << id << "already exists, dropping it";
×
84
                dropVideo(id);
×
85
        }
86

87
        videoObjects[id] = new VideoPlayer;
×
88
        videoObjects[id]->videoItem= new QGraphicsVideoItem();
×
89
        // This sets a tiny size so that if window should appear before proper resize, it should not disturb.
90
        videoObjects[id]->videoItem->setSize(QSizeF(1,1));
×
91

92
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
NEW
93
        videoObjects[id]->player = new QMediaPlayer(nullptr);
×
NEW
94
        if (audioEnabled)
×
95
        {
NEW
96
                videoObjects[id]->audioOutput = new QAudioOutput();
×
NEW
97
                videoObjects[id]->player->setAudioOutput(videoObjects[id]->audioOutput);
×
98
        }
99
        else
NEW
100
                videoObjects[id]->audioOutput = nullptr;
×
101

102
        videoObjects[id]->resolution=QSize(200,200); // We must initialize with "valid" resolution, maybe resize when player is starting!
×
103
        videoObjects[id]->targetFrameSize=QSizeF(100, 200); // depends on parameters given in playVideo(), playPopoutVideo() and resolution detected only after playing started.
×
104
#else
105
        videoObjects[id]->player = new QMediaPlayer(nullptr, QMediaPlayer::VideoSurface);
106
        videoObjects[id]->player->setAudioRole(audioEnabled ? QAudio::VideoRole : QAudio::UnknownRole);
107
        if (!audioEnabled)
108
                videoObjects[id]->player->setMuted(true);
109
        videoObjects[id]->resolution=QSize(); // initialize with "invalid" empty resolution, we must detect this when player is starting!
110
        videoObjects[id]->targetFrameSize=QSizeF(); // start with invalid, depends on parameters given in playVideo(), playPopoutVideo() and resolution detected only after playing started.
111
#endif
112
        videoObjects[id]->duration=-1; // -1 to signal "unknown".
×
113
        videoObjects[id]->keepVisible=false;
×
114
        videoObjects[id]->needResize=true; // resolution and target frame not yet known.
×
115
        videoObjects[id]->simplePlay=true;
×
116
        videoObjects[id]->popupOrigin=QPointF();
×
117
        videoObjects[id]->popupTargetCenter=QPointF();
×
118
        videoObjects[id]->player->setProperty("Stel_id", id); // allow tracking of log messages and access of members.
×
119
        videoObjects[id]->player->setVideoOutput(videoObjects[id]->videoItem);
×
120
        videoObjects[id]->videoItem->setOpacity(alpha);
×
121
        // There was a notable difference: on Windows this causes a crash (Qt5.4?) or prevents being visible in Qt5.9! Qt5.12 is OK.
122
        // On Linux, it is required, else the movie frame is visible before proper resize.
123
        videoObjects[id]->videoItem->setVisible(show);
×
124
        videoObjects[id]->lastPos=-1;
×
125

126
        // A few connections are not really needed, they are signals we don't use. TBD: Remove or keep commented out?
127
        connect(videoObjects[id]->player, SIGNAL(durationChanged(qint64)), this, SLOT(handleDurationChanged(qint64))); // (CRITICALLY IMPORTANT!)
×
128
        connect(videoObjects[id]->player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(handleMediaStatusChanged(QMediaPlayer::MediaStatus)));
×
129
        //connect(videoObjects[id]->player, SIGNAL(positionChanged(qint64)), this, SLOT(handlePositionChanged(qint64)));
130
        // we test isSeekable() where needed, so only debug log entry. --> And we may use the signal however now during blocking load below!
131
        connect(videoObjects[id]->player, SIGNAL(seekableChanged(bool)), this, SLOT(handleSeekableChanged(bool)));
×
132
        #if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
133
        connect(videoObjects[id]->player, SIGNAL(bufferProgressChanged(float)), this, SLOT(handleBufferProgressChanged(float)));
×
134
        connect(videoObjects[id]->player, SIGNAL(errorOccurred(QMediaPlayer::Error, const QString &)), this, SLOT(handleErrorMsg(QMediaPlayer::Error, const QString &)));
×
135
        connect(videoObjects[id]->player, SIGNAL(playbackStateChanged(QMediaPlayer::PlaybackState)), this, SLOT(handleStateChanged(QMediaPlayer::PlaybackState)));
×
136
        connect(videoObjects[id]->player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(handleMediaStatusChanged(QMediaPlayer::MediaStatus)));
×
137
        connect(videoObjects[id]->player, SIGNAL(hasVideoChanged(bool)), this, SLOT(handleVideoAvailableChanged(bool)));
×
138
        connect(videoObjects[id]->player, SIGNAL(hasAudioChanged(bool)), this, SLOT(handleAudioAvailableChanged(bool)));
×
139
        connect(videoObjects[id]->player, SIGNAL(sourceChanged(const QUrl &)), this, SLOT(handleSourceChanged(const QUrl &)));
×
140
        #else
141
        connect(videoObjects[id]->player, SIGNAL(bufferStatusChanged(int)), this, SLOT(handleBufferStatusChanged(int)));
142
        connect(videoObjects[id]->player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(handleError(QMediaPlayer::Error)));
143
        connect(videoObjects[id]->player, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(handleStateChanged(QMediaPlayer::State)));
144
        connect(videoObjects[id]->player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(handleVideoAvailableChanged(bool)));
145
        connect(videoObjects[id]->player, SIGNAL(audioAvailableChanged(bool)), this, SLOT(handleAudioAvailableChanged(bool)));
146
        connect(videoObjects[id]->player, SIGNAL(mutedChanged(bool)), this, SLOT(handleMutedChanged(bool)));
147
        connect(videoObjects[id]->player, SIGNAL(volumeChanged(int)), this, SLOT(handleVolumeChanged(int)));
148
        connect(videoObjects[id]->player, SIGNAL(availabilityChanged(bool)), this, SLOT(handleAvailabilityChanged(bool)));
149
        connect(videoObjects[id]->player, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)), this, SLOT(handleAvailabilityChanged(QMultimedia::AvailabilityStatus)));
150
        #endif
151

152
        // Only this is triggered also on Windows. Lets us read resolution etc. (CRITICALLY IMPORTANT!)
153
        connect(videoObjects[id]->player, SIGNAL(metaDataChanged()), this, SLOT(handleMetaDataChanged()));
×
154

155
        // We need an absolute pathname here.
156
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
157
        QUrl url(QUrl::fromLocalFile(QFileInfo(filename).absoluteFilePath()));
×
158
        videoObjects[id]->player->setSource(url);
×
159
#else
160
        QMediaContent content(QUrl::fromLocalFile(QFileInfo(filename).absoluteFilePath()));
161
        videoObjects[id]->player->setMedia(content);
162
#endif
163
        if (verbose)
×
164
        {
165
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
166
                qDebug() << "Loading " << url;
×
167
#elif (QT_VERSION>=QT_VERSION_CHECK(5,14,0))
168
                qDebug() << "Loading " << content.request().url();
169
#else
170
                qDebug() << "Loading " << content.canonicalUrl();
171
#endif
172
                qDebug() << "Media Resources queried from player:";
×
173
                qDebug() << "\tSTATUS:        " << videoObjects[id]->player->mediaStatus();
×
174
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
175
                qDebug() << "\tFile:          " << videoObjects[id]->player->source();
×
176
#elif (QT_VERSION>=QT_VERSION_CHECK(5,14,0))
177
                qDebug() << "\tFile:          " << videoObjects[id]->player->currentMedia().request().url();
178
#else
179
                qDebug() << "\tFile:          " << videoObjects[id]->player->currentMedia().canonicalUrl();
180
#endif
181
        }
182
//        qDebug() << "scene->addItem...";
183
        StelMainView::getInstance().scene()->addItem(videoObjects[id]->videoItem);
×
184
//        qDebug() << "scene->addItem OK";
185

186
        videoObjects[id]->videoItem->setPos(x, y);
×
187
        // DEFAULT SIZE: show a tiny frame. This gets updated to native resolution as soon as resolution becomes known. Needed?
188
        //videoObjects[id]->videoItem->setSize(QSizeF(1, 1));
189

190
        // after many troubles with incompletely loaded files we attempt a blocking load from https://wiki.qt.io/Seek_in_Sound_File
191
        // This may be no longer required. But please keep the block here for testing/reactivation if necessary.
192
//        if (! videoObjects[id]->player->isSeekable())
193
//        {
194
//                qDebug() << "Not Seekable!";
195
//                if (verbose)
196
//                        qDebug() << "Blocking load ...";
197
//                QEventLoop loop;
198
//                QTimer timer;
199
//                qDebug() << "Not Seekable: setSingleShot";
200
//                timer.setSingleShot(true);
201
//                timer.setInterval(5000); // 5 seconds, may be too long?
202
//                qDebug() << "Not Seekable: connect...";
203
//                loop.connect(&timer, SIGNAL (timeout()), &loop, SLOT (quit()) );
204
//                loop.connect(videoObjects[id]->player, SIGNAL (seekableChanged(bool)), &loop, SLOT (quit()));
205
//                qDebug() << "Not Seekable: loop...";
206
//                loop.exec();
207
//                if (verbose)
208
//                        qDebug() << "Blocking load finished, should be seekable now or 5s are over.";
209
//        }
210

211
        if (verbose)
×
212
                qDebug() << "Loaded video" << id << "for pos " << x << "/" << y << "Size" << videoObjects[id]->videoItem->size();
×
213
        videoObjects[id]->player->setPosition(0); // This should force triggering a metadataAvailable() with resolution update.
×
214
        if (show)
×
215
                videoObjects[id]->player->play();
×
216
        else
217
                videoObjects[id]->player->pause();
×
218
}
×
219

220
void StelVideoMgr::playVideo(const QString& id, const bool keepVisibleAtEnd)
×
221
{
222
        if (videoObjects.contains(id))
×
223
        {
224
                videoObjects[id]->keepVisible=keepVisibleAtEnd;
×
NEW
225
                if (videoObjects[id]->player!=nullptr)
×
226
                {
227
                        // if already playing, stop and play from the start
228
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
229
                        if (videoObjects[id]->player->playbackState() == QMediaPlayer::PlayingState)
×
230
#else
231
                        if (videoObjects[id]->player->state() == QMediaPlayer::PlayingState)
232
#endif
233
                        {
234
                                videoObjects[id]->player->stop();
×
235
                        }
236
                        // otherwise just play it, or resume playing paused video.
237
                        videoObjects[id]->videoItem->setVisible(true);
×
238
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
239
                        if (videoObjects[id]->player->playbackState() == QMediaPlayer::PausedState)
×
240
#else
241
                        if (videoObjects[id]->player->state() == QMediaPlayer::PausedState)
242
#endif
243
                                videoObjects[id]->lastPos=videoObjects[id]->player->position() - 1;
×
244
                        else
245
                                videoObjects[id]->lastPos=-1;
×
246

247
                        videoObjects[id]->simplePlay=true;
×
248
                        videoObjects[id]->player->play();
×
249
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
250
                        videoObjects[id]->videoItem->show();
×
251
                        if (verbose)
×
252
                                qDebug() << "StelVideoMgr::playVideo(): playing " << id << videoObjects[id]->player->playbackState() << " - media: " << videoObjects[id]->player->mediaStatus();
×
253
#else
254
                        if (verbose)
255
                                qDebug() << "StelVideoMgr::playVideo(): playing " << id << videoObjects[id]->player->state() << " - media: " << videoObjects[id]->player->mediaStatus();
256
#endif
257
                }
258
        }
259
        else qDebug() << "StelVideoMgr::playVideo(" << id << "): no such video";
×
260
}
×
261

262

263
//! Play a video which has previously been loaded with loadVideo with a complex start/end effect.
264
//! The video appears to grow out from @param fromX/ @param fromY
265
//! within @param popupDuration to size @param finalSizeX/@param finalSizeY, and
266
//! shrinks back towards @param fromX/@param fromY at the end during @param popdownDuration.
267
//! @param id the identifier used when @name loadVideo() was called
268
//! @param fromX X position of starting point, counted from left of window. May be absolute pixel coordinate (if >1) or relative to screen size (0<X<1)
269
//! @param fromY Y position of starting point, counted from top of window. May be absolute pixel coordinate (if >1) or relative to screen size (0<Y<1)
270
//! @param atCenterX X position of center of final video frame, counted from left of window. May be absolute pixel coordinate (if >1) or relative to screen size (0<X<1)
271
//! @param atCenterY Y position of center of final video frame, counted from top of window. May be absolute pixel coordinate (if >1) or relative to screen size (0<Y<1)
272
//! @param finalSizeX X size (width)  of final video frame. May be absolute (if >1) or relative to window size (0<X<1). If -1, scale proportional from @param finalSizeY.
273
//! @param finalSizeY Y size (height) of final video frame. May be absolute (if >1) or relative to window size (0<Y<1). If -1, scale proportional from @param finalSizeX.
274
//! @param popupDuration duration of growing start transition (seconds)
275
//! @param popdownDuration duration of shrinking end transition (seconds)
276
//! @param frozenInTransition true if video should be paused during growing/shrinking transition.
277
void StelVideoMgr::playVideoPopout(const QString& id, float fromX, float fromY, float atCenterX, float atCenterY,
×
278
                     float finalSizeX, float finalSizeY, float popupDuration, bool frozenInTransition)
279
{
280
        if (verbose)
×
281
                qDebug() << "\n\n====Configuring playVideoPopout(): " << id;
×
282
        if (videoObjects.contains(id))
×
283
        {
284
                videoObjects[id]->keepVisible=frozenInTransition;
×
NEW
285
                if (videoObjects[id]->player!=nullptr)
×
286
                {
287
                        // if already playing, stop and play from the start
288
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
289
                        if (videoObjects[id]->player->playbackState() == QMediaPlayer::PlayingState)
×
290
#else
291
                        if (videoObjects[id]->player->state() == QMediaPlayer::PlayingState)
292
#endif
293
                        {
294
                                qDebug() << "playVideoPopout(): stop the playing video";
×
295
                                videoObjects[id]->player->stop();
×
296
                        }
297

298
                        // prepare (1) target frame size, (2) XY start position, and (3) end position:
299
                        // (1) Target frame size.
300
                        // if finalSizeX or finalSizeY <= 1 we scale proportional to mainview!
301
                        // Note that finalSizeX or finalSizeY thus cannot be set to 1.0, i.e. single-pixel rows/columns!
302
                        // This is likely not tragic, else set to 1.0001
303
                        int viewportWidth=StelMainView::getInstance().size().width();
×
304
                        int viewportHeight=StelMainView::getInstance().size().height();
×
305

306
                        if (finalSizeX>0 && finalSizeX<=1)
×
307
                                finalSizeX*=viewportWidth;
×
308
                        if (finalSizeY>0 && finalSizeY<=1)
×
309
                                finalSizeY*=viewportHeight;
×
310

311
                        if (verbose)
×
312
                                qDebug() << "playVideoPopout() finalSize: "<< finalSizeX << "x" << finalSizeY;
×
313

314
                        QSize videoSize=videoObjects[id]->resolution;
×
315
                        if (verbose)
×
316
                                qDebug() << "playVideoPopout(): video resolution detected=" << videoSize;
×
317

318
                        if (!videoSize.isValid() && (finalSizeX==-1 || finalSizeY==-1))
×
319
                        {
320
                                // This should not happen, is a real problem.
321
                                qDebug() << "StelVideoMgr::playVideoPopout()" << id << ": size (resolution) not yet determined, cannot resize with -1 argument. Sorry, command stops here...";
×
322
                                return;
×
323
                        }
324
                        float aspectRatio=static_cast<float>(videoSize.width())/static_cast<float>(videoSize.height());
×
325
                        if (verbose)
×
326
                                qDebug() << "StelVideoMgr::playVideoPopout(): computed aspect ratio:" << aspectRatio;
×
327
                        if (finalSizeX!=-1.0f && finalSizeY!=-1.0f)
×
328
                                videoObjects[id]->videoItem->setAspectRatioMode(Qt::IgnoreAspectRatio);
×
329
                        else
330
                        {
331
                                videoObjects[id]->videoItem->setAspectRatioMode(Qt::KeepAspectRatio);
×
332
                                if (finalSizeX==-1.0f && finalSizeY==-1.0f)
×
333
                                {
334
                                        finalSizeX=videoSize.height();
×
335
                                        finalSizeY=videoSize.width();
×
336
                                }
337
                                else if (finalSizeY==-1.0f)
×
338
                                        finalSizeY=finalSizeX/aspectRatio;
×
339
                                else if (finalSizeX==-1.0f)
×
340
                                        finalSizeX=finalSizeY*aspectRatio;
×
341
                        }
342
                        if (verbose)
×
343
                                qDebug() << "StelVideoMgr::playVideoPopout(): Resetting target frame size to :" << finalSizeX << "x" << finalSizeY;
×
344
                        videoObjects[id]->targetFrameSize= QSizeF(finalSizeX, finalSizeY); // size in Pixels
×
345

346
                        // (2) start position:
347
                        if (fromX>0 && fromX<1)
×
348
                                fromX *= static_cast<float>(viewportWidth);
×
349
                        if (fromY>0 && fromY<1)
×
350
                                fromY *= static_cast<float>(viewportHeight);
×
351
                        videoObjects[id]->popupOrigin= QPointF(fromX, fromY); // Pixel coordinates of popout point.
×
352
                        if (verbose)
×
353
                                qDebug() << "StelVideoMgr::playVideoPopout(): Resetting start position to :" << fromX << "/" << fromY;
×
354

355

356
                        // (3) center of target frame
357
                        if (atCenterX>0 && atCenterX<1)
×
358
                                atCenterX *= static_cast<float>(viewportWidth);
×
359
                        if (atCenterY>0 && atCenterY<1)
×
360
                                atCenterY *= static_cast<float>(viewportHeight);
×
361
                        videoObjects[id]->popupTargetCenter= QPointF(atCenterX, atCenterY); // Pixel coordinates of frame center
×
362
                        if (verbose)
×
363
                                qDebug() << "StelVideoMgr::playVideoPopout(): Resetting target position to :" << atCenterX << "/" << atCenterY;
×
364

365
                        // (4) configure fader
366
                        videoObjects[id]->fader.setDuration(1000.0f*popupDuration);
×
367

368
                        // (5) TRIGGER!
369
                        videoObjects[id]->simplePlay=false;
×
370
                        videoObjects[id]->fader=true;
×
371
                        videoObjects[id]->videoItem->setVisible(true);
×
372
                        videoObjects[id]->lastPos=-1;
×
373
                        videoObjects[id]->player->setPosition(0);
×
374
                        videoObjects[id]->player->play();
×
375

376
                        if (verbose)
×
377
                                qDebug() << "StelVideoMgr::playVideoPopout(): fader triggered.";
×
378
                }
379
        }
380
        else qDebug() << "StelVideoMgr::playVideoPopout(" << id << "): no such video";
×
381
}
382

383

384
void StelVideoMgr::pauseVideo(const QString& id)
×
385
{
386
        if (videoObjects.contains(id))
×
387
        {
NEW
388
                if (videoObjects[id]->player!=nullptr)
×
389
                {
390
                        // Maybe we can only pause while already playing?
391
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
392
                        if (videoObjects[id]->player->playbackState() == QMediaPlayer::StoppedState)
×
393
#else
394
                        if (videoObjects[id]->player->state()==QMediaPlayer::StoppedState)
395
#endif
396
                                videoObjects[id]->player->play();
×
397

398
                        if (verbose)
×
399
                                qDebug() << "StelVideoMgr::pauseVideo() ...";
×
400
                        videoObjects[id]->player->pause();
×
401
                }
402
        }
403
        else qDebug() << "StelVideoMgr::pauseVideo()" << id << ": no such video";
×
404
}
×
405

406
void StelVideoMgr::stopVideo(const QString& id)
×
407
{
408
        if (videoObjects.contains(id))
×
409
        {
NEW
410
                if (videoObjects[id]->player!=nullptr)
×
411
                {
412
                        videoObjects[id]->player->stop();
×
413
                }
414
        }
415
        else qDebug() << "StelVideoMgr::stopVideo()" << id << ": no such video";
×
416
}
×
417

418
void StelVideoMgr::seekVideo(const QString& id, const qint64 ms, bool pause)
×
419
{
420
        if (verbose)
×
421
                qDebug() << "StelVideoMgr::seekVideo: " << id << " to:" << ms <<  (pause ? " (pausing)" : " (playing)");
×
422
        if (videoObjects.contains(id))
×
423
        {
NEW
424
                if (videoObjects[id]->player!=nullptr)
×
425
                {
426
                        if (videoObjects[id]->player->isSeekable())
×
427
                        {
428
                                videoObjects[id]->player->setPosition(ms);
×
429
                                // Seek capability depends on the backend used and likely media codec.
430
                        }
431
                        else
432
                        {
433
                                qDebug() << "[StelVideoMgr] Cannot seek media source" << id;
×
434
                        }
435
                        // visual update only happens if we play. So even with pause set, we must play to freeze the frame!
436
                        videoObjects[id]->player->play();
×
437
                        if (pause)
×
438
                                videoObjects[id]->player->pause();
×
439
                }
440
        }
441
        else qDebug() << "StelVideoMgr::seekVideo()" << id << ": no such video";
×
442
}
×
443

444
void StelVideoMgr::dropVideo(const QString& id)
×
445
{
446
        if (!videoObjects.contains(id))
×
447
                return;
×
NEW
448
        if (videoObjects[id]->player!=nullptr)
×
449
        {
450
                if (verbose)
×
451
                        qDebug() << "About to drop (unload) video " << id << "(" << videoObjects[id]->player->mediaStatus() << ")";
×
452
                videoObjects[id]->player->stop();
×
453
                StelMainView::getInstance().scene()->removeItem(videoObjects[id]->videoItem);
×
454
                delete videoObjects[id]->player;
×
455
                delete videoObjects[id]->videoItem;
×
456
                #if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
457
                delete videoObjects[id]->audioOutput;
×
458
                #endif
459
                delete videoObjects[id];
×
460
                videoObjects.remove(id);
×
461
        }
462
}
463

464
// setVideoXY(100, 200, false): absolute, as before
465
// setVideoXY(100, 200, true): shift 100 right, 200 down
466
// setVideoXY(0.5, 0.25, false): (on fullHD), set to (960/270)
467
// setVideoXY(0.5, 0.25, true): (on fullHD), shift by (960/270)
468
// setVideoXY(600, 0.25, false): (on fullHD), set to (600/270)
469
// setVideoXY(600, 0.25, true): (on fullHD), shift by (600/270)
470
void StelVideoMgr::setVideoXY(const QString& id, const float x, const float y, const bool relative)
×
471
{
472
        if (videoObjects.contains(id))
×
473
        {
NEW
474
                if (videoObjects[id]->videoItem!=nullptr)
×
475
                {
476
                        // if w or h < 1 we scale proportional to mainview!
477
                        int viewportWidth=StelMainView::getInstance().size().width();
×
478
                        int viewportHeight=StelMainView::getInstance().size().height();
×
479
                        float newX=x;
×
480
                        float newY=y;
×
481
                        if (x>-1 && x<1)
×
482
                                newX *= static_cast<float>(viewportWidth);
×
483
                        if (y>-1 && y<1)
×
484
                                newY *= static_cast<float>(viewportHeight);
×
485
                        if (relative)
×
486
                        {
487
                                QPointF pos = videoObjects[id]->videoItem->pos();
×
488
                                videoObjects[id]->videoItem->setPos(pos.x()+newX, pos.y()+newY);
×
489
                        }
490
                        else
491
                                videoObjects[id]->videoItem->setPos(newX, newY);
×
492
                        if (verbose)
×
493
                                qDebug() << "Setting video XY= " << newX << "/" << newY << (relative? "(relative)":"");
×
494
                }
495
        }
496
        else qDebug() << "StelVideoMgr::setVideoXY()" << id << ": no such video";
×
497
}
×
498

499
void StelVideoMgr::setVideoAlpha(const QString& id, const float alpha)
×
500
{
501
        if (videoObjects.contains(id))
×
502
        {
NEW
503
                if (videoObjects[id]->videoItem!=nullptr)
×
504
                {
505
                        videoObjects[id]->videoItem->setOpacity(alpha);
×
506
                }
507
        }
508
        else qDebug() << "StelVideoMgr::setVideoAlpha()" << id << ": no such video";
×
509
}
×
510

511
void StelVideoMgr::resizeVideo(const QString& id, float w, float h)
×
512
{
513
        if (videoObjects.contains(id))
×
514
        {
NEW
515
                if (videoObjects[id]->videoItem!=nullptr)
×
516
                {
517
                        // if w or h <= 1 we scale proportional to mainview!
518
                        // Note that w or h thus cannot be set to 1.0, i.e. single-pixel rows/columns!
519
                        // This is likely not tragic, else set to 1.0001
520
                        int viewportWidth=StelMainView::getInstance().size().width();
×
521
                        int viewportHeight=StelMainView::getInstance().size().height();
×
522

523
                        if (w>0 && w<=1)
×
524
                                w*=static_cast<float>(viewportWidth);
×
525
                        if (h>0 && h<=1)
×
526
                                h*=static_cast<float>(viewportHeight);
×
527

528
                        QSize videoSize=videoObjects[id]->resolution;
×
529
                        if (verbose)
×
530
                                qDebug() << "resizeVideo(): old resolution=" << videoSize;
×
531

532
                        if (!videoSize.isValid() && (w==-1 || h==-1))
×
533
                        {
534
                                if (verbose)
×
535
                                        qDebug() << "StelVideoMgr::resizeVideo()" << id << ": size not yet determined, cannot resize with -1 argument. We do that in next update().";
×
536
                                // mark necessity of deferred resize.
537
                                videoObjects[id]->needResize=true;
×
538
                                videoObjects[id]->targetFrameSize=QSizeF(w, h); // w|h can be -1 or >1, no longer 0<(w|h)<1.
×
539
                                return;
×
540
                        }
541
                        float aspectRatio=static_cast<float>(videoSize.width())/static_cast<float>(videoSize.height());
×
542
                        if (verbose)
×
543
                                qDebug() << "aspect ratio:" << aspectRatio; // 1 for invalid size.
×
544
                        if (w!=-1.0f && h!=-1.0f)
×
545
                                videoObjects[id]->videoItem->setAspectRatioMode(Qt::IgnoreAspectRatio);
×
546
                        else
547
                        {
548
                                videoObjects[id]->videoItem->setAspectRatioMode(Qt::KeepAspectRatio);
×
549
                                if (w==-1.0f && h==-1.0f)
×
550
                                {
551
                                        h=static_cast<float>(videoSize.height());
×
552
                                        w=static_cast<float>(videoSize.width());
×
553
                                }
554
                                else if (h==-1.0f)
×
555
                                        h=w/aspectRatio;
×
556
                                else if (w==-1.0f)
×
557
                                        w=h*aspectRatio;
×
558
                        }
559
                        if (verbose)
×
560
                                qDebug() << "Resizing to:" << w << "x" << h;
×
561
                        videoObjects[id]->targetFrameSize=QSizeF(w, h); // w|h cannot be -1 or >1 here.
×
562
                        videoObjects[id]->videoItem->setSize(QSizeF(w, h));
×
563
                        videoObjects[id]->needResize=false;
×
564
                }
565
        }
566
        else qDebug() << "StelVideoMgr::resizeVideo()" << id << ": no such video";
×
567
}
568

569
void StelVideoMgr::showVideo(const QString& id, const bool show)
×
570
{
571
        if (videoObjects.contains(id))
×
572
        {
NEW
573
                if (videoObjects[id]->videoItem!=nullptr)
×
574
                {
575
                        videoObjects[id]->videoItem->setVisible(show);
×
576
                }
577
        }
578
        else qDebug() << "StelVideoMgr::showVideo()" << id << ": no such video";
×
579
}
×
580

581
qint64 StelVideoMgr::getVideoDuration(const QString& id) const
×
582
{
583
        if (videoObjects.contains(id))
×
584
        {
585
                return videoObjects[id]->duration;
×
586
        }
587
        else qDebug() << "StelVideoMgr::getDuration()" << id << ": no such video";
×
588
        return -1;
×
589
}
590

591
qint64 StelVideoMgr::getVideoPosition(const QString& id) const
×
592
{
593
        if (videoObjects.contains(id))
×
594
        {
595
                return videoObjects[id]->player->position();
×
596
        }
597
        else qDebug() << "StelVideoMgr::getPosition()" << id << ": no such video";
×
598
        return -1;
×
599
}
600

601
//! returns native resolution (in pixels) of loaded video. Returned value may be invalid before video has been fully loaded.
602
QSize StelVideoMgr::getVideoResolution(const QString& id) const
×
603
{
604
        if (videoObjects.contains(id))
×
605
        {
606
                return videoObjects[id]->resolution;
×
607
        }
608
        else qDebug() << "StelVideoMgr::getResolution()" << id << ": no such video";
×
609
        return QSize();
×
610
}
611

612
int StelVideoMgr::getVideoWidth(const QString& id) const
×
613
{
614
        if (videoObjects.contains(id))
×
615
        {
616
                if (videoObjects[id]->resolution.isValid())
×
617
                        return videoObjects[id]->resolution.width();
×
618
                else
619
                        return -1;
×
620
        }
621
        else qDebug() << "StelVideoMgr::getWidth()" << id << ": no such video";
×
622
        return -1;
×
623
}
624

625
int StelVideoMgr::getVideoHeight(const QString& id) const
×
626
{
627
        if (videoObjects.contains(id))
×
628
        {
629
                if (videoObjects[id]->resolution.isValid())
×
630
                        return videoObjects[id]->resolution.height();
×
631
                else
632
                        return -1;
×
633
        }
634
        else qDebug() << "StelVideoMgr::getHeight()" << id << ": no such video";
×
635
        return -1;
×
636
}
637

638

639
void StelVideoMgr::muteVideo(const QString& id, bool mute)
×
640
{
NEW
641
        if (!audioEnabled)
×
NEW
642
                return;
×
643
        if (videoObjects.contains(id))
×
644
        {
NEW
645
                if (videoObjects[id]->player!=nullptr)
×
646
                {
647
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
648
                        videoObjects[id]->player->audioOutput()->setMuted(mute);
×
649
#else
650
                        videoObjects[id]->player->setMuted(mute);
651
#endif
652
                }
653
        }
654
        else qDebug() << "StelVideoMgr::mute()" << id << ": no such video";
×
655
}
656

657
void StelVideoMgr::setVideoVolume(const QString& id, int newVolume)
×
658
{
NEW
659
        if (!audioEnabled)
×
NEW
660
                return;
×
661
        if (videoObjects.contains(id))
×
662
        {
NEW
663
                if (videoObjects[id]->player!=nullptr)
×
664
                {
665
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
666
                        videoObjects[id]->player->audioOutput()->setVolume(qBound(0,newVolume,100)/100.);
×
667
#else
668
                        videoObjects[id]->player->setVolume(newVolume);
669
#endif
670
                }
671
        }
672
        else qDebug() << "StelVideoMgr::setVolume()" << id << ": no such video";
×
673
}
674

675
int StelVideoMgr::getVideoVolume(const QString& id) const
×
676
{
NEW
677
        if (!audioEnabled)
×
NEW
678
                return 0;
×
679

680
        int volume=-1;
×
681
        if (videoObjects.contains(id))
×
682
        {
NEW
683
                if (videoObjects[id]->player!=nullptr)
×
684
                {
685
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
686
                        volume=int(videoObjects[id]->player->audioOutput()->volume()*100.);
×
687
#else
688
                        volume=videoObjects[id]->player->volume();
689
#endif
690
                }
691
        }
692
        else qDebug() << "StelVideoMgr::getVolume()" << id << ": no such video";
×
693
        return volume;
×
694
}
695

696
bool StelVideoMgr::isVideoPlaying(const QString& id) const
×
697
{
698
        bool playing=false;
×
699
        if (videoObjects.contains(id))
×
700
        {
NEW
701
                if (videoObjects[id]->player!=nullptr)
×
702
                {
703
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
704
                        playing= (videoObjects[id]->player->playbackState() == QMediaPlayer::PlayingState );
×
705
#else
706
                        playing= (videoObjects[id]->player->state() == QMediaPlayer::PlayingState );
707
#endif
708
                }
709
        }
710
        else qDebug() << "StelVideoMgr::isPlaying()" << id << ": no such video";
×
711
        return playing;
×
712
}
713

714

715
/* *************************************************
716
 * Signal handlers for all signals of QMediaPlayer. Usually for now this only writes a message to logfile.
717
 */
718
void StelVideoMgr::handleAudioAvailableChanged(bool available)
×
719
{
720
        if (verbose)
×
721
                qDebug() << "StelVideoMgr: " << this->sender()->property("Stel_id").toString() << ": Audio is now available:" << available;
×
722
}
×
723

724
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
725
void StelVideoMgr::handleBufferProgressChanged(float filled)
×
726
{
727
        if (verbose)
×
728
                qDebug() << "StelVideoMgr: " << QObject::sender()->property("Stel_id").toString() << ": Buffer filled (fraction):" << filled;
×
729
}
×
730
void StelVideoMgr::handleErrorMsg(QMediaPlayer::Error error, const QString &errorString)
×
731
{
732
        qDebug() << "StelVideoMgr: " << QObject::sender()->property("Stel_id").toString() << ":  error:" << error << ":" << errorString;
×
733
}
×
734
#else
735
// It seems this is never called in practice.
736
void StelVideoMgr::handleBufferStatusChanged(int percentFilled)
737
{
738
        if (verbose)
739
                qDebug() << "StelVideoMgr: " << QObject::sender()->property("Stel_id").toString() << ": Buffer filled (%):" << percentFilled;
740
}
741
void StelVideoMgr::handleError(QMediaPlayer::Error error)
742
{
743
        qDebug() << "StelVideoMgr: " << QObject::sender()->property("Stel_id").toString() << ":  error:" << error;
744
}
745
#endif
746

747
void StelVideoMgr::handleDurationChanged(qint64 duration)
×
748
{
749
        const QString id=QObject::sender()->property("Stel_id").toString();
×
750
        if (verbose)
×
751
                qDebug() << "StelVideoMgr: " << id << ": Duration changed to:" << duration;
×
752
        if (videoObjects.contains(id))
×
753
        {
754
                videoObjects[id]->duration=duration;
×
755
        }
756
}
×
757

758
// This may have been useful to trigger the pause-at-end if it was fast enough.
759
// It seems that this is too slow! At EndOfMedia the player window disappears, then reappears. This is ugly!
760
// Currently we deal with polling status changes within update().
761
void StelVideoMgr::handleMediaStatusChanged(QMediaPlayer::MediaStatus status) // debug-log messages
×
762
{
763
        QString id=QObject::sender()->property("Stel_id").toString();
×
764
        if (verbose)
×
765
                qDebug() << "StelVideoMgr: " << id << ":  MediaStatus changed to:" << status;
×
766
}
×
767

768
void StelVideoMgr::handleMutedChanged(bool muted)
×
769
{
770
        if (verbose)
×
771
                qDebug() << "StelVideoMgr: " << QObject::sender()->property("Stel_id").toString() << ":  mute changed:" << muted;
×
772
}
×
773

774

775

776
/* // USELESS. This is called not often enough (could be configured), but update() is better suited to check for video-at-end.
777
void StelVideoMgr::handlePositionChanged(qint64 position)
778
{
779
    QString senderId=QObject::sender()->property("Stel_id").toString();
780
    qDebug() << "StelVideoMgr: " << senderId << ":  position changed to (ms):" << position;
781
    // We could deal with the keep-visible here, however this is not called often enough by default, and we have update anyways
782
    if ((position==videoObjects[senderId]->duration) && (videoObjects[senderId]->keepVisible))
783
    {
784
        videoObjects[senderId]->player->setPosition(videoObjects[senderId]->duration - 1);
785
        videoObjects[senderId]->player->pause();
786
        qDebug() << " ---> paused at end as requested" ;
787
    }
788
}
789
*/
790

791
// USELESS?
792
void StelVideoMgr::handleSeekableChanged(bool seekable)
×
793
{
794
        if (verbose)
×
795
                qDebug() << "StelVideoMgr: handleSeekableChanged()" << QObject::sender()->property("Stel_id").toString() << ":  seekable changed to:" << seekable;
×
796
}
×
797
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
798
void StelVideoMgr::handleStateChanged(QMediaPlayer::PlaybackState state)
×
799
#else
800
void StelVideoMgr::handleStateChanged(QMediaPlayer::State state)
801
#endif
802
{
803
        QString senderId=QObject::sender()->property("Stel_id").toString();
×
804
        if (verbose)
×
805
                qDebug() << "StelVideoMgr: " << senderId << ":  state changed to:" << state
×
806
                         << "(Media Status: " << videoObjects[senderId]->player->mediaStatus() << ")";
×
807
}
×
808

809
void StelVideoMgr::handleVideoAvailableChanged(bool videoAvailable)
×
810
{
811
        QString senderId=QObject::sender()->property("Stel_id").toString();
×
812
        if (verbose)
×
813
                qDebug() << "StelVideoMgr: " << senderId << ":  Video available:" << videoAvailable;
×
814
        // Sometimes it appears the video has not fully loaded when popup stars, and the movie is not shown.
815
        // Maybe force showing here? --> NO, breaks our own logic...
816
        //videoObjects[senderId]->videoItem->setVisible(videoAvailable);
817
}
×
818

819
void StelVideoMgr::handleVolumeChanged(int volume)
×
820
{
821
        if (verbose)
×
822
                qDebug() << "StelVideoMgr: " << QObject::sender()->property("Stel_id").toString() << ":  volume changed to:" << volume;
×
823
}
×
824

825
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
826
void StelVideoMgr::handleMetaDataChanged()
×
827
{
828
        QString id=QObject::sender()->property("Stel_id").toString();
×
829
        if (verbose)
×
830
                qDebug() << "StelVideoMgr: " << id << ":  Metadata changed (global notification).";
×
831

832
        if (videoObjects.contains(id))
×
833
        {
834
                const QMediaMetaData metaData=videoObjects[id]->player->metaData();
×
835

836
                if (verbose)
×
837
                        qDebug() << "StelVideoMgr: " << id << ":  Following metadata are available:";
×
838
                for (const auto& mdKey : metaData.keys())
×
839
                {
840
                        QString key = metaData.stringValue(mdKey);
×
841
                        if (verbose)
×
842
                                qDebug() << "\t" << mdKey << "==>" << key;
×
843

844
                        if ((key=="Resolution"))
×
845
                        {
846
                                if (verbose)
×
847
                                        qDebug() << "StelVideoMgr: Resolution becomes available: " << metaData.stringValue(mdKey);
×
848
                                videoObjects[id]->resolution=metaData.value(mdKey).toSize();
×
849
                        }
850
                }
×
851
        }
×
852
        else
853
                qDebug() << "StelVideoMgr::handleMetaDataChanged()" << id << ": no such video - this is absurd.";
×
854
}
×
855
void StelVideoMgr::handleSourceChanged(const QUrl &media)
×
856
{
857
        if (verbose)
×
858
                qDebug() << "StelVideoMgr: " << QObject::sender()->property("Stel_id").toString() << ": source changed to:" << media;
×
859
}
×
860
#else
861
void StelVideoMgr::handleAvailabilityChanged(bool available)
862
{
863
        if (verbose)
864
                qDebug() << "StelVideoMgr::handleAvailabilityChanged(bool) " << QObject::sender()->property("Stel_id").toString() << ":  available:" << available;
865
}
866

867
void StelVideoMgr::handleAvailabilityChanged(QMultimedia::AvailabilityStatus availability)
868
{
869
        if (verbose)
870
                qDebug() << "StelVideoMgr::availabilityChanged(QMultimedia::AvailabilityStatus) " << QObject::sender()->property("Stel_id").toString() << ":  availability:" << availability;
871
}
872

873

874
// The signal sequence (at least on Windows7/MinGW/Qt5.4) seems to be:
875
// metadatachanged() as soon as video has been loaded. But Result: no metadata.
876
// After media has started playing and frame is already growing,
877
// audioAvailable() (but no audio in this movie...)
878
// videoAvailable() (true)
879
// durationChanged() --> only now duration becomes known!
880
// status changed: QMediaPlayer::BufferedMedia
881
// metadataAvailablechanged(true): Duration, PixelAspectRatio(unknown!), Resolution(unknown!), Videobitrate, VideoFramerate
882
// metadataChanged() now true, and finally here also PixelAspectRatio and Resolution are known.
883
// Then periodically, positionChanged(). We can skip that because in update() we can check position() if required.
884
// Sequence is the same on Win/MSVC and Qt5.3.2, so metadataChanged(.,.) is NOT called on Windows.
885
// This is also already observed on MacOSX and listed as QTBUG-42034.
886
// This signal is sent several times during replay because min/max rates often change, and we must go through the metadata list each time. We avoid setting resolution more than once.
887
void StelVideoMgr::handleMetaDataChanged()
888
{
889
        QString id=QObject::sender()->property("Stel_id").toString();
890
        if (verbose)
891
                qDebug() << "StelVideoMgr: " << id << ":  Metadata changed (global notification).";
892

893
        if (videoObjects.contains(id) && videoObjects[id]->player->isMetaDataAvailable())
894
        {
895
                if (verbose)
896
                        qDebug() << "StelVideoMgr: " << id << ":  Following metadata are available:";
897
                const QStringList metadataList=videoObjects[id]->player->availableMetaData();
898
                for (const auto& md : metadataList)
899
                {
900
                        QString key = md.toLocal8Bit().constData();
901
                        if (verbose)
902
                                qDebug() << "\t" << key << "==>" << videoObjects[id]->player->metaData(key);
903

904
                        if ((key=="Resolution") && !(videoObjects[id]->resolution.isValid()))
905
                        {
906
                                if (verbose)
907
                                        qDebug() << "StelVideoMgr: Resolution becomes available: " << videoObjects[id]->player->metaData(key).toSize();
908
                                videoObjects[id]->resolution=videoObjects[id]->player->metaData(key).toSize();
909
                        }
910
                }
911
        }
912
        else if (videoObjects.contains(id) && !(videoObjects[id]->player->isMetaDataAvailable()) &&verbose)
913
                qDebug() << "StelVideoMgr::handleMetaDataChanged()" << id << ": no metadata now.";
914
        else
915
                qDebug() << "StelVideoMgr::handleMetaDataChanged()" << id << ": no such video - this is absurd.";
916
}
917
#endif
918

919
// update() has only to deal with the faders in all videos, and (re)set positions and sizes of video windows.
920
void StelVideoMgr::update(double deltaTime)
×
921
{
922
        for (auto voIter = videoObjects.constBegin(); voIter != videoObjects.constEnd(); ++voIter)
×
923
        {
924
                QMediaPlayer::MediaStatus mediaStatus = (*voIter)->player->mediaStatus();
×
925
                QString id=voIter.key();
×
926
                // Maybe we have verbose as int with levels of verbosity, and output the next line with verbose>=2?
927
                if (verbose)
×
928
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
929
                        qDebug() << "StelVideoMgr::update() for" << id << ": PlayerState:" << (*voIter)->player->playbackState() << "MediaStatus: " << mediaStatus;
×
930
#else
931
                        qDebug() << "StelVideoMgr::update() for" << id << ": PlayerState:" << (*voIter)->player->state() << "MediaStatus: " << mediaStatus;
932
#endif
933

934
                // fader must be updated here, else the video may not be visible when not yet fully loaded?
935
                (*voIter)->fader.update(static_cast<int>(deltaTime*1000));
×
936

937
                // It seems we need a more thorough analysis of MediaStatus!
938
                // In all not-ready status we immediately leave further handling, usually in the hope that loading is successful really soon.
939
                switch (mediaStatus)
×
940
                {
941
#if (QT_VERSION<QT_VERSION_CHECK(6,0,0))
942
                        case QMediaPlayer::UnknownMediaStatus:
943
#endif
944
                        case QMediaPlayer::NoMedia:
×
945
                        case QMediaPlayer::InvalidMedia:
946
                        case QMediaPlayer::LoadingMedia:
947
                        case QMediaPlayer::StalledMedia:
948
                                if (verbose)
×
949
                                        qDebug() << "StelVideoMgr::update(): " << id  << mediaStatus << "\t==> no further update action";
×
950
                                continue;
×
951
                        case QMediaPlayer::LoadedMedia:
×
952
                        case QMediaPlayer::BufferingMedia:
953
                        case QMediaPlayer::BufferedMedia:
954
                        case QMediaPlayer::EndOfMedia:
955
                        default:
956
                                break;
×
957
                }
958

959
                // First fix targetFrameSize if needed and possible.
960
                if ((*voIter)->needResize && ((*voIter)->resolution.isValid()))
×
961
                {
962
                        // we have buffered our final size (which may be relative to screen size) in targetFrameSize. So, simply
963
                        resizeVideo(voIter.key(), (*voIter)->targetFrameSize.width(), (*voIter)->targetFrameSize.height());
×
964
                }
965

966
                // if keepVisible, pause video if already close to end.
967
                if ((*voIter)->simplePlay)
×
968
                {
969
                        if ( ((*voIter)->keepVisible) &&  ((*voIter)->duration > 0) &&  ((*voIter)->player->position() >= ((*voIter)->duration - 250))   )
×
970
                        {
971
                                if (verbose)
×
972
                                        qDebug() << "update(): pausing" << id << "at end";
×
973
                                (*voIter)->player->pause();
×
974
                        }
975

976
                        continue;
×
977
                }
978

979
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
980
                if ((*voIter)->player->playbackState()==QMediaPlayer::StoppedState)
×
981
#else
982
                if ((*voIter)->player->state()==QMediaPlayer::StoppedState)
983
#endif
984
                        continue;
×
985

986
                // the rest of the loop is only needed if we are in popup playing mode.
987

988
                QSizeF currentFrameSize= (*voIter)->fader.getInterstate() * (*voIter)->targetFrameSize;
×
989
                QPointF frameCenter=  (*voIter)->popupOrigin +  ( (*voIter)->popupTargetCenter - (*voIter)->popupOrigin ) *  (*voIter)->fader.getInterstate();
×
990
                QPointF frameXY=frameCenter - 0.5*QPointF(currentFrameSize.width(), currentFrameSize.height());
×
991
                (*voIter)->videoItem->setPos(frameXY);
×
992
                (*voIter)->videoItem->setSize(currentFrameSize);
×
993
                if (verbose)
×
994
                        qDebug() << "StelVideoMgr::update(): Video" << id << "at" << (*voIter)->player->position()
×
995
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
996
                                 << ", player state=" << (*voIter)->player->playbackState() << ", media status=" << (*voIter)->player->mediaStatus();
×
997
#else
998
                                 << ", player state=" << (*voIter)->player->state() << ", media status=" << (*voIter)->player->mediaStatus();
999
#endif
1000

1001
                int newPos=(*voIter)->player->position();
×
1002
//                if ((newPos==(*voIter)->lastPos) && ((*voIter)->player->state()==QMediaPlayer::PlayingState))
1003
//                {
1004
//                        // I (GZ) have no idea how this can happen, but it does, every couple of runs.
1005
//                        // I see this happen only in the grow-while-play phase, but I see no logical error.
1006
//                        // It seemed to indicate not-fully-loaded, but this would have been caught in the intro test.
1007
//                        // But this even can happen if MediaStatus==BufferedMedia, i.e. fully loaded. Really a shame!
1008
//                        // TODO: check with every version of Qt whether this can still happen.
1009
//                        // SILLY! Of course if Stellarium framerate > video framerate...
1010
//                        if (verbose)
1011
//                        {
1012
//                                qDebug() << "StelVideoMgr::update(): player state" << (*voIter)->player->state() << "with MediaStatus" << mediaStatus;
1013
//                                qDebug() << "This should not be: video should play but position" << newPos << "does not increase? Bumping video.";
1014
//                        }
1015
//                        //(*voIter)->player->stop(); // GZ Dec2: Do we really need to stop?
1016
//                        (*voIter)->player->setPosition(newPos+1); // GZ Dec2 flipped 2 lines.
1017
//                        (*voIter)->player->play();
1018
//                        qDebug() << "We had an issue with a stuck mediaplayer, should play again!";
1019
//                }
1020
                (*voIter)->lastPos=newPos;
×
1021

1022
                if (verbose)
×
1023
                        qDebug() << "StelVideoMgr::update(): fader at " << (*voIter)->fader.getInterstate()  << "; update frame size " << currentFrameSize << "to XY" << frameXY;
×
1024

1025
                // if we want still videos during transition, we must grow/shrink paused, and run only when reached full size.
1026
                // We must detect a frame close to end, pause there, and trigger the fader back to 0.
1027
                if ((*voIter)->keepVisible)
×
1028
                {
1029
                        if ((*voIter)->fader.getInterstate()==0.0f)
×
1030
                        { // interstate is >0 on startup, so 0 is reached only at end of loop. we can send stop here.
1031
                                (*voIter)->player->stop(); // this immediately hides the video window.
×
1032
                                (*voIter)->simplePlay=true; // to reset
×
1033
                                (*voIter)->keepVisible=false;
×
1034
                        }
1035
                        else if ((*voIter)->fader.getInterstate()<1.0f)
×
1036
                        {
1037
                                if (verbose)
×
1038
                                        qDebug() << "StelVideoMgr::update(): not fully grown: pausing video at start or end!";
×
1039
                                (*voIter)->player->pause();
×
1040
                        }
1041
                        else if (((*voIter)->duration > 0) && ((*voIter)->player->position() >= ((*voIter)->duration - 250))) // allow stop 250ms before end. 100ms was too short!
×
1042
                        {
1043
                                if (verbose)
×
1044
                                        qDebug() << "StelVideoMgr::update(): position " << (*voIter)->player->position() << "close to end of duration " << (*voIter)->duration << "--> pause and shutdown with fader ";
×
1045
                                (*voIter)->player->pause();
×
1046
                                // TBD: If we set some very last frame position here, it takes a very long while to seek (may disturb/flicker!)
1047
                                // (*voIter)->player->setPosition((*voIter)->duration-10);
1048
                                (*voIter)->fader=false; // trigger shutdown (sending again does not disturb)
×
1049
                        }
1050
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
1051
                        else if (((*voIter)->player->playbackState() != QMediaPlayer::PlayingState))
×
1052
#else
1053
                        else if (((*voIter)->player->state() != QMediaPlayer::PlayingState))
1054
#endif
1055
                        {
1056
                                if (verbose)
×
1057
                                        qDebug() << "StelVideoMgr::update(): fully grown: play!";
×
1058
                                (*voIter)->player->play();
×
1059
                        }
1060
                }
1061
                // If the videos come with their own fade-in/-out, this can be played during transitions. (keepVisible configured to false)
1062
                // In this case we must trigger shrinking *before* end of video!
1063
                else
1064
                {
1065
                        if ((*voIter)->fader.getInterstate()>0.0f)
×
1066
                        {
1067
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
1068
                                if (((*voIter)->player->playbackState() != QMediaPlayer::PlayingState))
×
1069
#else
1070
                                if (((*voIter)->player->state() != QMediaPlayer::PlayingState))
1071
#endif
1072
                                        (*voIter)->player->play();
×
1073
                                if (( ((*voIter)->duration > 0) &&  ((*voIter)->player->position() >= ((*voIter)->duration - (*voIter)->fader.getDuration() - 200))))
×
1074
                                {
1075
                                        if (verbose)
×
1076
                                                qDebug() << "StelVideoMgr::update(): position " << (*voIter)->player->position() << "close to end of duration " << (*voIter)->duration <<
×
1077
                                                            "minus fader duration " << (*voIter)->fader.getDuration() << "--> shutdown with fader ";
×
1078
                                        (*voIter)->fader=false; // trigger shutdown (sending again does not disturb)
×
1079
                                }
1080
                        }
1081
                        else // interstate==0: end of everything.
1082
                        {
1083
                                if (verbose)
×
1084
                                        qDebug() << "StelVideoMgr::update(): Stopping at Interstate " << (*voIter)->fader.getInterstate();
×
1085
                                (*voIter)->player->stop();  // immediately hides video window.
×
1086
                                (*voIter)->simplePlay=true; // reset
×
1087
                        }
1088
                }
1089
        }
×
1090
}
×
1091

1092

1093

1094
#else 
1095
void StelVideoMgr::loadVideo(const QString& filename, const QString& id, float x, float y, bool show, float alpha)
1096
{
1097
        qWarning() << "[StelVideoMgr] This build of Stellarium does not support video - cannot load video" << QDir::toNativeSeparators(filename) << id << x << y << show << alpha;
1098
}
1099
StelVideoMgr::~StelVideoMgr() {;}
1100
void StelVideoMgr::update(double){;}
1101
void StelVideoMgr::playVideo(const QString&, const bool) {;}
1102
void StelVideoMgr::playVideoPopout(const QString&, float, float, float, float, float, float, float, bool){;}
1103
void StelVideoMgr::pauseVideo(const QString&) {;}
1104
void StelVideoMgr::stopVideo(const QString&) {;}
1105
void StelVideoMgr::dropVideo(const QString&) {;}
1106
void StelVideoMgr::seekVideo(const QString&, qint64, bool) {;}
1107
void StelVideoMgr::setVideoXY(const QString&, float, float, const bool) {;}
1108
void StelVideoMgr::setVideoAlpha(const QString&, float) {;}
1109
void StelVideoMgr::resizeVideo(const QString&, float, float) {;}
1110
void StelVideoMgr::showVideo(const QString&, bool) {;}
1111
// New functions for 0.15
1112
qint64 StelVideoMgr::getVideoDuration(const QString&)const{return -1;}
1113
qint64 StelVideoMgr::getVideoPosition(const QString&)const{return -1;}
1114
QSize StelVideoMgr::getVideoResolution(const QString&)const{return QSize(0,0);}
1115
int StelVideoMgr::getVideoWidth(const QString&)const{return -1;}
1116
int StelVideoMgr::getVideoHeight(const QString&)const{return -1;}
1117
void StelVideoMgr::muteVideo(const QString&, bool){;}
1118
void StelVideoMgr::setVideoVolume(const QString&, int){;}
1119
int StelVideoMgr::getVideoVolume(const QString&)const{return -1;}
1120
bool StelVideoMgr::isVideoPlaying(const QString& id) const
1121
{
1122
        Q_UNUSED(id)
1123
        return false;
1124
}
1125

1126
#endif // ENABLE_MEDIA
1127

1128

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc