15#ifndef QWASMVIDEOOUTPUT_H
16#define QWASMVIDEOOUTPUT_H
20#include <emscripten/val.h>
21#include <emscripten/html5.h>
23#include <QMediaPlayer>
25#include <QtMultimedia/qtvideo.h>
28#include "private/qwasmmediadevices_p.h"
31#include <private/qwasmjs_p.h>
33#include <QtCore/qloggingcategory.h>
35#include <private/qstdweb_p.h>
36#include <private/qwasmsuspendresumecontrol_p.h>
40Q_DECLARE_LOGGING_CATEGORY(qWasmMediaVideoOutput)
73 void seekTo(qint64 position);
88 void setHasAudio(
bool needsAudio) { m_hasAudio = needsAudio; }
98 m_video.isNull() || m_video.isUndefined() ? emscripten::val::null()
119 void checkNetworkState();
120 void playVideoElement();
121 void videoComputeFrame(
void *context);
122 void getDeviceSettings();
123 bool isPlatformiOs();
124 void detectIosCameraRotation();
125 void applyIosRotation(
int orientationIndex);
130 float m_requestedPosition = 0.0;
133 int getCurrentOrientationIndex();
136 bool m_isStopped =
false;
137 bool m_toBePaused =
false;
138 bool m_isSeeking =
false;
139 bool m_hasAudio =
false;
140 bool m_cameraIsReady =
false;
141 bool m_shouldBeStarted =
false;
142 bool m_streamStarted =
false;
143 bool m_isSeekable =
false;
144 bool m_useCameraRotation =
false;
146 QSize m_pendingVideoSize;
148 QMediaPlayer::MediaStatus m_currentMediaStatus;
149 qreal m_currentBufferedValue;
150 JsMediaInputStream *m_mediaInputStream =
nullptr;
152 QScopedPointer<QWasmEventHandler> m_timeUpdateEvent;
153 QScopedPointer<QWasmEventHandler> m_playEvent;
154 QScopedPointer<QWasmEventHandler> m_endedEvent;
155 QScopedPointer<QWasmEventHandler> m_durationChangeEvent;
156 QScopedPointer<QWasmEventHandler> m_loadedDataEvent;
157 QScopedPointer<QWasmEventHandler> m_errorChangeEvent;
158 QScopedPointer<QWasmEventHandler> m_resizeChangeEvent;
159 QScopedPointer<QWasmEventHandler> m_loadedMetadataChangeEvent;
160 QScopedPointer<QWasmEventHandler> m_loadStartChangeEvent;
161 QScopedPointer<QWasmEventHandler> m_canPlayChangeEvent;
162 QScopedPointer<QWasmEventHandler> m_canPlayThroughChangeEvent;
163 QScopedPointer<QWasmEventHandler> m_seekingChangeEvent;
164 QScopedPointer<QWasmEventHandler> m_seekedChangeEvent;
165 QScopedPointer<QWasmEventHandler> m_emptiedChangeEvent;
166 QScopedPointer<QWasmEventHandler> m_stalledChangeEvent;
167 QScopedPointer<QWasmEventHandler> m_waitingChangeEvent;
168 QScopedPointer<QWasmEventHandler> m_playingChangeEvent;
169 QScopedPointer<QWasmEventHandler> m_progressChangeEvent;
170 QScopedPointer<QWasmEventHandler> m_pauseChangeEvent;
171 QScopedPointer<QWasmEventHandler> m_beforeUnloadEvent;
173 std::string m_cameraId;
174 QMetaObject::Connection m_connection;
175 QSize m_videoResolution;
176 float m_minFrameRate = 0;
177 float m_maxFrameRate = 0;
178 float m_streamFrameRate = 0;
179 static bool orientationchangeCallback(
int eventType,
const EmscriptenOrientationChangeEvent *orientationChangeEvent,
void *userData);
QWasmVideoFrameGrabber(QWasmVideoOutput *videoOutput)
static QVideoFrameFormat::PixelFormat fromJsPixelFormat(std::string_view videoFormat)
void addCameraSourceElement(const std::string &id)
void updateVideoElementGeometry(const QRect &windowGeometry)
bool setDeviceSetting(const std::string &key, emscripten::val value)
void sizeChange(qint32 width, qint32 height)
emscripten::val surfaceElement()
void seekableChanged(bool seekable)
void durationChanged(qint64 duration)
emscripten::val getDeviceCapabilities()
void setVideoSize(const QSize &)
void setMuted(bool muted)
emscripten::val currentVideoElement()
void setSource(const QUrl &url)
void setVideoMode(QWasmVideoOutput::WasmVideoMode mode)
void bufferingChanged(qint32 percent)
void setVideoConstraints(QSize resolution, float minFrameRate, float maxFrameRate)
void seekTo(qint64 position)
void orientationChanged(int rotationIndex)
void setVolume(qreal volume)
void createVideoElement(const std::string &id)
void stateChanged(QWasmMediaPlayer::QWasmMediaPlayerState newState)
void setSurface(QVideoSink *surface)
void removeCurrentVideoElement()
void updateVideoElementSource(const QString &src)
std::string m_videoSurfaceId
void statusChanged(QMediaPlayer::MediaStatus status)
void progressChanged(qint32 position)
void errorOccured(qint32 code, const QString &message)
void doElementCallbacks()
void setSource(QIODevice *stream)
qint64 getCurrentPosition()
void setPlaybackRate(qreal rate)
void setHasAudio(bool needsAudio)
Combined button and popup list for selecting options.
EM_JS(void, em_texImage2DFromVideo,(const char *videoId, int *pW, int *pH), { var gl=GL.currentContext.GLctx;var video=document.getElementById(UTF8ToString(videoId));if(!video) { return;} var frame;try { frame=new VideoFrame(video);} catch(e) { return;} HEAP32[pW > > 2]=frame.displayWidth;HEAP32[pH > > 2]=frame.displayHeight;gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, frame);frame.close();})
EM_JS(EM_VAL, qt_st_sink_createWorkletNode,(EM_VAL ctxHandle, int callbackId, int channels), { var node=new AudioWorkletNode(Emval.toValue(ctxHandle), 'qt-audio-sink', { numberOfInputs:0, numberOfOutputs:1, outputChannelCount:[channels], processorOptions:{ channels:channels } });node.port.onmessage=function() { Module._qt_sinkDeliverData(callbackId);};return Emval.toHandle(node);})