Hi, Iโ€™m trying to create a KMP module for audio pr...
# javascript
o
Hi, Iโ€™m trying to create a KMP module for audio processing and want to split the processor code into a separate JS file, similar to this example: // script.js
await audioContext.audioWorklet.addModule("hiss-generator.js");
// hiss-generator.js
registerProcessor("hiss-generator", HissGeneratorProcessor);
I tried to creating the processor in another module with:
Copy code
// processor/build.gradle.kts
commonWebpackConfig {
    outputFileName = "audio-processor.js"
}
But when I add it as a dependency to the app,
audio-processor.js
isnโ€™t included in the
dist
output. What am I missing?
t
Do you use Kotlin Warappers?
o
yep, currently I do it like in this example:
Copy code
context.audioWorklet.addModule(blobUrl)
where the blobUrl is raw JS string, but Iโ€™d prefer to write it in Kotlin.
t
We already support
Worker
creation without separate subproject creation - example.
AFAIK Webpack doesn't support worklet modules without loaders ๐Ÿ˜ž
We can support worklet modules, but they will work only with Vite bundler (recommended).
Could you please create issue? I will add example of worklet creation
o
sure, Thanks! So, what do you think is the best approach right now? Do you have any examples on how to set it up?
t
It will be something like this:
Copy code
// MyAydioWorkletModule.kt
val MyAydioWorkletModule = AudioWorkletModule {
    // this - AudioWorkletGlobalScope
}

// App.kt
audioContext.audioWorklet.addModule(MyAydioWorkletModule)
All additional magic Vite and Seskar will do ๐Ÿ˜‰
o
Too good to be true ๐Ÿ˜…. BTW the issue has been created.
thank you color 1
t
Please add links on JS examples in issue
๐Ÿ‘Œ 1
o
I saw AudioWorkletModule was merged and released โ€” is it ready to go?
t
I added MDN example here. Compiler plugin support - next (final) step. Hope it will be ready this week ๐Ÿ˜‰
kodee happy 1
In any case I will write in this thread when it will be ready.
Example in Seskar works!
๐ŸŽ‰ 1
Plugin will be released later
Plugin released.
d
๐Ÿ‘‹ I configured Seskar on one of my project to use an audio worklet. Using
./gradlew jsViteDev
, it's working: the worklet is loaded in the browser and it's working as expected. (it's loading the *.mjs audio module) But I was not able to make it work using the task
jsBundleProduction
: the audio worklet is not created. When updating the vite configuration to use the Audio Worklet as entry point
Copy code
rollupOptions: {
            input: {
                // HTML entry point - relative to root (kotlin directory)
                main: resolve(__dirname, 'kotlin/index.html'),
                // Audio worklet entry point (will be bundled separately)
                'audio-worklet': resolve(__dirname, 'kotlin/HissGeneratorWorkletModule__worklet__module.mjs')
            },
}
It's not working also as it generated a base64 string of the mjs file (without resolving its dependencies.) I tried the same thing using this test from seskar and use the same command: the audio worklet is not generated also using
./gradlew jsBundleProduction
. (see
build/dist/js/production
) is the audio worklet can be bundled using vite and
./gradlew jsBundleProduction
? I do believe that it's a configuration issue with vite so it can generate the right bundle with the audio worklet. But as a fresh user of vite, I'm bit lost at the moment. Could you point me what to do to fix this issue? thanks ๐Ÿ™‚
t
Do you use NPM dependencies inside worklet?
d
i don't use any
npm
dependencies in my project. If I decode the base64 string from the generated audio worklet javascript file, I can see import of mjs files: (example below)
Copy code
import { Unit_instance1fbcbse1fwigr as Unit_instance } from '../kotlin-kotlin-stdlib/kotlin/Unit.mjs';
But as files are bundle, there is no
mjs
to download. You can reproduce the issue by using this
vite.config.mjs
with the seskar example.
Copy code
import { defineConfig } from 'vite'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'

const __dirname = dirname(fileURLToPath(import.meta.url))

export default defineConfig({
    root: "kotlin",
    build: {
        rollupOptions: {
            input: {
                // HTML entry point - relative to root (kotlin directory)
                 main: resolve(__dirname, 'kotlin/index.html'),
                'audio-worklet': resolve(__dirname, 'kotlin/mdn-audioworklet-example/mdn/audioworklet/example/HissGeneratorWorkletModule__worklet__module.mjs'),
            },
        }
    }
})
By using the command:
./gradlew jsBrowserProductionVite --rerun-tasks
, The
audio-worklet.js
in
seskar/tests/worklets/mdn-audioworklet-example/build/dist/js/production
will contains a base64 string to be decoded by the javascript code. If i'm serving the content of this directory (
python3 -m http.server 8000
) the page is not working and crash when playing an audio because
Failed to resolve module specifier "./HissGeneratorParameters.mjs"
. Am I doing something wrong? ๐Ÿค”
t
Looks like Vite configuration problem. It doesn't process audio worklet for some reason. At the same moment worker processing works as expected.
d
Thanks! Iโ€™ll investigate Vite with audio worklet then :) (wish me luck ๐Ÿ˜‚)
t
Looks like fake
Worker
class can be used as workaround
Are you familiar with
includeBuild
? ๐Ÿ˜‰
d
yes. But I would like to avoid as a fix to this issue. (But I'm very ok to test a fix for this issue)
t
Workaround will be hidden inside plugin ;)
Workaround with Worker add
importScripts
(and fail worklet)
I pushed "Fake worker" workaround for worklets
Could you please check (with
includeBuild
) if it work's for you?
https
server required for check
d
I tried to generate the worklet: It seems to work (the js file is created and loaded by the browser) I need more work on my project to fully test the audio worklet. So I test with the seskar example: โ€ข the worklet is generated โ€ข the worklet is loaded by the browser. โ€ข I put a console.log in the worklet: it didn't show up in the console. I didn't investigate the generated worklet and would need a bit more time to understand if it's an issue or a mistake from me. (but it's a very good progress!) What do you mean that a
https
server is required? I'm using an
http
server only. With an audio worklet created by myself, in Javascript. it was working with a
http
only server.
t
@dwursteisen I released Seskar with required workaround (Vite pack worklet as Worker ๐Ÿ˜‰ )
Single problem for now - Kotlin/JS removes external
process
method override in production without reason. cc @Artem Kobzar
But we can add temp workaround ๐Ÿ˜‰
d
Oh! Thanks! I was in holidays and was thinking to look at it again this week. Will try the new release tomorrow then.
t
Workaround for production ๐Ÿ˜œ