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);
130 setError(QMediaPlayer::NoError, {});
135 media = m_sourceResolver->resolve(media);
137 auto setErrorFn = [&](
138 QMediaPlayer::MediaStatus status,
139 QMediaPlayer::Error err,
140 const QString &errString)
142 control->setMedia(QUrl(),
nullptr);
143 control->mediaStatusChanged(status);
144 control->error(err, errString);
147 std::unique_ptr<QFile> file;
152 if (!media.isEmpty() && !stream && media.scheme() == QLatin1String(
"qrc")
156 file.reset(
new QFile(QLatin1Char(
':') + media.path()));
157 if (!file->open(QFile::ReadOnly)) {
160 QMediaPlayer::InvalidMedia,
161 QMediaPlayer::ResourceError,
162 QMediaPlayer::tr(
"Attempting to play invalid Qt resource"));
164 }
else if (
control->streamPlaybackSupported()) {
165 control->setMedia(media, file.get());
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) {
174 QMediaPlayer::InvalidMedia,
175 QMediaPlayer::ResourceError,
176 QMediaPlayer::tr(
"Failed to establish temporary file during playback"));
179 if (!tempFile->rename(tempFileName)) {
181 QMediaPlayer::InvalidMedia,
182 QMediaPlayer::ResourceError,
183 QStringLiteral(
"Could not rename temporary file to: %1").arg(tempFileName));
187 std::unique_ptr<QTemporaryFile> tempFile = std::make_unique<QTemporaryFile>();
191 const QString suffix = QFileInfo(*file).suffix();
192 if (!suffix.isEmpty())
193 tempFile->setFileTemplate(tempFile->fileTemplate() + QLatin1Char(
'.') + suffix);
196 if (!tempFile->open()) {
198 QMediaPlayer::InvalidMedia,
199 QMediaPlayer::ResourceError,
200 tempFile->errorString());
206 qint64 len = file->read(buffer,
sizeof(buffer));
209 tempFile->write(buffer, len);
213 file = std::move(tempFile);
214 control->setMedia(QUrl(QUrl::fromLocalFile(file->fileName())),
nullptr);
216 qWarning(
"Qt was built with -no-feature-temporaryfile: playback from resource file is not supported!");
221 QUrl url = qMediaFromUserInput(media);
222 if (url.scheme() == QLatin1String(
"content") && !stream) {
223 file.reset(
new QFile(media.url()));
227 control->setMedia(url, stream);
249QMediaPlayer::QMediaPlayer(QObject *parent)
250 : QObject(*
new QMediaPlayerPrivate, parent)
254 auto maybeControl = QPlatformMediaIntegration::instance()->createPlayer(
this);
256 d->control = maybeControl.value();
257 d->state = d->control->state();
259 qWarning() <<
"Failed to initialize QMediaPlayer" << maybeControl.error();
260 d->setError(QMediaPlayer::ResourceError, maybeControl.error());
665void QMediaPlayer::setSourceDevice(QIODevice *device,
const QUrl &sourceUrl)
670 if (d->source == sourceUrl && d->stream == device)
673 d->source = sourceUrl;
676 d->setMedia(d->source, device);
677 emit sourceChanged(d->source);
730void QMediaPlayer::setAudioBufferOutput(QAudioBufferOutput *output)
734 QAudioBufferOutput *oldOutput = d->audioBufferOutput;
735 if (oldOutput == output)
738 d->audioBufferOutput = output;
741 auto oldPlayer = QAudioBufferOutputPrivate::exchangeMediaPlayer(*oldOutput,
this);
743 oldPlayer->setAudioBufferOutput(
nullptr);
747 d->control->setAudioBufferOutput(output);
749 emit audioBufferOutputChanged();
777void QMediaPlayer::setAudioOutput(QAudioOutput *output)
780 auto oldOutput = d->audioOutput;
781 if (oldOutput == output)
783 d->audioOutput = output;
785 d->control->setAudioOutput(
nullptr);
787 oldOutput->setDisconnectFunction({});
789 output->setDisconnectFunction([
this](){ setAudioOutput(
nullptr); });
791 d->control->setAudioOutput(output->handle());
793 emit audioOutputChanged();
1012void QMediaPlayer::setVideoOutput(QObject *output)
1015 if (d->videoOutput == output)
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));
1023 d->videoOutput = output;
1024 d->setVideoSink(sink);
1226void QMediaPlayer::setPlaybackOptions(
const QPlaybackOptions &options)
1229 if (std::exchange(d->playbackOptions, options) != options)
1230 emit playbackOptionsChanged();
1233void QMediaPlayer::resetPlaybackOptions()
1236 QPlaybackOptions defaultOptions{ };
1237 if (std::exchange(d->playbackOptions, defaultOptions) != defaultOptions)
1238 emit playbackOptionsChanged();