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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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