Better_Software_Header_Mobile Better_Software_Header_Web

Find what you need - explore our website and developer resources

Qt 6 WASM: Uploading & Playing Back Audio Files

Adapting to the limitations of the web platform and Qt Multimedia

#pragma once

#include <qmainwindow>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr) noexcept;
    ~MainWindow() override;
};
connect(dialogButton, &QPushButton::clicked, this, [this]() {
    QFileDialog::getOpenFileContent(
        tr("Audio files (*.mp3 *.flac *.wav *.aiff *.ogg)"),
        [this](const QString &fileName, const QByteArray &fileContent) {
            if (fileName.isEmpty()) {
                // no file selected
            } else {
                // do stuff with file data
            }
        });
});
QFileDialog::getOpenFileContent(
    tr("Audio files (*.mp3 *.flac *.wav *.aiff *.ogg)"),
    [this](const QString &fileName, const QByteArray &fileContent) {
        if (fileName.isEmpty()) {
            // no file selected
        } else {
            auto contentCopy = fileContent;
            auto buf = contentCopy.toEcmaUint8Array();
            // ...
            // ...
            // ...
        }
    });
mAudioContext = emscripten::val::global("AudioContext").new_();
MainWindow::MainWindow(QWidget *parent) noexcept
    : QMainWindow(parent)
    , mAudioContext(emscripten::val::global("AudioContext").new_())
{
    // ...
    // ...
    // ...
}
auto contentCopy = fileContent;
auto buf = contentCopy.toEcmaUint8Array();
auto decodedBuffer = mAudioContext.call<emscripten::val>("decodeAudioData", /* arguments */);
auto decodedBuffer = mAudioContext.call<emscripten::val>("decodeAudioData", buf["buffer"]).await();
target_link_options(<target name> PUBLIC -sASYNCIFY -O3)
QFileDialog::getOpenFileContent(
    tr("Audio files (*.mp3 *.flac *.wav *.aiff *.ogg)"),
    [this](const QString &fileName, const QByteArray &fileContent) {
        if (fileName.isEmpty()) {
            // no file selected
        } else {
            auto contentCopy = fileContent;
            auto buf = contentCopy.toEcmaUint8Array();

            mDecodedBuffer = mAudioContext.call<emscripten::val>("decodeAudioData", buf["buffer"]).await();
        }
    });
auto source = mAudioContext.call<emscripten::val>("createBufferSource");
source.set("buffer", mDecodedBuffer);
source.call<void>("connect", mAudioContext["destination"]);
source.call<void>("start");
connect(playButton, &QPushButton::clicked, this, [this]() {
    auto source = mAudioContext.call<emscripten::val>("createBufferSource");
    source.set("buffer", mDecodedBuffer);
    source.call<void>("connect", mAudioContext["destination"]);
    source.call<void>("start");
});
#pragma once

#include <QMainWindow>
#include <emscripten/bind.h>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr) noexcept;
    ~MainWindow() override;

signals:
    void notReady();
    void readyToPlay();

private:
    emscripten::val mAudioContext;
    emscripten::val mDecodedBuffer;
};
#include "mainwindow.h"

#include <QFileDialog>
#include <QHBoxLayout>
#include <QPushButton>

MainWindow::MainWindow(QWidget *parent) noexcept
    : QMainWindow(parent)
    , mAudioContext(emscripten::val::global("AudioContext").new_())
{
    auto *centerWidget = new QWidget(this);
    auto *layout = new QHBoxLayout(centerWidget);

    auto *dialogButton = new QPushButton(centerWidget);
    dialogButton->setText(tr("Choose file"));

    auto *playButton = new QPushButton(centerWidget);
    playButton->setText(tr("Play"));
    playButton->setEnabled(false);

    layout->addWidget(dialogButton);
    layout->addWidget(playButton);
    centerWidget->setLayout(layout);
    setCentralWidget(centerWidget);

    connect(dialogButton, &QPushButton::clicked, this, [this]() {
        QFileDialog::getOpenFileContent(
            tr("Audio files (*.mp3 *.flac *.wav *.aiff *.ogg)"),
            [this](const QString &fileName, const QByteArray &fileContent) {
                if (fileName.isEmpty()) {
                    emscripten::val::global().call<void>(
                        "alert", std::string("no file selected"));
                } else {
                    emit notReady();

                    auto contentCopy = fileContent;
                    auto buf = contentCopy.toEcmaUint8Array();

                    mDecodedBuffer = mAudioContext.call<emscripten::val>("decodeAudioData", buf["buffer"]).await();

                    emit readyToPlay();
                }
            });
    });

    connect(playButton, &QPushButton::clicked, this, [this]() {
        auto source = mAudioContext.call<emscripten::val>("createBufferSource");
        source.set("buffer", mDecodedBuffer);
        source.call<void>("connect", mAudioContext["destination"]);
        source.call<void>("start");
    });

    connect(this, &MainWindow::notReady, this, [playButton]() {
        if (playButton->isEnabled())
            playButton->setEnabled(false);
    });

    connect(this, &MainWindow::readyToPlay, this, [playButton]() {
        if (!playButton->isEnabled())
            playButton->setEnabled(true);
    });
}

MainWindow::~MainWindow() = default;

Tags:

c++qmlqt

About KDAB

1 Comment

6 - Jan - 2025

Glen Mabey