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->updateVideoElementGeometry(QRect(0, 0, 1280, 720));
45 connect(m_videoOutput, &QWasmVideoOutput::bufferingChanged,
this,
46 &QWasmMediaPlayer::bufferingChanged);
47 connect(m_videoOutput, &QWasmVideoOutput::errorOccured,
this,
48 [=](qint32 code,
const QString &message ) {
49 error((QMediaPlayer::Error)code, message);
54 connect(m_videoOutput, &QWasmVideoOutput::progressChanged,
this,
55 &QWasmMediaPlayer::setPositionChanged);
56 connect(m_videoOutput, &QWasmVideoOutput::durationChanged,
this,
57 &QWasmMediaPlayer::setDurationChanged);
58 connect(m_videoOutput, &QWasmVideoOutput::sizeChange,
this,
59 &QWasmMediaPlayer::videoSizeChanged);
60 connect(m_videoOutput, &QWasmVideoOutput::readyChanged,
this,
62 connect(m_videoOutput, &QWasmVideoOutput::statusChanged,
this,
63 &QWasmMediaPlayer::onMediaStatusChanged);
69 setVideoAvailable(
true);
77 connect(m_audioOutput->q, &QAudioOutput::deviceChanged,
79 connect(m_audioOutput->q, &QAudioOutput::volumeChanged,
80 this, &QWasmMediaPlayer::volumeChanged);
81 connect(m_audioOutput->q, &QAudioOutput::mutedChanged,
83 connect(m_audioOutput, &QWasmAudioOutput::bufferingChanged,
this,
84 &QWasmMediaPlayer::bufferingChanged);
86 connect( m_audioOutput, &QWasmAudioOutput::errorOccured,
this,
87 [=](qint32 code,
const QString &message ) {
88 error((QMediaPlayer::Error)code, message);
91 connect(m_audioOutput, &QWasmAudioOutput::progressChanged,
this,
92 &QWasmMediaPlayer::setPositionChanged);
93 connect(m_audioOutput, &QWasmAudioOutput::durationChanged,
this,
94 &QWasmMediaPlayer::setDurationChanged);
95 connect(m_audioOutput, &QWasmAudioOutput::statusChanged,
this,
96 &QWasmMediaPlayer::onMediaStatusChanged);
97 connect(m_audioOutput, &QWasmAudioOutput::stateChanged,
this,
99 setAudioAvailable(
true);
104 return m_videoOutput->getDuration();
109 if (mediaStatus() == QMediaPlayer::EndOfMedia)
112 if (m_videoAvailable)
113 return m_videoOutput->getCurrentPosition();
123 const int seekPosition = (position > INT_MAX) ? INT_MAX : position;
125 if (seekPosition ==
this->position())
128 if (mediaStatus() == QMediaPlayer::EndOfMedia)
129 setMediaStatus(QMediaPlayer::LoadedMedia);
131 if (m_videoAvailable)
132 return m_videoOutput->seekTo(position);
134 emit positionChanged(seekPosition);
142 if (m_videoAvailable)
143 m_videoOutput->setVolume(gain);
151 if (m_videoAvailable)
152 m_videoOutput->setMuted(muted);
157 return qBound(0.0, (m_bufferPercent * .01), 1.0);
162 return m_audioAvailable;
167 return m_videoAvailable;
172 return m_availablePlaybackRange;
178 const qint64 pos = position();
179 const qint64 end = (duration() / 100) * m_bufferPercent;
180 m_availablePlaybackRange.addInterval(pos, end);
182 m_availablePlaybackRange = QMediaTimeRange(0, duration());
184 m_availablePlaybackRange = QMediaTimeRange();
193 if (isVideoAvailable())
194 return m_videoOutput->playbackRate();
203 m_videoOutput->setPlaybackRate(rate);
204 emit playbackRateChanged(rate);
209 return m_mediaContent;
214 return m_mediaStream;
219 qCDebug(lcMediaPlayer) << Q_FUNC_INFO << mediaContent << stream;
222 if (mediaContent.isEmpty()) {
224 m_mediaStream = stream;
225 qCDebug(lcMediaPlayer) << db.mimeTypeForData(stream).name();
226 if (db.mimeTypeForData(stream).name().contains(u"audio"_s)) {
227 setAudioAvailable(
true);
228 m_audioOutput->setSource(m_mediaStream);
230 setVideoAvailable(
true);
231 m_videoOutput->setSource(m_mediaStream);
235 setMediaStatus(QMediaPlayer::NoMedia);
238 if (mediaContent.isLocalFile()) {
239 QString sourceFile = mediaContent.toLocalFile();
240 if (db.mimeTypeForFile(QFileInfo(sourceFile)).name().contains(u"audio"_s)) {
241 setAudioAvailable(
true);
242 m_audioOutput->setSource(mediaContent);
244 setVideoAvailable(
true);
245 m_videoOutput->setSource(mediaContent);
249 if (!m_videoOutput->currentVideoElement().isNull()) {
250 m_videoOutput->setSource(mediaContent);
251 setVideoAvailable(
true);
253 m_audioOutput->setSource(mediaContent);
254 setAudioAvailable(
true);
259 resetBufferingProgress();
264 if (m_videoSink == sink)
273 m_videoOutput->setSurface(sink);
274 setVideoAvailable(
true);
276 m_audioOutput->setVideoElement(m_videoOutput->currentVideoElement());
281 if (m_audioOutput == output)
285 m_audioOutput->q->disconnect(
this);
286 m_audioOutput =
static_cast<QWasmAudioOutput *>(output);
288 setAudioAvailable(
true);
294 m_audioOutput->setAudioDevice(m_audioOutput->q->device());
303 m_videoOutput->start();
304 m_playWhenReady =
true;
307 m_audioOutput->start();
311#ifdef DEBUG_AUDIOENGINE
312 QAudioEnginePrivate::checkNoError(
"play");
324 m_videoOutput->pause();
326 m_audioOutput->pause();
327 stateChanged(QMediaPlayer::PausedState);
333 m_playWhenReady =
false;
341 m_videoOutput->stop();
343 m_audioOutput->stop();
350 return isVideoAvailable() && m_videoOutput->isVideoSeekable();
356 QMediaPlayer::Error error = QMediaPlayer::ResourceError;
359 case QWasmMediaNetworkState::NetworkEmpty:
361 case QWasmMediaNetworkState::NetworkIdle:
363 case QWasmMediaNetworkState::NetworkLoading:
365 case QWasmMediaNetworkState::NetworkNoSource:
366 error = QMediaPlayer::ResourceError;
367 errorString = message;
371 emit QPlatformMediaPlayer::error(error, errorString);
376 m_buffering = percent != 100;
377 m_bufferPercent = percent;
379 updateAvailablePlaybackRanges();
385 QSize newSize(width, height);
387 if (width == 0 || height == 0 || newSize == m_videoSize)
390 m_videoSize = newSize;
396 QMediaPlayer::PlaybackState m_mediaPlayerState;
398 case QWasmMediaPlayer::Started:
399 m_mediaPlayerState = QMediaPlayer::PlayingState;
401 case QWasmMediaPlayer::Paused:
402 m_mediaPlayerState = QMediaPlayer::PausedState;
404 case QWasmMediaPlayer::Stopped:
405 m_mediaPlayerState = QMediaPlayer::StoppedState;
408 m_mediaPlayerState = QMediaPlayer::StoppedState;
412 QPlatformMediaPlayer::stateChanged(m_mediaPlayerState);
424 QPlatformMediaPlayer::positionChanged(position);
429 QPlatformMediaPlayer::durationChanged(duration);
434 setVideoAvailable(ready);
436 if (m_playWhenReady && m_videoOutput->isReady())
442 mediaStatusChanged(status);
445 case QMediaPlayer::NoMedia:
446 case QMediaPlayer::InvalidMedia:
447 emit durationChanged(0);
449 case QMediaPlayer::EndOfMedia:
450 setPositionChanged(position());
458 if (m_audioAvailable == available)
461 m_audioAvailable = available;
462 emit audioAvailableChanged(m_audioAvailable);
467 if (m_videoAvailable == available)
471 m_videoSize = QSize();
473 m_videoAvailable = available;
474 emit videoAvailableChanged(m_videoAvailable);
481 m_availablePlaybackRange = QMediaTimeRange();
484void QWasmMediaPlayer::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
486 setMediaStatus(status);
496 seekableChanged(seekable);
501#include "moc_qwasmmediaplayer_p.cpp"
void seekableChanged(bool seekable)
void stateChanged(QWasmMediaPlayer::QWasmMediaPlayerState newState)
Combined button and popup list for selecting options.