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