Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmediaplayer.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <private/qmultimediautils_p.h>
7#include <private/qplatformmediaintegration_p.h>
8#include <private/qaudiobufferoutput_p.h>
9#include <qvideosink.h>
10#include <qaudiooutput.h>
11
12#include <QtCore/qcoreevent.h>
13#include <QtCore/qmetaobject.h>
14#include <QtCore/qtimer.h>
15#include <QtCore/qdebug.h>
16#include <QtCore/qdir.h>
17#include <QtCore/qpointer.h>
18#include <QtCore/qfileinfo.h>
19#include <QtCore/qtemporaryfile.h>
20#include <QtCore/qcoreapplication.h>
21
22#if defined(Q_OS_ANDROID)
23# include <QtCore/qjniobject.h>
24# include <QtCore/qrandom.h>
25#endif
26
28
29/*!
30 \class QMediaPlayer
31 \brief The QMediaPlayer class allows the playing of a media files.
32 \inmodule QtMultimedia
33 \ingroup multimedia
34 \ingroup multimedia_playback
35 \ingroup multimedia_video
36
37 The QMediaPlayer class is a high level media playback class. It can be used
38 to playback audio of video media files. The content
39 to playback is specified as a QUrl object.
40
41 \snippet multimedia-snippets/media.cpp Player
42
43 QVideoWidget can be used with QMediaPlayer for video rendering.
44
45 \sa QVideoWidget
46*/
47
48/*!
49 \qmltype MediaPlayer
50 \nativetype QMediaPlayer
51 \brief Adds media playback to a scene.
52
53 \inqmlmodule QtMultimedia
54 \ingroup multimedia_qml
55 \ingroup multimedia_audio_qml
56 \ingroup multimedia_video_qml
57
58 \qml
59 Text {
60 text: "Click Me!";
61 font.pointSize: 24;
62 width: 150; height: 50;
63
64 MediaPlayer {
65 id: playMusic
66 source: "music.wav"
67 audioOutput: AudioOutput {}
68 }
69 MouseArea {
70 anchors.fill: parent
71 onPressed: { playMusic.play() }
72 }
73 }
74 \endqml
75
76 You can use MediaPlayer together with a MultiMedia::AudioOutput to play audio content, or you can use it
77 in conjunction with a Multimedia::VideoOutput for rendering video.
78
79 \qml
80 Item {
81 MediaPlayer {
82 id: mediaplayer
83 source: "groovy_video.mp4"
84 audioOutput: AudioOutput {}
85 videoOutput: videoOutput
86 }
87
88 VideoOutput {
89 id: videoOutput
90 anchors.fill: parent
91 }
92
93 MouseArea {
94 anchors.fill: parent
95 onPressed: mediaplayer.play();
96 }
97 }
98 \endqml
99
100 \sa AudioOutput, VideoOutput
101*/
102
103void QMediaPlayerPrivate::setState(QMediaPlayer::PlaybackState toState)
104{
105 Q_Q(QMediaPlayer);
106
107 if (toState != state) {
108 const auto fromState = std::exchange(state, toState);
109 if (toState == QMediaPlayer::PlayingState || fromState == QMediaPlayer::PlayingState)
110 emit q->playingChanged(toState == QMediaPlayer::PlayingState);
111 emit q->playbackStateChanged(toState);
112 }
113}
114
115void QMediaPlayerPrivate::setStatus(QMediaPlayer::MediaStatus s)
116{
117 Q_Q(QMediaPlayer);
118
119 emit q->mediaStatusChanged(s);
120}
121
122void QMediaPlayerPrivate::setError(QMediaPlayer::Error error, const QString &errorString)
123{
124 Q_Q(QMediaPlayer);
125
126 this->error.setAndNotify(error, errorString, *q);
127}
128
129void QMediaPlayerPrivate::setMedia(QUrl media, QIODevice *stream)
130{
131 setError(QMediaPlayer::NoError, {});
132
133 if (!control)
134 return;
135
136 media = m_sourceResolver->resolve(media);
137
138 std::unique_ptr<QFile> file;
139
140 // Back ends can't play qrc files directly.
141 // If the back end supports StreamPlayback, we pass a QFile for that resource.
142 // If it doesn't, we copy the data to a temporary file and pass its path.
143 if (!media.isEmpty() && !stream && media.scheme() == QLatin1String("qrc")
144 && !control->canPlayQrc()) {
145 qrcMedia = media;
146
147 control->mediaStatusChanged(QMediaPlayer::LoadingMedia);
148
149 file.reset(new QFile(QLatin1Char(':') + media.path()));
150 if (!file->open(QFile::ReadOnly)) {
151 file.reset();
152 control->setInvalidMediaWithError(
153 QMediaPlayer::ResourceError,
154 QMediaPlayer::tr("Attempting to play invalid Qt resource"));
155
156 } else if (control->streamPlaybackSupported()) {
157 control->setMedia(media, file.get());
158 } else {
159#if QT_CONFIG(temporaryfile)
160#if defined(Q_OS_ANDROID)
161 std::unique_ptr<QTemporaryFile> tempFile { QTemporaryFile::createNativeFile(*file) };
162 if (!tempFile) {
163 control->setInvalidMediaWithError(
164 QMediaPlayer::ResourceError,
165 QMediaPlayer::tr("Failed to establish temporary file during playback"));
166 return;
167 }
168
169 // Use a temp path derived from the original resource path
170 const QFileInfo mediaInfo(media.path());
171 const QString targetDirPath = QDir::tempPath() + mediaInfo.path();
172 if (!QDir().mkpath(targetDirPath)) {
173 control->setInvalidMediaWithError(
174 QMediaPlayer::ResourceError,
175 QStringLiteral("Could not create a temporary directory: %1")
176 .arg(targetDirPath));
177 return;
178 }
179
180 // Add a random suffix to avoid collisions
181 const QString baseName = mediaInfo.completeBaseName() + QLatin1Char('_')
182 + QString::number(QRandomGenerator::global()->generate(), 16);
183
184 // Keep extension suffix
185 const QString suffix = mediaInfo.suffix();
186
187 const QString newName = targetDirPath + QLatin1Char('/') + baseName
188 + (suffix.isEmpty() ? QString() : QLatin1Char('.') + suffix);
189
190 if (!tempFile->rename(newName)) {
191 control->setInvalidMediaWithError(
192 QMediaPlayer::ResourceError,
193 QStringLiteral("Could not rename temporary file to: %1").arg(newName));
194 return;
195 }
196#else
197 std::unique_ptr<QTemporaryFile> tempFile = std::make_unique<QTemporaryFile>();
198
199 // Preserve original file extension, some back ends might not load the file if it doesn't
200 // have an extension.
201 const QString suffix = QFileInfo(*file).suffix();
202 if (!suffix.isEmpty())
203 tempFile->setFileTemplate(tempFile->fileTemplate() + QLatin1Char('.') + suffix);
204
205 // Copy the qrc data into the temporary file
206 if (!tempFile->open()) {
207 control->setInvalidMediaWithError(QMediaPlayer::ResourceError,
208 tempFile->errorString());
209 qrcFile.reset();
210 return;
211 }
212 char buffer[4096];
213 while (true) {
214 qint64 len = file->read(buffer, sizeof(buffer));
215 if (len < 1)
216 break;
217 tempFile->write(buffer, len);
218 }
219 tempFile->close();
220#endif
221 file = std::move(tempFile);
222 control->setMedia(QUrl(QUrl::fromLocalFile(file->fileName())), nullptr);
223#else
224 qWarning("Qt was built with -no-feature-temporaryfile: playback from resource file is not supported!");
225#endif
226 }
227 } else {
228 qrcMedia = QUrl();
229 QUrl url = qMediaFromUserInput(media);
230 if (url.scheme() == QLatin1String("content") && !stream) {
231 file.reset(new QFile(media.url()));
232 stream = file.get();
233 }
234
235 control->setMedia(url, stream);
236 }
237
238 qrcFile.swap(file); // Cleans up any previous file
239}
240
241QList<QMediaMetaData> QMediaPlayerPrivate::trackMetaData(QPlatformMediaPlayer::TrackType s) const
242{
243 QList<QMediaMetaData> tracks;
244 if (control) {
245 int count = control->trackCount(s);
246 for (int i = 0; i < count; ++i) {
247 tracks.append(control->trackMetaData(s, i));
248 }
249 }
250 return tracks;
251}
252
253/*!
254 Constructs a QMediaPlayer instance as a child of \a{parent}.
255*/
256
257QMediaPlayer::QMediaPlayer(QObject *parent)
258 : QObject(*new QMediaPlayerPrivate, parent)
259{
260 Q_D(QMediaPlayer);
261
262 auto maybeControl = QPlatformMediaIntegration::instance()->createPlayer(this);
263 if (maybeControl) {
264 d->control = maybeControl.value();
265 d->state = d->control->state();
266 } else {
267 qWarning() << "Failed to initialize QMediaPlayer" << maybeControl.error();
268 d->setError(QMediaPlayer::ResourceError, maybeControl.error());
269 }
270}
271
272
273/*!
274 Destroys the player object.
275*/
276
277QMediaPlayer::~QMediaPlayer()
278{
279 Q_D(QMediaPlayer);
280
281 // prevents emitting audioOutputChanged and videoOutputChanged.
282 QSignalBlocker blocker(this);
283
284 // Reset audio output and video sink to ensure proper unregistering of the source
285 // To be investigated: registering of the source might be removed after switching on the ffmpeg
286 // backend;
287
288 // Workaround to prevent freeze in GStreamer when setting audioOutput while stopped
289 if (d->control)
290 d->control->qmediaplayerDestructorCalled = true;
291 setAudioOutput(nullptr);
292
293 d->setVideoSink(nullptr);
294 delete d->control;
295}
296
297QUrl QMediaPlayer::source() const
298{
299 Q_D(const QMediaPlayer);
300
301 return d->source;
302}
303
304/*!
305 Returns the stream source of media data.
306
307 This is only valid if a stream was passed to setSource().
308
309 \sa setSource()
310*/
311
312const QIODevice *QMediaPlayer::sourceDevice() const
313{
314 Q_D(const QMediaPlayer);
315
316 return d->stream;
317}
318
319/*!
320 \property QMediaPlayer::playbackState
321
322 Returns the \l{QMediaPlayer::}{PlaybackState}.
323
324 \sa playing
325*/
326QMediaPlayer::PlaybackState QMediaPlayer::playbackState() const
327{
328 Q_D(const QMediaPlayer);
329
330 // In case if EndOfMedia status is already received
331 // but state is not.
332 if (d->control
333 && d->control->mediaStatus() == QMediaPlayer::EndOfMedia
334 && d->state != d->control->state()) {
335 return d->control->state();
336 }
337
338 return d->state;
339}
340
341QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const
342{
343 Q_D(const QMediaPlayer);
344 return d->control ? d->control->mediaStatus() : NoMedia;
345}
346
347/*!
348 Returns the duration of the current media in ms.
349
350 Returns 0 if the media player doesn't have a valid media file or stream.
351 For live streams, the duration usually changes during playback as more
352 data becomes available.
353*/
354qint64 QMediaPlayer::duration() const
355{
356 Q_D(const QMediaPlayer);
357 return d->control ? d->control->duration() : 0;
358}
359
360/*!
361 Returns the current position inside the media being played back in ms.
362
363 Returns 0 if the media player doesn't have a valid media file or stream.
364 For live streams, the duration usually changes during playback as more
365 data becomes available.
366*/
367qint64 QMediaPlayer::position() const
368{
369 Q_D(const QMediaPlayer);
370 return d->control ? d->control->position() : 0;
371}
372
373/*!
374 Returns a number between 0 and 1 when buffering data.
375
376 0 means that there is no buffered data available, playback is usually
377 stalled in this case. Playback will resume once the buffer reaches 1,
378 meaning enough data has been buffered to be able to resume playback.
379
380 bufferProgress() will always return 1 for local files.
381*/
382float QMediaPlayer::bufferProgress() const
383{
384 Q_D(const QMediaPlayer);
385 return d->control ? d->control->bufferProgress() : 0;
386}
387
388/*!
389 Returns a QMediaTimeRange describing the currently buffered data.
390
391 When streaming media from a remote source, different parts of the media
392 file can be available locally. The returned QMediaTimeRange object describes
393 the time ranges that are buffered and available for immediate playback.
394
395 \sa QMediaTimeRange
396*/
397QMediaTimeRange QMediaPlayer::bufferedTimeRange() const
398{
399 Q_D(const QMediaPlayer);
400 return d->control ? d->control->availablePlaybackRanges() : QMediaTimeRange{};
401}
402
403/*!
404 \qmlproperty bool QtMultimedia::MediaPlayer::hasAudio
405
406 This property holds whether the media contains audio.
407*/
408
409/*!
410 \property QMediaPlayer::hasAudio
411 \brief This property holds whether the media contains audio.
412*/
413bool QMediaPlayer::hasAudio() const
414{
415 Q_D(const QMediaPlayer);
416 return d->control && d->control->isAudioAvailable();
417}
418
419/*!
420 \qmlproperty bool QtMultimedia::MediaPlayer::hasVideo
421
422 This property holds whether the media contains video.
423*/
424
425/*!
426 \property QMediaPlayer::hasVideo
427 \brief This property holds whether the media contains video.
428*/
429bool QMediaPlayer::hasVideo() const
430{
431 Q_D(const QMediaPlayer);
432 return d->control && d->control->isVideoAvailable();
433}
434
435/*!
436 Returns true if the media is seekable. Most file based media files are seekable,
437 but live streams usually are not.
438
439 \sa position
440*/
441bool QMediaPlayer::isSeekable() const
442{
443 Q_D(const QMediaPlayer);
444 return d->control && d->control->isSeekable();
445}
446
447bool QMediaPlayer::isPlaying() const
448{
449 Q_D(const QMediaPlayer);
450 return d->state == QMediaPlayer::PlayingState;
451}
452
453/*!
454 Returns the current playback rate.
455*/
456qreal QMediaPlayer::playbackRate() const
457{
458 Q_D(const QMediaPlayer);
459 return d->control ? d->control->playbackRate() : 0.;
460}
461
462/*!
463 \enum QMediaPlayer::Loops
464
465 Some predefined constants for the \l loops property.
466
467 \value Infinite Loop forever.
468 \value Once Play the media once (the default).
469*/
470
471/*!
472 \property QMediaPlayer::loops
473
474 Determines how often the media is played before the player stops.
475 Set to QMediaPlayer::Infinite to loop the current media file forever.
476
477 The default value is \c 1. Setting this property to \c 0 has no effect.
478*/
479
480/*!
481 \qmlproperty int QtMultimedia::MediaPlayer::loops
482
483 Determines how often the media is played before the player stops.
484 Set to MediaPlayer::Infinite to loop the current media file forever.
485
486 The default value is \c 1. Setting this property to \c 0 has no effect.
487*/
488int QMediaPlayer::loops() const
489{
490 Q_D(const QMediaPlayer);
491 return d->control ? d->control->loops() : 1;
492}
493
494void QMediaPlayer::setLoops(int loops)
495{
496 Q_D(QMediaPlayer);
497 if (loops == 0)
498 return;
499 if (d->control)
500 d->control->setLoops(loops);
501}
502
503/*!
504 Returns the current error state.
505*/
506QMediaPlayer::Error QMediaPlayer::error() const
507{
508 return d_func()->error.code();
509}
510
511/*!
512 \qmlproperty string QtMultimedia::MediaPlayer::errorString
513
514 This property holds a string describing the current error condition in more
515 detail.
516*/
517
518/*!
519 \property QMediaPlayer::errorString
520 \brief This property holds a string describing the current error condition in
521 more detail.
522*/
523QString QMediaPlayer::errorString() const
524{
525 return d_func()->error.description();
526}
527
528/*!
529 \qmlmethod void QtMultimedia::MediaPlayer::play()
530
531 Starts or resumes playback of the media.
532
533 Sets the \l playbackState property to PlayingState, and changes
534 \l playing to \c true.
535*/
536
537/*!
538 Start or resume playing the current source.
539
540 \sa pause(), stop()
541*/
542void QMediaPlayer::play()
543{
544 Q_D(QMediaPlayer);
545
546 if (!d->control)
547 return;
548
549 d->control->play();
550}
551
552/*!
553 \qmlmethod void QtMultimedia::MediaPlayer::pause()
554
555 Pauses playback of the media.
556
557 Sets the \l playbackState property to PausedState,
558 and changes \l playing to \c false.
559*/
560
561/*!
562 Pause playing the current source.
563
564 \sa play(), stop()
565*/
566void QMediaPlayer::pause()
567{
568 Q_D(QMediaPlayer);
569
570 if (d->control)
571 d->control->pause();
572}
573
574/*!
575 \qmlmethod void QtMultimedia::MediaPlayer::stop()
576
577 Stops playback of the media.
578
579 Sets the \l playbackState property to StoppedState,
580 and changes \l playing to \c false.
581*/
582
583/*!
584 Stop playing, and reset the play position to the beginning.
585
586 \sa play(), pause()
587*/
588void QMediaPlayer::stop()
589{
590 Q_D(QMediaPlayer);
591
592 if (d->control)
593 d->control->stop();
594}
595
596void QMediaPlayer::setPosition(qint64 position)
597{
598 Q_D(QMediaPlayer);
599
600 if (!d->control)
601 return;
602 if (!d->control->isSeekable())
603 return;
604 d->control->setPosition(qMax(position, 0ll));
605}
606
607void QMediaPlayer::setPlaybackRate(qreal rate)
608{
609 Q_D(QMediaPlayer);
610
611 if (d->control)
612 d->control->setPlaybackRate(rate);
613}
614
615/*!
616 \qmlproperty url QtMultimedia::MediaPlayer::source
617
618 This property holds the source URL of the media.
619
620 \snippet multimedia-snippets/qtvideosink.qml complete
621
622 \sa QMediaPlayer::setSource()
623*/
624
625/*!
626 Sets the current \a source.
627
628 Setting the media to a null QUrl will cause the player to discard all
629 information relating to the current media source and to cease all I/O operations related
630 to that media. Setting the media will stop the playback.
631
632 \note This function returns immediately after recording the specified source of the media.
633 It does not wait for the media to finish loading and does not check for errors. Listen for
634 the mediaStatusChanged() and error() signals to be notified when the media is loaded and
635 when an error occurs during loading.
636
637 \note FFmpeg, used by the FFmpeg media backend, restricts use of nested protocols for
638 security reasons. In controlled environments where all inputs are trusted, the list of
639 approved protocols can be overridden using the QT_FFMPEG_PROTOCOL_WHITELIST environment
640 variable. This environment variable is Qt's private API and can change between patch
641 releases without notice.
642*/
643
644void QMediaPlayer::setSource(const QUrl &source)
645{
646 Q_D(QMediaPlayer);
647 stop();
648
649 if (d->source == source && d->stream == nullptr)
650 return;
651
652 d->source = source;
653 d->stream = nullptr;
654
655 d->setMedia(source, nullptr);
656 emit sourceChanged(d->source);
657}
658
659/*!
660 Sets the current source \a device.
661
662 The media data will be read from \a device. The \a sourceUrl can be provided
663 to resolve additional information about the media, mime type etc. The
664 \a device must be open and readable.
665
666 For macOS the \a device should also be seek-able.
667
668 \note This function returns immediately after recording the specified source
669 of the media. It does not wait for the media to finish loading and does not
670 check for errors. Listen for the mediaStatusChanged() and error() signals to
671 be notified when the media is loaded, and if an error occurs during loading.
672*/
673void QMediaPlayer::setSourceDevice(QIODevice *device, const QUrl &sourceUrl)
674{
675 Q_D(QMediaPlayer);
676 stop();
677
678 if (d->source == sourceUrl && d->stream == device)
679 return;
680
681 d->source = sourceUrl;
682 d->stream = device;
683
684 d->setMedia(d->source, device);
685 emit sourceChanged(d->source);
686}
687
688/*!
689 \qmlproperty QAudioBufferOutput QtMultimedia::MediaPlayer::audioBufferOutput
690 \since 6.8
691
692 This property holds the target audio buffer output.
693
694 Normal usage of MediaPlayer from QML should not require using this property.
695
696 \sa QMediaPlayer::audioBufferOutput()
697*/
698
699/*!
700 \property QMediaPlayer::audioBufferOutput
701 \since 6.8
702 \brief The output audio buffer used by the media player.
703
704 Sets an audio buffer \a output to the media player.
705
706 If \l QAudioBufferOutput is specified and the media source
707 contains an audio stream, the media player, it will emit
708 the signal \l{QAudioBufferOutput::audioBufferReceived} with
709 audio buffers containing decoded audio data. At the end of
710 the audio stream, \c QMediaPlayer emits an empty \l QAudioBuffer.
711
712 \c QMediaPlayer emits outputs audio buffers at the same time as it
713 pushes the matching data to the audio output if it's specified.
714 However, the sound can be played with a small delay due to
715 audio bufferization.
716
717 The format of emitted audio buffers is taken from the
718 specified \a output or from the matching audio stream
719 if the \a output returns an invalid format. Emitted
720 audio data is not scaled depending on the current playback rate.
721
722 Potential use cases of utilizing \c QAudioBufferOutput
723 with \c QMediaPlayer might be:
724 \list
725 \li Audio visualization. If the playback rate of the media player
726 is not \c 1, you may scale the output image dimensions,
727 or image update interval according to the requirements
728 of the visualizer.
729 \li Any AI sound processing, e.g. voice recognition.
730 \li Sending the data to external audio output.
731 Playback rate changing, synchronization with video, and manual
732 flushing on stoping and seeking should be considered.
733 We don't recommend using the audio buffer output
734 for this purpose unless you have a strong reason for this.
735 \endlist
736
737*/
738void QMediaPlayer::setAudioBufferOutput(QAudioBufferOutput *output)
739{
740 Q_D(QMediaPlayer);
741
742 QAudioBufferOutput *oldOutput = d->audioBufferOutput;
743 if (oldOutput == output)
744 return;
745
746 d->audioBufferOutput = output;
747
748 if (oldOutput) {
749 auto oldPlayer = QAudioBufferOutputPrivate::exchangeMediaPlayer(*oldOutput, this);
750 if (oldPlayer)
751 oldPlayer->setAudioBufferOutput(nullptr);
752 }
753
754 if (d->control)
755 d->control->setAudioBufferOutput(output);
756
757 emit audioBufferOutputChanged();
758}
759
760QAudioBufferOutput *QMediaPlayer::audioBufferOutput() const
761{
762 Q_D(const QMediaPlayer);
763 return d->audioBufferOutput;
764}
765
766/*!
767 \qmlproperty AudioOutput QtMultimedia::MediaPlayer::audioOutput
768
769 This property holds the target audio output.
770 Accepts one AudioOutput elements.
771
772 \sa QMediaPlayer::setAudioOutput()
773*/
774
775
776/*!
777 \property QMediaPlayer::audioOutput
778 \brief The audio output device used by the media player.
779
780 The current audio output to be used when playing back media. Setting
781 a new audio output will replace the currently used output.
782
783 Setting this property to \c nullptr will disable any audio output.
784*/
785void QMediaPlayer::setAudioOutput(QAudioOutput *output)
786{
787 Q_D(QMediaPlayer);
788 auto oldOutput = d->audioOutput;
789 if (oldOutput == output)
790 return;
791 d->audioOutput = output;
792 if (d->control)
793 d->control->setAudioOutput(nullptr);
794 if (oldOutput)
795 oldOutput->setDisconnectFunction({});
796 if (output) {
797 output->setDisconnectFunction([this](){ setAudioOutput(nullptr); });
798 if (d->control)
799 d->control->setAudioOutput(output->handle());
800 }
801 emit audioOutputChanged();
802}
803
804QAudioOutput *QMediaPlayer::audioOutput() const
805{
806 Q_D(const QMediaPlayer);
807 return d->audioOutput;
808}
809
810/*!
811 \qmlsignal QtMultimedia::MediaPlayer::tracksChanged()
812
813 This signal is emitted when the \l{audioTracks}, \l{subtitleTracks}
814 or \l{videoTracks} properties are changed.
815*/
816
817/*!
818 \fn QMediaPlayer::tracksChanged()
819*/
820
821/*!
822 \qmlproperty list<mediaMetaData> QtMultimedia::MediaPlayer::audioTracks
823
824 This property holds a list of metadata.
825 Each index refers to an audio track.
826
827 The metadata holds properties describing the individual tracks. For
828 audio tracks the \l{QMediaMetaData}{Language} is usually the most
829 important property.
830
831 This property emits the \l{tracksChanged} signal when modified.
832
833 \sa mediaMetaData
834*/
835
836/*!
837 \property QMediaPlayer::audioTracks
838
839 Lists the set of available audio tracks inside the media.
840
841 The QMediaMetaData returned describes the properties of individual
842 tracks.
843
844 Different audio tracks can for example contain audio in different languages.
845*/
846QList<QMediaMetaData> QMediaPlayer::audioTracks() const
847{
848 Q_D(const QMediaPlayer);
849 return d->trackMetaData(QPlatformMediaPlayer::AudioStream);
850}
851
852/*!
853 \qmlproperty list<mediaMetaData> QtMultimedia::MediaPlayer::videoTracks
854
855 This property holds a list of metadata.
856 Each index refers to a video track.
857
858 The metadata holds properties describing the individual tracks.
859
860 This property emits the \l{tracksChanged} signal when modified.
861
862 \sa mediaMetaData
863*/
864
865/*!
866 \property QMediaPlayer::videoTracks
867
868 Lists the set of available video tracks inside the media.
869
870 The QMediaMetaData returned describes the properties of individual
871 tracks.
872*/
873QList<QMediaMetaData> QMediaPlayer::videoTracks() const
874{
875 Q_D(const QMediaPlayer);
876 return d->trackMetaData(QPlatformMediaPlayer::VideoStream);
877}
878
879/*!
880 \qmlproperty list<mediaMetaData> QtMultimedia::MediaPlayer::subtitleTracks
881
882 This property holds a list of metadata.
883 Each index refers to a subtitle track.
884
885 The metadata holds properties describing the individual tracks. For
886 subtitle tracks the \l{QMediaMetaData}{Language} is usually the most
887 important property.
888
889 This property emits the \l{tracksChanged} signal when modified.
890
891 \sa mediaMetaData
892*/
893
894/*!
895 \property QMediaPlayer::subtitleTracks
896
897 Lists the set of available subtitle tracks inside the media.
898
899 The QMediaMetaData returned describes the properties of individual
900 tracks.
901*/
902QList<QMediaMetaData> QMediaPlayer::subtitleTracks() const
903{
904 Q_D(const QMediaPlayer);
905 return d->trackMetaData(QPlatformMediaPlayer::SubtitleStream);
906}
907
908/*!
909 \qmlproperty int QtMultimedia::MediaPlayer::activeAudioTrack
910
911 This property holds the track number of the currently active audio track.
912 Set to \c{-1} to disable audio track.
913
914 The default property value is \c{0}: the first audio track.
915*/
916
917/*!
918 \property QMediaPlayer::activeAudioTrack
919 \brief Returns the currently active audio track.
920
921 By default, the first available audio track will be chosen.
922
923 Set \a index to \c -1 to disable all audio tracks.
924*/
925int QMediaPlayer::activeAudioTrack() const
926{
927 Q_D(const QMediaPlayer);
928 return d->control ? d->control->activeTrack(QPlatformMediaPlayer::AudioStream) : 0;
929}
930
931/*!
932 \since 6.2
933 \qmlproperty int QtMultimedia::MediaPlayer::activeVideoTrack
934
935 This property holds the track number of the currently active video audio track.
936 Set to \c{-1} to disable video track.
937
938 The default property value is \c{0}: the first video track.
939*/
940
941/*!
942 \property QMediaPlayer::activeVideoTrack
943 \brief Returns the currently active video track.
944
945 By default, the first available audio track will be chosen.
946
947 Set \a index to \c -1 to disable all video tracks.
948*/
949int QMediaPlayer::activeVideoTrack() const
950{
951 Q_D(const QMediaPlayer);
952 return d->control ? d->control->activeTrack(QPlatformMediaPlayer::VideoStream) : -1;
953}
954
955/*!
956 \since 6.2
957 \qmlproperty int QtMultimedia::MediaPlayer::activeSubtitleTrack
958
959 This property holds the track number of the currently active subtitle track.
960 Set to \c{-1} to disable subtitle track.
961
962 The default property value is \c{-1}: no subtitles active.
963*/
964
965/*!
966 \property QMediaPlayer::activeSubtitleTrack
967 \brief Returns the currently active subtitle track.
968
969 Set \a index to \c -1 to disable subtitles.
970
971 Subtitles are disabled by default.
972*/
973int QMediaPlayer::activeSubtitleTrack() const
974{
975 Q_D(const QMediaPlayer);
976 return d->control ? d->control->activeTrack(QPlatformMediaPlayer::SubtitleStream) : -1;
977}
978
979void QMediaPlayer::setActiveAudioTrack(int index)
980{
981 Q_D(QMediaPlayer);
982 if (!d->control)
983 return;
984
985 if (activeAudioTrack() == index)
986 return;
987 d->control->setActiveTrack(QPlatformMediaPlayer::AudioStream, index);
988}
989
990void QMediaPlayer::setActiveVideoTrack(int index)
991{
992 Q_D(QMediaPlayer);
993 if (!d->control)
994 return;
995
996 if (activeVideoTrack() == index)
997 return;
998 d->control->setActiveTrack(QPlatformMediaPlayer::VideoStream, index);
999}
1000
1001void QMediaPlayer::setActiveSubtitleTrack(int index)
1002{
1003 Q_D(QMediaPlayer);
1004 if (!d->control)
1005 return;
1006
1007 if (activeSubtitleTrack() == index)
1008 return;
1009 d->control->setActiveTrack(QPlatformMediaPlayer::SubtitleStream, index);
1010}
1011
1012/*!
1013 \qmlproperty VideoOutput QtMultimedia::MediaPlayer::videoOutput
1014
1015 This property holds the target video output.
1016 Accepts one VideoOutput elements.
1017
1018 \sa QMediaPlayer::setVideoOutput()
1019*/
1020
1021/*!
1022 \property QMediaPlayer::videoOutput
1023 \brief The video output to be used by the media player.
1024
1025 A media player can only have one video output attached, so
1026 setting this property will replace the previously connected
1027 video output.
1028
1029 Setting this property to \c nullptr will disable video output.
1030*/
1031QObject *QMediaPlayer::videoOutput() const
1032{
1033 Q_D(const QMediaPlayer);
1034 return d->videoOutput;
1035}
1036
1037void QMediaPlayer::setVideoOutput(QObject *output)
1038{
1039 Q_D(QMediaPlayer);
1040 if (d->videoOutput == output)
1041 return;
1042
1043 auto *sink = qobject_cast<QVideoSink *>(output);
1044 if (!sink && output) {
1045 auto *mo = output->metaObject();
1046 mo->invokeMethod(output, "videoSink", Q_RETURN_ARG(QVideoSink *, sink));
1047 }
1048 d->videoOutput = output;
1049 d->setVideoSink(sink);
1050}
1051
1052/*!
1053 Sets \a sink to be the QVideoSink instance to
1054 retrieve video data.
1055*/
1056void QMediaPlayer::setVideoSink(QVideoSink *sink)
1057{
1058 Q_D(QMediaPlayer);
1059 d->videoOutput = nullptr;
1060 d->setVideoSink(sink);
1061}
1062
1063/*!
1064 Returns the QVideoSink instance.
1065*/
1066QVideoSink *QMediaPlayer::videoSink() const
1067{
1068 Q_D(const QMediaPlayer);
1069 return d->videoSink;
1070}
1071
1072
1073#if 0
1074/*
1075 \since 5.15
1076 Sets multiple video sinks as the video output of a media player.
1077 This allows the media player to render video frames on several outputs.
1078
1079 If a video output has already been set on the media player the new surfaces
1080 will replace it.
1081*/
1082void QMediaPlayer::setVideoOutput(const QList<QVideoSink *> &sinks)
1083{
1084 // ### IMPLEMENT ME
1085 Q_UNUSED(sinks);
1086// setVideoOutput(!surfaces.empty() ? new QVideoSurfaces(surfaces, this) : nullptr);
1087}
1088#endif
1089
1090/*!
1091 Returns true if the media player is supported on this platform.
1092*/
1093bool QMediaPlayer::isAvailable() const
1094{
1095 Q_D(const QMediaPlayer);
1096 return bool(d->control);
1097}
1098
1099/*!
1100 \qmlproperty mediaMetaData QtMultimedia::MediaPlayer::metaData
1101
1102 Returns meta data for the current media used by the media player.
1103
1104 Meta data can contain information such as the title of the video or its creation date.
1105
1106 \note The Windows implementation provides metadata only for media located on the local file
1107 system.
1108*/
1109
1110/*!
1111 \property QMediaPlayer::metaData
1112
1113 Returns meta data for the current media used by the media player.
1114
1115 Meta data can contain information such as the title of the video or its creation date.
1116
1117 \note The Windows implementation provides metadata only for media located on the local file
1118 system.
1119*/
1120QMediaMetaData QMediaPlayer::metaData() const
1121{
1122 Q_D(const QMediaPlayer);
1123 return d->control ? d->control->metaData() : QMediaMetaData{};
1124}
1125
1126/*!
1127 \qmlproperty bool QtMultimedia::MediaPlayer::pitchCompensation
1128 \since 6.10
1129
1130 This property holds whether pitch compensation is enabled.
1131*/
1132
1133/*!
1134 \property QMediaPlayer::pitchCompensation
1135 \brief The pitch compensation status of the media player.
1136 \since 6.10
1137
1138 Indicates whether pitch compensation is enabled. When enabled, changing the playback rate
1139 will not affect the pitch of the audio signal.
1140
1141 \note The pitch compensation will increase the CPU load of the QMediaPlayer.
1142
1143 By default is \c{true} if pitch compensation, is available, else \c{false}.
1144*/
1145
1146/*!
1147 Returns the state of pitch compensation.
1148 \since 6.10
1149*/
1150bool QMediaPlayer::pitchCompensation() const
1151{
1152 Q_D(const QMediaPlayer);
1153 return d->control ? d->control->pitchCompensation() : false;
1154}
1155
1156/*!
1157 Sets the state (\a enabled or disabled) of pitch compensation. This only
1158 has an effect if the audio pitch compensation can be configured on the
1159 backend at runtime.
1160 \since 6.10
1161*/
1162void QMediaPlayer::setPitchCompensation(bool enabled) const
1163{
1164 Q_D(const QMediaPlayer);
1165 if (d->control)
1166 d->control->setPitchCompensation(enabled);
1167}
1168
1169/*!
1170 \enum QMediaPlayer::PitchCompensationAvailability
1171 \since 6.10
1172
1173 Availablility of pitch compensation.
1174
1175 Different backends have different behavior regarding pitch compensation when changing
1176 playback rate.
1177
1178 \value AlwaysOn The media player is always performing pitch compensation.
1179 \value Available The media player can be configured to use pitch compensation.
1180 If pitch compensation is available on the current platform, it will be enabled by default,
1181 but users can disable if needed.
1182 \value Unavailable The media player is not able to perform pitch compensation
1183 on the current platform.
1184*/
1185
1186/*!
1187 \qmlproperty enumeration QtMultimedia::MediaPlayer::pitchCompensationAvailability
1188 \since 6.10
1189
1190 Indicates the availability of pitch compensation of the \c MediaPlayer on the current backend.
1191 The enumeration \c PitchCompensationAvailability is scoped.
1192
1193 \qmlenumeratorsfrom QMediaPlayer::PitchCompensationAvailability
1194*/
1195
1196/*!
1197 \property QMediaPlayer::pitchCompensationAvailability
1198 \brief The pitch compensation availability of the current QtMultimedia backend.
1199 \since 6.10
1200
1201 Indicates the availability of pitch compensation of the QMediaPlayer on the current backend.
1202
1203 \note Different backends may have different behavior.
1204
1205 For more information, see \l{QMediaPlayer::PitchCompensationAvailability}.
1206*/
1207
1208/*!
1209 Returns availability of pitch compensation of the current backend.
1210 \since 6.10
1211*/
1212
1213QMediaPlayer::PitchCompensationAvailability QMediaPlayer::pitchCompensationAvailability() const
1214{
1215 Q_D(const QMediaPlayer);
1216 return d->control ? d->control->pitchCompensationAvailability()
1217 : PitchCompensationAvailability::Unavailable;
1218}
1219
1220/*!
1221 \qmlproperty PlaybackOptions MediaPlayer::playbackOptions
1222 \since 6.10
1223
1224 This property exposes the \l PlaybackOptions API that gives low-level control of media playback
1225 options. Although we strongly recommend to rely on the default settings of \l MediaPlayer,
1226 this API can be used to optimize media playback for specific use cases where the default
1227 options are not ideal.
1228
1229 Playback options take effect the next time \l MediaPlayer::source is changed.
1230*/
1231
1232/*!
1233 \property QMediaPlayer::playbackOptions
1234 \brief Advanced playback options used to configure media playback and decoding.
1235 \since 6.10
1236
1237 This property exposes the \l QPlaybackOptions API that gives low-level control of media
1238 playback options. Although we strongly recommend to rely on the default settings of
1239 \l QMediaPlayer, this API can be used to optimize media playback for specific use cases where
1240 the default options are not ideal.
1241
1242 Playback options take effect the next time \l QMediaPlayer::setSource() is called.
1243*/
1244
1245QPlaybackOptions QMediaPlayer::playbackOptions() const
1246{
1247 Q_D(const QMediaPlayer);
1248 return d->playbackOptions;
1249}
1250
1251void QMediaPlayer::setPlaybackOptions(const QPlaybackOptions &options)
1252{
1253 Q_D(QMediaPlayer);
1254 if (std::exchange(d->playbackOptions, options) != options)
1255 emit playbackOptionsChanged();
1256}
1257
1258void QMediaPlayer::resetPlaybackOptions()
1259{
1260 Q_D(QMediaPlayer);
1261 QPlaybackOptions defaultOptions{ };
1262 if (std::exchange(d->playbackOptions, defaultOptions) != defaultOptions)
1263 emit playbackOptionsChanged();
1264}
1265
1266// Enums
1267/*!
1268 \enum QMediaPlayer::PlaybackState
1269
1270 Defines the current state of a media player.
1271
1272 \value StoppedState The media player is not playing content, playback will begin from the start
1273 of the current track.
1274 \value PlayingState The media player is currently playing content. This indicates the same as the \l playing property.
1275 \value PausedState The media player has paused playback, playback of the current track will
1276 resume from the position the player was paused at.
1277*/
1278
1279/*!
1280 \qmlproperty enumeration QtMultimedia::MediaPlayer::playbackState
1281
1282 This property holds the state of media playback. It can be one of the following:
1283
1284 \table
1285 \header \li Property value
1286 \li Description
1287 \row \li PlayingState
1288 \li The media is currently playing. This indicates the same as the \l playing property.
1289 \row \li PausedState
1290 \li Playback of the media has been suspended.
1291 \row \li StoppedState
1292 \li Playback of the media is yet to begin.
1293 \endtable
1294*/
1295
1296/*!
1297 \qmlsignal QtMultimedia::MediaPlayer::playbackStateChanged()
1298
1299 This signal is emitted when the \l playbackState property is altered.
1300*/
1301
1302/*!
1303 \qmlsignal QtMultimedia::MediaPlayer::playingChanged()
1304
1305 This signal is emitted when the \l playing property changes.
1306*/
1307
1308/*!
1309 \enum QMediaPlayer::MediaStatus
1310
1311 Defines the status of a media player's current media.
1312
1313 \value NoMedia The is no current media. The player is in the StoppedState.
1314 \value LoadingMedia The current media is being loaded. The player may be in any state.
1315 \value LoadedMedia The current media has been loaded. The player is in the StoppedState.
1316 \value StalledMedia Playback of the current media has stalled due to insufficient buffering or
1317 some other temporary interruption. The player is in the PlayingState or PausedState.
1318 \value BufferingMedia The player is buffering data but has enough data buffered for playback to
1319 continue for the immediate future. The player is in the PlayingState or PausedState.
1320 \value BufferedMedia The player has fully buffered the current media. The player is in the
1321 PlayingState or PausedState.
1322 \value EndOfMedia Playback has reached the end of the current media. The player is in the
1323 StoppedState.
1324 \value InvalidMedia The current media cannot be played. The player is in the StoppedState.
1325*/
1326
1327/*!
1328 \qmlproperty enumeration QtMultimedia::MediaPlayer::mediaStatus
1329
1330 This property holds the status of media loading. It can be one of the following:
1331
1332 \qmlenumeratorsfrom QMediaPlayer::MediaStatus
1333*/
1334
1335/*!
1336 \qmlproperty enumeration QtMultimedia::MediaPlayer::error
1337
1338 This property holds the error state of the audio. It can be one of the following.
1339
1340 \qmlenumeratorsfrom QMediaPlayer::Error
1341*/
1342
1343/*!
1344 \enum QMediaPlayer::Error
1345
1346 Defines a media player error condition.
1347
1348 \value NoError No error has occurred.
1349 \value ResourceError A media resource couldn't be resolved.
1350 \value FormatError The format of a media resource isn't (fully) supported. Playback may still
1351 be possible, but without an audio or video component.
1352 \value NetworkError A network error occurred.
1353 \value AccessDeniedError There are not the appropriate permissions to play a media resource.
1354*/
1355
1356/*!
1357 \qmlsignal QtMultimedia::MediaPlayer::errorOccurred(error, errorString)
1358
1359 This signal is emitted when an \a error has occurred. The \a errorString
1360 parameter may contain more detailed information about the error.
1361
1362 \sa QMediaPlayer::Error
1363*/
1364
1365/*!
1366 \fn QMediaPlayer::errorOccurred(QMediaPlayer::Error error, const QString &errorString)
1367
1368 Signals that an \a error condition has occurred, with \a errorString
1369 containing a description of the error.
1370
1371 \sa errorString()
1372*/
1373
1374/*!
1375 \fn QMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status)
1376
1377 Signals that the \a status of the current media has changed.
1378
1379 \sa mediaStatus()
1380*/
1381
1382/*!
1383 \fn void QMediaPlayer::sourceChanged(const QUrl &media);
1384
1385 Signals that the media source has been changed to \a media.
1386*/
1387
1388/*!
1389 \fn void QMediaPlayer::playbackRateChanged(qreal rate);
1390
1391 Signals the playbackRate has changed to \a rate.
1392*/
1393
1394/*!
1395 \fn void QMediaPlayer::seekableChanged(bool seekable);
1396
1397 Signals the \a seekable status of the player object has changed.
1398*/
1399
1400// Properties
1401/*!
1402 \property QMediaPlayer::error
1403 \brief a string describing the last error condition.
1404
1405 \sa error()
1406*/
1407
1408/*!
1409 \property QMediaPlayer::source
1410 \brief the active media source being used by the player object.
1411
1412 The player object will use the QUrl for selection of the content to
1413 be played.
1414
1415 By default this property has a null QUrl.
1416
1417 Setting this property to a null QUrl will cause the player to discard all
1418 information relating to the current media source and to cease all I/O operations related
1419 to that media.
1420
1421 \sa QUrl
1422*/
1423
1424/*!
1425 \property QMediaPlayer::mediaStatus
1426 \brief the status of the current media stream.
1427
1428 The stream status describes how the playback of the current stream is
1429 progressing.
1430
1431 By default this property is QMediaPlayer::NoMedia
1432
1433*/
1434
1435/*!
1436 \qmlproperty int QtMultimedia::MediaPlayer::duration
1437
1438 This property holds the duration of the media in milliseconds.
1439
1440 If the media doesn't have a fixed duration (a live stream for example) this
1441 will be set to \c{0}.
1442*/
1443
1444/*!
1445 \property QMediaPlayer::duration
1446 \brief the duration of the current media.
1447
1448 The value is the total playback time in milliseconds of the current media.
1449 The value may change across the life time of the QMediaPlayer object and
1450 may not be available when initial playback begins, connect to the
1451 durationChanged() signal to receive status notifications.
1452*/
1453
1454/*!
1455 \qmlproperty int QtMultimedia::MediaPlayer::position
1456
1457 The value is the current playback position, expressed in milliseconds since
1458 the beginning of the media. Periodically changes in the position will be
1459 indicated with the positionChanged() signal.
1460
1461 If the \l seekable property is true, this property can be set to milliseconds.
1462*/
1463
1464/*!
1465 \property QMediaPlayer::position
1466 \brief the playback position of the current media.
1467
1468 The value is the current playback position, expressed in milliseconds since
1469 the beginning of the media. Periodically changes in the position will be
1470 indicated with the positionChanged() signal.
1471
1472 If the \l seekable property is true, this property can be set to milliseconds.
1473*/
1474
1475/*!
1476 \qmlproperty real QtMultimedia::MediaPlayer::bufferProgress
1477
1478 This property holds how much of the data buffer is currently filled,
1479 from \c 0.0 (empty) to \c 1.0 (full).
1480
1481 Playback can start or resume only when the buffer is entirely filled.
1482 When the buffer is filled, \c MediaPlayer.Buffered is true.
1483 When buffer progress is between \c 0.0 and \c 1.0, \c MediaPlayer.Buffering
1484 is set to \c{true}.
1485
1486 A value lower than \c 1.0 implies that the property \c MediaPlayer.StalledMedia
1487 is \c{true}.
1488
1489 \sa mediaStatus
1490 */
1491
1492/*!
1493 \property QMediaPlayer::bufferProgress
1494 \brief the percentage of the temporary buffer filled before playback begins or resumes, from
1495 \c 0. (empty) to \c 1. (full).
1496
1497 When the player object is buffering; this property holds the percentage of
1498 the temporary buffer that is filled. The buffer will need to reach 100%
1499 filled before playback can start or resume, at which time mediaStatus() will return
1500 BufferedMedia or BufferingMedia. If the value is anything lower than \c 100, mediaStatus() will
1501 return StalledMedia.
1502
1503 \sa mediaStatus()
1504*/
1505
1506/*!
1507 \qmlproperty bool QtMultimedia::MediaPlayer::seekable
1508
1509 This property holds whether the \l position of the media can be changed.
1510*/
1511
1512/*!
1513 \property QMediaPlayer::seekable
1514 \brief the seek-able status of the current media
1515
1516 If seeking is supported this property will be true; false otherwise. The
1517 status of this property may change across the life time of the QMediaPlayer
1518 object, use the seekableChanged signal to monitor changes.
1519*/
1520
1521/*!
1522 \qmlproperty bool QtMultimedia::MediaPlayer::playing
1523 \since 6.5
1524
1525 Indicates whether the media is currently playing.
1526
1527 \sa playbackState
1528*/
1529
1530/*!
1531 \property QMediaPlayer::playing
1532 \brief Whether the media is playing.
1533 \since 6.5
1534
1535 \sa playbackState, PlayingState
1536*/
1537
1538/*!
1539 \qmlproperty real QtMultimedia::MediaPlayer::playbackRate
1540
1541 This property holds the rate at which media is played at as a multiple of
1542 the normal rate.
1543
1544 For more information, see \l{QMediaPlayer::playbackRate}.
1545
1546 Defaults to \c{1.0}.
1547*/
1548
1549/*!
1550 \property QMediaPlayer::playbackRate
1551 \brief the playback rate of the current media.
1552
1553 This value is a multiplier applied to the media's standard playback
1554 rate. By default this value is 1.0, indicating that the media is
1555 playing at the standard speed. Values higher than 1.0 will increase
1556 the playback speed, while values between 0.0 and 1.0 results in
1557 slower playback. Negative playback rates are not supported.
1558
1559 Not all playback services support change of the playback rate. It is
1560 framework defined as to the status and quality of audio and video
1561 while fast forwarding or rewinding.
1562*/
1563
1564/*!
1565 \fn void QMediaPlayer::durationChanged(qint64 duration)
1566
1567 Signals the duration of the content has changed to \a duration, expressed in milliseconds.
1568*/
1569
1570/*!
1571 \fn void QMediaPlayer::positionChanged(qint64 position)
1572
1573 Signals the position of the content has changed to \a position, expressed in
1574 milliseconds.
1575*/
1576
1577/*!
1578 \fn void QMediaPlayer::hasVideoChanged(bool videoAvailable)
1579
1580 Signals the availability of visual content has changed to \a videoAvailable.
1581*/
1582
1583/*!
1584 \fn void QMediaPlayer::hasAudioChanged(bool available)
1585
1586 Signals the availability of audio content has changed to \a available.
1587*/
1588
1589/*!
1590 \fn void QMediaPlayer::bufferProgressChanged(float filled)
1591
1592 Signals the amount of the local buffer \a filled as a number between 0 and 1.
1593*/
1594
1595QT_END_NAMESPACE
1596
1597#include "moc_qmediaplayer.cpp"
QPlatformMediaPlayer * control
void setState(QMediaPlayer::PlaybackState state)
\qmltype MediaPlayer \nativetype QMediaPlayer
QList< QMediaMetaData > trackMetaData(QPlatformMediaPlayer::TrackType s) const
void setMedia(QUrl media, QIODevice *stream=nullptr)
void setStatus(QMediaPlayer::MediaStatus status)
Combined button and popup list for selecting options.