20 qCDebug(qWasmMediaVideoOutput) << Q_FUNC_INFO;
24 auto timeUpdateCallback = [=](emscripten::val event) {
25 qCDebug(qWasmMediaVideoOutput) <<
"timeupdate";
28 emit progressChanged(event[
"target"][
"currentTime"].as<
double>() * 1000);
30 m_timeUpdateEvent.reset(
new QWasmEventHandler(m_video,
"timeupdate", timeUpdateCallback));
33 auto playCallback = [=](emscripten::val event) {
35 qCDebug(qWasmMediaVideoOutput) <<
"play" << m_video[
"src"].as<std::string>();
39 m_playEvent.reset(
new QWasmEventHandler(m_video,
"play", playCallback));
42 auto endedCallback = [=](emscripten::val event) {
44 qCDebug(qWasmMediaVideoOutput) <<
"ended";
45 m_currentMediaStatus = MediaStatus::EndOfMedia;
46 emit statusChanged(m_currentMediaStatus);
48 m_endedEvent.reset(
new QWasmEventHandler(m_video,
"ended", endedCallback));
51 auto durationChangeCallback = [=](emscripten::val event) {
52 qCDebug(qWasmMediaVideoOutput) <<
"durationChange";
55 qint64 dur = event[
"target"][
"duration"].as<
double>() * 1000;
56 emit durationChanged(dur);
58 m_durationChangeEvent.reset(
59 new QWasmEventHandler(m_video,
"durationchange", durationChangeCallback));
62 auto loadedDataCallback = [=](emscripten::val event) {
64 qCDebug(qWasmMediaVideoOutput) <<
"loaded data";
69 emit seekableChanged(m_isSeekable);
72 m_loadedDataEvent.reset(
new QWasmEventHandler(m_video,
"loadeddata", loadedDataCallback));
75 auto errorCallback = [=](emscripten::val event) {
76 qCDebug(qWasmMediaVideoOutput) <<
"error";
77 if (event.isUndefined() || event.isNull())
79 emit errorOccured(m_video[
"error"][
"code"].as<
int>(),
80 QString::fromStdString(m_video[
"error"][
"message"].as<std::string>()));
82 m_errorChangeEvent.reset(
new QWasmEventHandler(m_video,
"error", errorCallback));
85 auto resizeCallback = [=](emscripten::val event) {
87 qCDebug(qWasmMediaVideoOutput) <<
"resize";
89 updateVideoElementGeometry(
90 QRect(0, 0, m_video[
"videoWidth"].as<
int>(), m_video[
"videoHeight"].as<
int>()));
91 emit sizeChange(m_video[
"videoWidth"].as<
int>(), m_video[
"videoHeight"].as<
int>());
94 m_resizeChangeEvent.reset(
new QWasmEventHandler(m_video,
"resize", resizeCallback));
97 auto loadedMetadataCallback = [=](emscripten::val event) {
99 qCDebug(qWasmMediaVideoOutput) <<
"loaded meta data";
101 emit metaDataLoaded();
103 m_loadedMetadataChangeEvent.reset(
104 new QWasmEventHandler(m_video,
"loadedmetadata", loadedMetadataCallback));
107 auto loadStartCallback = [=](emscripten::val event) {
109 qCDebug(qWasmMediaVideoOutput) <<
"load started";
110 m_currentMediaStatus = MediaStatus::LoadingMedia;
111 emit statusChanged(m_currentMediaStatus);
114 m_loadStartChangeEvent.reset(
new QWasmEventHandler(m_video,
"loadstart", loadStartCallback));
118 auto canPlayCallback = [=](emscripten::val event) {
119 if (event.isUndefined() || event.isNull())
121 qCDebug(qWasmMediaVideoOutput) <<
"can play"
122 <<
"m_requestedPosition" << m_requestedPosition;
125 emit readyChanged(
true);
127 m_canPlayChangeEvent.reset(
new QWasmEventHandler(m_video,
"canplay", canPlayCallback));
130 auto canPlayThroughCallback = [=](emscripten::val event) {
132 qCDebug(qWasmMediaVideoOutput) <<
"can play through"
133 <<
"m_isStopped" << m_isStopped;
135 if (m_currentMediaStatus == MediaStatus::EndOfMedia)
138 if (m_isSeekable != seekable) {
139 m_isSeekable = seekable;
140 emit seekableChanged(m_isSeekable);
142 if (!m_isSeeking && !m_isStopped) {
143 emscripten::val timeRanges = m_video[
"buffered"];
144 if ((!timeRanges.isNull() || !timeRanges.isUndefined())
145 && timeRanges[
"length"].as<
int>() == 1) {
146 double buffered = m_video[
"buffered"].call<emscripten::val>(
"end", 0).as<
double>();
147 const double duration = m_video[
"duration"].as<
double>();
149 if (duration == buffered) {
150 m_currentBufferedValue = 100;
151 emit bufferingChanged(m_currentBufferedValue);
154 constexpr int hasEnoughData = 4;
155 if (m_video[
"readyState"].as<
int>() == hasEnoughData) {
156 m_currentMediaStatus = MediaStatus::LoadedMedia;
157 emit statusChanged(m_currentMediaStatus);
158 m_frameGrabber.startFrameLoop();
164 m_canPlayThroughChangeEvent.reset(
165 new QWasmEventHandler(m_video,
"canplaythrough", canPlayThroughCallback));
168 auto seekingCallback = [=](emscripten::val event) {
170 qCDebug(qWasmMediaVideoOutput)
171 <<
"seeking started" << (m_video[
"currentTime"].as<
double>() * 1000);
174 m_seekingChangeEvent.reset(
new QWasmEventHandler(m_video,
"seeking", seekingCallback));
177 auto seekedCallback = [=](emscripten::val event) {
179 qCDebug(qWasmMediaVideoOutput) <<
"seeked" << (m_video[
"currentTime"].as<
double>() * 1000);
180 emit progressChanged(m_video[
"currentTime"].as<
double>() * 1000);
183 m_seekedChangeEvent.reset(
new QWasmEventHandler(m_video,
"seeked", seekedCallback));
186 auto emptiedCallback = [=](emscripten::val event) {
188 qCDebug(qWasmMediaVideoOutput) <<
"emptied";
189 emit readyChanged(
false);
190 m_currentMediaStatus = MediaStatus::EndOfMedia;
191 emit statusChanged(m_currentMediaStatus);
193 m_emptiedChangeEvent.reset(
new QWasmEventHandler(m_video,
"emptied", emptiedCallback));
196 auto stalledCallback = [=](emscripten::val event) {
198 qCDebug(qWasmMediaVideoOutput) <<
"stalled";
199 m_currentMediaStatus = MediaStatus::StalledMedia;
200 emit statusChanged(m_currentMediaStatus);
202 m_stalledChangeEvent.reset(
new QWasmEventHandler(m_video,
"stalled", stalledCallback));
205 auto waitingCallback = [=](emscripten::val event) {
208 qCDebug(qWasmMediaVideoOutput) <<
"waiting";
211 m_waitingChangeEvent.reset(
new QWasmEventHandler(m_video,
"waiting", waitingCallback));
216 auto playingCallback = [=](emscripten::val event) {
218 qCDebug(qWasmMediaVideoOutput) <<
"playing";
223 m_toBePaused =
false;
224 m_frameGrabber.startFrameLoop();
227 m_playingChangeEvent.reset(
new QWasmEventHandler(m_video,
"playing", playingCallback));
230 auto progesssCallback = [=](emscripten::val event) {
231 if (event.isUndefined() || event.isNull())
234 const double duration = event[
"target"][
"duration"].as<
double>();
238 emscripten::val timeRanges = event[
"target"][
"buffered"];
240 if ((!timeRanges.isNull() || !timeRanges.isUndefined())
241 && timeRanges[
"length"].as<
int>() == 1) {
242 emscripten::val dVal = timeRanges.call<emscripten::val>(
"end", 0);
243 if (!dVal.isNull() || !dVal.isUndefined()) {
244 double bufferedEnd = dVal.as<
double>();
246 if (duration > 0 && bufferedEnd > 0) {
247 const double bufferedValue = (bufferedEnd / duration * 100);
248 qCDebug(qWasmMediaVideoOutput) <<
"progress buffered";
249 m_currentBufferedValue = bufferedValue;
250 emit bufferingChanged(m_currentBufferedValue);
251 if (bufferedEnd == duration)
252 m_currentMediaStatus = MediaStatus::BufferedMedia;
254 m_currentMediaStatus = MediaStatus::BufferingMedia;
255 emit statusChanged(m_currentMediaStatus);
260 m_progressChangeEvent.reset(
new QWasmEventHandler(m_video,
"progress", progesssCallback));
263 auto pauseCallback = [=](emscripten::val event) {
265 qCDebug(qWasmMediaVideoOutput) <<
"pause";
267 const double currentTime = m_video[
"currentTime"].as<
double>();
268 const double duration = m_video[
"duration"].as<
double>();
269 if ((currentTime > 0 && currentTime < duration) && (!m_isStopped)) {
273 m_video.set(
"currentTime", emscripten::val(0));
277 m_pauseChangeEvent.reset(
new QWasmEventHandler(m_video,
"pause", pauseCallback));
282 emscripten::val window = emscripten::val::global(
"window");
284 auto beforeUnloadCallback = [=](emscripten::val event) {
288 m_video.call<
void>(
"removeAttribute", emscripten::val(
"src"));
289 m_video.call<
void>(
"load");
291 m_beforeUnloadEvent.reset(
new QWasmEventHandler(window,
"beforeunload", beforeUnloadCallback));