5#include <common/qwasmvideooutput_p.h>
6#include <common/qwasmaudiooutput_p.h>
9#include <QtCore/qloggingcategory.h>
12#include <QMimeDatabase>
17Q_STATIC_LOGGING_CATEGORY(lcMediaPlayer,
"qt.multimedia.wasm.mediaplayer");
19using namespace Qt::Literals;
22 : QPlatformMediaPlayer(parent),
23 m_videoOutput(
new QWasmVideoOutput),
26 qCDebug(lcMediaPlayer) << Q_FUNC_INFO <<
this;
37 m_videoOutput->setVideoMode(QWasmVideoOutput::VideoDisplay);
38 QUuid videoElementId = QUuid::createUuid();
39 qCDebug(lcMediaPlayer) << Q_FUNC_INFO <<
"videoElementId"<< videoElementId <<
this;
41 m_videoOutput->createVideoElement(videoElementId.toString(QUuid::WithoutBraces).toStdString());
42 m_videoOutput->doElementCallbacks();
43 m_videoOutput->createOffscreenElement(QSize(1280, 720));
44 m_videoOutput->updateVideoElementGeometry(QRect(0, 0, 1280, 720));
46 connect(m_videoOutput, &QWasmVideoOutput::bufferingChanged,
this,
47 &QWasmMediaPlayer::bufferingChanged);
48 connect(m_videoOutput, &QWasmVideoOutput::errorOccured,
this,
49 [=](qint32 code,
const QString &message ) {
50 error((QMediaPlayer::Error)code, message);
55 connect(m_videoOutput, &QWasmVideoOutput::progressChanged,
this,
56 &QWasmMediaPlayer::setPositionChanged);
57 connect(m_videoOutput, &QWasmVideoOutput::durationChanged,
this,
58 &QWasmMediaPlayer::setDurationChanged);
59 connect(m_videoOutput, &QWasmVideoOutput::sizeChange,
this,
60 &QWasmMediaPlayer::videoSizeChanged);
61 connect(m_videoOutput, &QWasmVideoOutput::readyChanged,
this,
63 connect(m_videoOutput, &QWasmVideoOutput::statusChanged,
this,
64 &QWasmMediaPlayer::onMediaStatusChanged);
70 setVideoAvailable(
true);
75 connect(m_audioOutput->q, &QAudioOutput::deviceChanged,
77 connect(m_audioOutput->q, &QAudioOutput::volumeChanged,
78 this, &QWasmMediaPlayer::volumeChanged);
79 connect(m_audioOutput->q, &QAudioOutput::mutedChanged,
81 connect(m_audioOutput, &QWasmAudioOutput::bufferingChanged,
this,
82 &QWasmMediaPlayer::bufferingChanged);
84 connect( m_audioOutput, &QWasmAudioOutput::errorOccured,
this,
85 [=](qint32 code,
const QString &message ) {
86 error((QMediaPlayer::Error)code, message);
89 connect(m_audioOutput, &QWasmAudioOutput::progressChanged,
this,
90 &QWasmMediaPlayer::setPositionChanged);
91 connect(m_audioOutput, &QWasmAudioOutput::durationChanged,
this,
92 &QWasmMediaPlayer::setDurationChanged);
93 connect(m_audioOutput, &QWasmAudioOutput::statusChanged,
this,
94 &QWasmMediaPlayer::onMediaStatusChanged);
95 connect(m_audioOutput, &QWasmAudioOutput::stateChanged,
this,
97 setAudioAvailable(
true);
102 return m_videoOutput->getDuration();
107 if (mediaStatus() == QMediaPlayer::EndOfMedia)
110 if (m_videoAvailable)
111 return m_videoOutput->getCurrentPosition();
121 const int seekPosition = (position > INT_MAX) ? INT_MAX : position;
123 if (seekPosition ==
this->position())
126 if (mediaStatus() == QMediaPlayer::EndOfMedia)
127 setMediaStatus(QMediaPlayer::LoadedMedia);
129 if (m_videoAvailable)
130 return m_videoOutput->seekTo(position);
132 emit positionChanged(seekPosition);
140 if (m_videoAvailable)
141 m_videoOutput->setVolume(gain);
149 if (m_videoAvailable)
150 m_videoOutput->setMuted(muted);
155 return qBound(0.0, (m_bufferPercent * .01), 1.0);
160 return m_audioAvailable;
165 return m_videoAvailable;
170 return m_availablePlaybackRange;
176 const qint64 pos = position();
177 const qint64 end = (duration() / 100) * m_bufferPercent;
178 m_availablePlaybackRange.addInterval(pos, end);
180 m_availablePlaybackRange = QMediaTimeRange(0, duration());
182 m_availablePlaybackRange = QMediaTimeRange();
191 if (isVideoAvailable())
192 return m_videoOutput->playbackRate();
201 m_videoOutput->setPlaybackRate(rate);
202 emit playbackRateChanged(rate);
207 return m_mediaContent;
212 return m_mediaStream;
217 qCDebug(lcMediaPlayer) << Q_FUNC_INFO << mediaContent << stream;
220 if (mediaContent.isEmpty()) {
222 m_mediaStream = stream;
223 qCDebug(lcMediaPlayer) << db.mimeTypeForData(stream).name();
224 if (db.mimeTypeForData(stream).name().contains(u"audio"_s)) {
225 setAudioAvailable(
true);
226 m_audioOutput->setSource(m_mediaStream);
228 setVideoAvailable(
true);
229 m_videoOutput->setSource(m_mediaStream);
233 setMediaStatus(QMediaPlayer::NoMedia);
236 if (mediaContent.isLocalFile()) {
237 QString sourceFile = mediaContent.toLocalFile();
238 if (db.mimeTypeForFile(QFileInfo(sourceFile)).name().contains(u"audio"_s)) {
239 setAudioAvailable(
true);
240 m_audioOutput->setSource(mediaContent);
242 setVideoAvailable(
true);
243 m_videoOutput->setSource(mediaContent);
247 if (!m_videoOutput->currentVideoElement().isNull()) {
248 m_videoOutput->setSource(mediaContent);
249 setVideoAvailable(
true);
251 m_audioOutput->setSource(mediaContent);
252 setAudioAvailable(
true);
257 resetBufferingProgress();
262 if (m_videoSink == sink)
271 m_videoOutput->setSurface(sink);
272 setVideoAvailable(
true);
274 m_audioOutput->setVideoElement(m_videoOutput->currentVideoElement());
279 if (m_audioOutput == output)
283 m_audioOutput->q->disconnect(
this);
284 m_audioOutput =
static_cast<QWasmAudioOutput *>(output);
286 setAudioAvailable(
true);
292 m_audioOutput->setAudioDevice(m_audioOutput->q->device());
301 m_videoOutput->start();
302 m_playWhenReady =
true;
305 m_audioOutput->start();
309#ifdef DEBUG_AUDIOENGINE
310 QAudioEnginePrivate::checkNoError(
"play");
322 m_videoOutput->pause();
324 m_audioOutput->pause();
325 stateChanged(QMediaPlayer::PausedState);
331 m_playWhenReady =
false;
335 qWarning() << Q_FUNC_INFO << __LINE__;
340 m_videoOutput->stop();
342 m_audioOutput->stop();
349 return isVideoAvailable() && m_videoOutput->isVideoSeekable();
355 QMediaPlayer::Error error = QMediaPlayer::ResourceError;
358 case QWasmMediaNetworkState::NetworkEmpty:
360 case QWasmMediaNetworkState::NetworkIdle:
362 case QWasmMediaNetworkState::NetworkLoading:
364 case QWasmMediaNetworkState::NetworkNoSource:
365 error = QMediaPlayer::ResourceError;
366 errorString = message;
370 emit QPlatformMediaPlayer::error(error, errorString);
375 m_buffering = percent != 100;
376 m_bufferPercent = percent;
378 updateAvailablePlaybackRanges();
384 QSize newSize(width, height);
386 if (width == 0 || height == 0 || newSize == m_videoSize)
389 m_videoSize = newSize;
395 QMediaPlayer::PlaybackState m_mediaPlayerState;
397 case QWasmMediaPlayer::Started:
398 m_mediaPlayerState = QMediaPlayer::PlayingState;
400 case QWasmMediaPlayer::Paused:
401 m_mediaPlayerState = QMediaPlayer::PausedState;
403 case QWasmMediaPlayer::Stopped:
404 m_mediaPlayerState = QMediaPlayer::StoppedState;
407 m_mediaPlayerState = QMediaPlayer::StoppedState;
411 QPlatformMediaPlayer::stateChanged(m_mediaPlayerState);
423 QPlatformMediaPlayer::positionChanged(position);
428 QPlatformMediaPlayer::durationChanged(duration);
433 setVideoAvailable(ready);
435 if (m_playWhenReady && m_videoOutput->isReady())
441 mediaStatusChanged(status);
444 case QMediaPlayer::NoMedia:
445 case QMediaPlayer::InvalidMedia:
446 emit durationChanged(0);
448 case QMediaPlayer::EndOfMedia:
449 setPositionChanged(position());
457 if (m_audioAvailable == available)
460 m_audioAvailable = available;
461 emit audioAvailableChanged(m_audioAvailable);
466 if (m_videoAvailable == available)
470 m_videoSize = QSize();
472 m_videoAvailable = available;
473 emit videoAvailableChanged(m_videoAvailable);
480 m_availablePlaybackRange = QMediaTimeRange();
483void QWasmMediaPlayer::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
485 setMediaStatus(status);
495 seekableChanged(seekable);
500#include "moc_qwasmmediaplayer_p.cpp"
void seekableChanged(bool seekable)
void stateChanged(QWasmMediaPlayer::QWasmMediaPlayerState newState)
Combined button and popup list for selecting options.