26
class StelVideoMgr : public QObject
31
#include <QMediaContent>
32
#include <QMediaPlayer>
33
#include "StelFader.hpp"
35
#include "StelModule.hpp"
37
class QGraphicsVideoItem;
39
//! @class StelVideoMgr
40
//! A scriptable way to show videos embedded in the screen.
41
//! After experimental support with Qt4/Phonon library, this feature is back.
42
//! Videos can be scaled, paused, placed and relocated (shifted) on screen.
43
//! Setting opacity seems not to do much unless setting it to zero, the video is then simply invisible.
44
//! Therefore smooth fading in/out or setting a semitransparent overlay does not work, but there is now an intro/end animation available:
45
//! zooming out from a pixel position to a player frame position, and returning to that spot close to end of video playback.
47
//! However, support for multimedia content depends on the operating system, installed codecs, and completeness of the QtMultimedia system support,
48
//! so some features or video formats may not work for you (test video and re-code it if necessary).
50
//! <h2>Linux notes</h2>
51
//! The listed functions have been tested and work on Ubuntu 15.04 with Qt5.4 with NVidia 9800M and Intel Core-i3/HD5500.
52
//! You need to install GStreamer plugins. Most critical seems to be gstreamer0.10-ffmpeg from
53
//! https://launchpad.net/~mc3man/+archive/ubuntu/gstffmpeg-keep,
56
//! <li>MP4 (h264)</li>
57
//! <li>Apple MOV(Sorenson)</li>
59
//! <li>Some type of AVI failed</li>
62
//! <h2>Windows notes</h2>
63
//! According to https://wiki.qt.io/Qt_Multimedia, MinGW is limited to the decaying DirectShow platform plugin.
64
//! The WMF platform plugin requires Visual Studio, so building with MSVC should provide better result.
65
//! Some signals are not triggered under Windows, so we cannot use them, globally.
66
//! There is partial success with MP4 files on MinGW, but also these are rendered badly. Often just shows an error on Windows/MinGW:
67
//! DirectShowPlayerService::doRender: Unresolved error code 80040154
68
//! (number may differ, also seen: 80040228. Where is a list?)
69
//! The formats tested on Windows are: <ul>
70
//! <li>MP4 (h264; OK) </li>
71
//! <li>WMV (OK, but jumping to different locations via seekVideo() seems not to work properly) </li>
72
//! <li>MOV (mp4v codec, very jerky, basically unusable) </li>
73
//! <li>AVI (DIVX MP4 codec, same bad issues as MOV) </li>
74
//! <li>OGV (invalid media) </li>
75
//! <li>WEBM (invalid media) </li>
78
//! <h2>Mac OS X Notes</h2>
79
//! NOT TESTED ON A MAC! There is a critical difference (causing a crash!) between Win and Linux to either hide or not hide the player just after loading.
80
//! Please somebody find out Mac behaviour.
82
//! QtMultimedia is a bit tricky to use: There seems to be no way to load a media file to analyze resolution or duration before starting its replay.
83
//! This means, configuring player frames either require absolute frame coordinates, or triggering necessary configuration steps only after replay has started.
84
//! We opted for the latter solution because it allows scaled but undistorted video frames which may also take current screen resolution into account.
86
//! Under unclear circumstances we also have a pair of messages:
87
//! @code Failed to start video surface due to main thread blocked.
88
//! @code Failed to start video surface
89
//! and non-appearing video frame, this seems to be https://bugreports.qt.io/browse/QTBUG-39567.
90
//! This occurred on an Intel NUC5i3 with SSD, so loading the file should not be much of an issue.
92
//! To help in debugging scripts, this module can be quite verbose in the logfile if Stellarium is called with the command-line argument "--verbose".
94
class StelVideoMgr : public StelModule
35
void loadVideo(const QString& filename, const QString& id, float x, float y, bool show, float alpha);
36
void playVideo(const QString& id);
104
// Methods from StelModule: only update() needed.
105
virtual void init(){;} // Or do something?
107
//! Update the module with respect to the time. This allows the special effects in @name playVideoPopout(), and may evaluate things like video resolution when they become available.
108
//! @param deltaTime the time increment in second since last call.
109
virtual void update(double deltaTime);
111
//! load a video from @param filename, assign an @param id for it for later reference.
112
//! If @param id is already in use, replace it.
113
//! Prepare replay at upper-left corner @param x/@param y in native resolution,
114
//! decide whether to @param show (play) the video already, and set opacity @name alpha.
115
//! If you want non-native resolution, load with @param show set to false, and use @name resizeVideo() and @name showVideo().
116
//! @bug Note that with @param alpha =0 the video is invisible as expected, other values make it fully opaque. There is no semi-transparency possible.
117
void loadVideo(const QString& filename, const QString& id, const float x, const float y, const bool show, const float alpha);
118
//! play video from current position. If @param keepLastFrame is true, video pauses at last frame.
119
void playVideo(const QString& id, const bool keepVisibleAtEnd=false);
121
//! Play a video which has previously been loaded with loadVideo with a complex effect.
122
//! The video appears to pop out from @param fromX/ @param fromY,
123
//! grows within @param popupDuration to size @param finalSizeX/@param finalSizeY, and
124
//! shrinks back towards @param fromX/@param fromY at the end during @param popdownDuration.
125
//! @param id the identifier used when loadVideo was called
126
//! @param fromX X position of starting point, counted from left of window. May be absolute (if >1) or relative (0<X<1)
127
//! @param fromY Y position of starting point, counted from top of window. May be absolute (if >1) or relative (0<Y<1)
128
//! @param atCenterX X position of center of final video frame, counted from left of window. May be absolute (if >1) or relative (0<X<1)
129
//! @param atCenterY Y position of center of final video frame, counted from top of window. May be absolute (if >1) or relative (0<Y<1)
130
//! @param finalSizeX X size of final video frame. May be absolute (if >1) or relative to window size (0<X<1). If -1, scale proportional from @param finalSizeY.
131
//! @param finalSizeY Y size of final video frame. May be absolute (if >1) or relative to window size (0<Y<1). If -1, scale proportional from @param finalSizeX.
132
//! @param popupDuration duration of growing (start) / shrinking (end) transitions (seconds)
133
//! @param frozenInTransition true if video should be paused during growing/shrinking transition.
134
void playVideoPopout(const QString& id, float fromX, float fromY, float atCenterX, float atCenterY, float finalSizeX, float finalSizeY, float popupDuration, bool frozenInTransition);
136
//! Pause video, keep it visible on-screen.
137
//! Sending @name playVideo() continues replay, sending seekVideo() can move to a different position.
37
138
void pauseVideo(const QString& id);
140
//! Stop playing, resets video and hides video output window
38
141
void stopVideo(const QString& id);
143
//! Unload video from memory.
39
144
void dropVideo(const QString& id);
40
void seekVideo(const QString& id, qint64 ms);
41
void setVideoXY(const QString& id, float x, float y);
42
void setVideoAlpha(const QString& id, float alpha);
43
void resizeVideo(const QString& id, float w, float h);
44
void showVideo(const QString& id, bool show);
146
//! Seek a position in video @param id. Pause the video playing if @param pause=true.
147
//! @note This may not work if video has not been fully loaded. Better wait a second before proceeding after loadVideo(), and call seekVideo(., ., false); pauseVideo(.);
148
void seekVideo(const QString& id, const qint64 ms, bool pause=false);
150
//! move upper left corner of video @name id to @name x, @name y.
151
//! If x or y are <1, this is relative to screen size!
152
void setVideoXY(const QString& id, const float x, const float y, const bool relative=false);
155
//! @param alpha opacity for the video (0=transparent, ... 1=fully opaque).
156
//! @note if alpha is 0, also @name showVideo(id, true) cannot show the video.
157
//! @bug (as of Qt5.5) Note that with @param alpha =0 the video is invisible as expected, other values make it fully opaque. There is no semi-transparency possible.
158
void setVideoAlpha(const QString& id, const float alpha);
160
//! set video size to width @param w and height @param h.
161
//! Use @param w=-1 or @param h=-1 for autoscale from the other dimension,
162
//! or use @param w=h=-1 for native size of video.
163
//! if @param w or @param h are <=1, the size is relative to screen dimensions.
164
//! This should be the preferred use, because it allows the development of device-independent scripts.
165
//! When native resolution is unknown at the time you call this, it will be evaluated at the next update() after resolution becomes known.
166
//! Autoscaling uses viewport dimensions at the time of calling, so resizing the Stellarium window will not resize the video frame during replay.
167
void resizeVideo(const QString& id, float w = -1.0f, float h = -1.0f);
169
//! show or hide video player
170
//! @param id name given during loadVideo()
171
//! @param show @value true to show, @value false to hide
172
void showVideo(const QString& id, const bool show);
174
//! returns duration (in milliseconds) of loaded video. This may return valid result only after @name playVideo() or @name pauseVideo() have been called.
175
//! Returns -1 if video has not been analyzed yet. (loaded, but not started).
176
qint64 getVideoDuration(const QString& id);
178
//! returns current position (in milliseconds) of loaded video. This may return valid result only after @name playVideo() or @name pauseVideo() have been called.
179
//! Returns -1 if video has not been analyzed yet. (loaded, but not started).
180
qint64 getVideoPosition(const QString& id);
182
//! returns resolution (in pixels) of loaded video. Returned value may be invalid before video has been fully loaded.
183
QSize getVideoResolution(const QString& id);
184
//! returns native width (in pixels) of loaded video, or -1 in case of trouble.
185
int getVideoWidth(const QString& id);
186
//! returns native height (in pixels) of loaded video, or -1 in case of trouble.
187
int getVideoHeight(const QString& id);
189
//! set mute state of video player
190
//! @param mute true to silence the video, false to hear audio.
191
void muteVideo(const QString& id, bool muteVideo=true);
192
//! set volume for video. Valid values are 0..100, values outside this range will be clamped.
193
void setVideoVolume(const QString& id, int newVolume);
194
//! return currently set volume (0..100) of media player, or -1 in case of some error.
195
int getVideoVolume(const QString& id);
197
//! returns whether video is currently playing.
198
//! @param id name assigned during loadVideo().
199
//! @note If video is not found, also returns @value false.
200
bool isVideoPlaying(const QString& id);
204
// Slots to handle QMediaPlayer signals. Never call them yourself!
205
// Some of them are useful to understand media handling and to get to crucial information like native resolution and duration during loading of media.
206
// Most only give simple debug output...
207
void handleAudioAvailableChanged(bool available);
208
void handleBufferStatusChanged(int percentFilled);
209
void handleDurationChanged(qint64 duration);
210
void handleError(QMediaPlayer::Error error);
211
void handleMediaStatusChanged(QMediaPlayer::MediaStatus status);
212
void handleMutedChanged(bool muted);
213
//void handlePositionChanged(qint64 position); // periodically notify where in the video we are. Could be used to update scale bars, not needed.
214
void handleSeekableChanged(bool seekable);
215
void handleStateChanged(QMediaPlayer::State state);
216
void handleVideoAvailableChanged(bool videoAvailable);
217
void handleVolumeChanged(int volume);
219
// Slots to handle QMediaPlayer change signals inherited from QMediaObject:
220
void handleAvailabilityChanged(bool available);
221
void handleAvailabilityChanged(QMultimedia::AvailabilityStatus availability);
222
//! @note This one works, while handleMetaDataChanged(key, value) is not called on Windows (QTBUG-42034)
223
void handleMetaDataChanged();
224
// This signal is not triggered on Windows, we must work around using handleMetaDataChanged()
225
//void handleMetaDataChanged(const QString & key, const QVariant & value);
231
// Traces of old Qt4/Phonon:
50
234
Phonon::VideoPlayer *player;