9#include <QMimeDatabase>
10#include <QtCore/qloggingcategory.h>
11#include <QMediaDevices>
14#include <QMimeDatabase>
36 if (m_audio.isUndefined() || m_audio.isNull()) {
37 qCDebug(qWasmMediaAudioOutput) <<
"Error"
38 <<
"Audio element could not be created";
43 m_audio.set(
"mute",
muted);
48 if (m_audio.isUndefined() || m_audio.isNull()) {
49 qCDebug(qWasmMediaAudioOutput) <<
"Error"
50 <<
"Audio element could not be created";
56 m_audio.set(
"volume",
volume);
69 if (m_audio.isUndefined() || m_audio.isNull()) {
70 qCDebug(qWasmMediaAudioOutput) <<
"Error"
71 <<
"Audio element could not be created";
77 emscripten::val document = emscripten::val::global(
"document");
78 emscripten::val body = document[
"body"];
82 body.call<
void>(
"appendChild", m_audio);
86 qCDebug(qWasmMediaAudioOutput) <<
"is localfile";
89 QFile mediaFile(m_source);
91 qCDebug(qWasmMediaAudioOutput) <<
"Error"
92 <<
"Media file could not be opened";
105 emscripten::val contentUrl =
108 emscripten::val audioSourceElement =
109 document.call<emscripten::val>(
"createElement", std::string(
"source"));
111 audioSourceElement.set(
"src", contentUrl);
117 audioSourceElement.set(
"type",
mimeType.name().toStdString());
118 m_audio.call<
void>(
"appendChild", audioSourceElement);
120 m_audio.call<
void>(
"setAttribute", emscripten::val(
"srcObject"), contentUrl);
128 body.call<
void>(
"appendChild", m_audio);
131 doElementCallbacks();
141 if (m_audio.isNull() || m_audio.isUndefined()) {
142 qCDebug(qWasmMediaAudioOutput) <<
"audio failed to start";
148 m_audio.call<
void>(
"play");
153 if (m_audio.isNull() || m_audio.isUndefined()) {
154 qCDebug(qWasmMediaAudioOutput) <<
"audio failed to start";
161 m_audio.set(
"currentTime", emscripten::val(0));
163 if (m_audioIODevice) {
164 m_audioIODevice->
close();
165 delete m_audioIODevice;
172 if (m_audio.isNull() || m_audio.isUndefined()) {
173 qCDebug(qWasmMediaAudioOutput) <<
"audio failed to start";
178 m_audio.call<emscripten::val>(
"pause");
181void QWasmAudioOutput::createAudioElement(
const std::string &
id)
183 emscripten::val document = emscripten::val::global(
"document");
184 m_audio = document.call<emscripten::val>(
"createElement", std::string(
"audio"));
190 if (!m_audio.hasOwnProperty(
"sinkId") || m_audio[
"sinkId"].isUndefined()) {
194 std::string usableId =
id;
195 if (usableId.empty())
199 .
thenFunc = [](emscripten::val) {
qCWarning(qWasmMediaAudioOutput) <<
"setSinkId ok"; },
201 [](emscripten::val) {
202 qCWarning(qWasmMediaAudioOutput) <<
"Error while trying to setSinkId";
207 m_audio.set(
"id", usableId.c_str());
210void QWasmAudioOutput::doElementCallbacks()
213 auto errorCallback = [&](emscripten::val
event) {
214 qCDebug(qWasmMediaAudioOutput) <<
"error";
223 switch (m_audio[
"error"][
"code"].as<int>()) {
245 auto loadedDataCallback = [&](emscripten::val
event) {
247 qCDebug(qWasmMediaAudioOutput) <<
"loaded data";
248 qstdweb::window()[
"URL"].call<emscripten::val>(
"revokeObjectURL", m_audio[
"src"]);
253 auto canPlayCallback = [&](emscripten::val
event) {
254 if (
event.isUndefined() ||
event.isNull())
256 qCDebug(qWasmMediaAudioOutput) <<
"can play";
263 auto canPlayThroughCallback = [&](emscripten::val
event) {
267 m_canPlayThroughChangeEvent.
reset(
271 auto playCallback = [&](emscripten::val
event) {
273 qCDebug(qWasmMediaAudioOutput) <<
"play";
279 auto durationChangeCallback = [&](emscripten::val
event) {
280 qCDebug(qWasmMediaAudioOutput) <<
"durationChange";
285 m_durationChangeEvent.
reset(
289 auto endedCallback = [&](emscripten::val
event) {
291 qCDebug(qWasmMediaAudioOutput) <<
"ended";
298 auto progesssCallback = [&](emscripten::val
event) {
299 if (
event.isUndefined() ||
event.isNull())
301 qCDebug(qWasmMediaAudioOutput) <<
"progress";
302 float duration =
event[
"target"][
"duration"].as<
int>();
306 emscripten::val timeRanges =
event[
"target"][
"buffered"];
308 if ((!timeRanges.isNull() || !timeRanges.isUndefined())
309 && timeRanges[
"length"].as<
int>() == 1) {
310 emscripten::val dVal = timeRanges.call<emscripten::val>(
"end", 0);
312 if (!dVal.isNull() || !dVal.isUndefined()) {
313 double bufferedEnd = dVal.as<
double>();
315 if (duration > 0 && bufferedEnd > 0) {
316 float bufferedValue = (bufferedEnd / duration * 100);
317 qCDebug(qWasmMediaAudioOutput) <<
"progress buffered" << bufferedValue;
320 if (bufferedEnd == duration)
333 auto timeUpdateCallback = [&](emscripten::val
event) {
335 <<
"timeupdate" << (
event[
"target"][
"currentTime"].as<
double>() * 1000);
343 auto pauseCallback = [&](emscripten::val
event) {
345 qCDebug(qWasmMediaAudioOutput) <<
"pause";
347 int currentTime = m_audio[
"currentTime"].as<
int>();
348 int duration = m_audio[
"duration"].as<
int>();
The QAudioDevice class provides an information about audio devices and their functionality.
QByteArray id
\qmlproperty string QtMultimedia::audioDevice::id
\qmltype AudioOutput \instantiates QAudioOutput
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
std::string toStdString() const
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
\inmodule QtCore \reentrant
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
\inmodule QtCore \reentrant
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
virtual void close()
First emits aboutToClose(), then closes the device and sets its OpenMode to NotOpen.
QMimeType mimeTypeForData(const QByteArray &data) const
Returns a MIME type for data.
QMimeType mimeTypeForFile(const QString &fileName, MatchMode mode=MatchDefault) const
Returns a MIME type for the file named fileName using mode.
QString name
the name of the MIME type
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromStdString(const std::string &s)
std::string toStdString() const
Returns a std::string object with the data contained in this QString.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
void progressChanged(qint32 position)
void bufferingChanged(qint32 percent)
void errorOccured(qint32 code, const QString &message)
void setMuted(bool muted) override
void stateChanged(QWasmMediaPlayer::QWasmMediaPlayerState newState)
void statusChanged(QMediaPlayer::MediaStatus status)
@ MEDIA_ERR_SRC_NOT_SUPPORTED
void durationChanged(qint64 duration)
void setVolume(float volume) override
void setAudioDevice(const QAudioDevice &device) final
void setSource(const QUrl &url)
static Blob copyFrom(const char *buffer, uint32_t size, std::string mimeType)
Combined button and popup list for selecting options.
void make(emscripten::val target, QString methodName, PromiseCallbacks callbacks, Args... args)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qBound(const T &min, const T &val, const T &max)
#define QStringLiteral(str)
static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &errorSource, qsizetype errorPosition)
static double currentTime()
QFileInfo info(fileName)
[8]
QUrl url("example.com")
[constructor-url-reference]
std::function< void(emscripten::val)> thenFunc
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent