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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtmultimedia/src/multimedia/playback/qmediaplayer.cpp