diff --git a/deno.json b/deno.json
index 2f93c3a..e8c8e35 100644
--- a/deno.json
+++ b/deno.json
@@ -3,7 +3,8 @@
"@picocss/pico": "npm:@picocss/pico@^2.0.6",
"@web-applets/sdk": "npm:@web-applets/sdk@^0.2.6",
"astro": "npm:astro@^5.4.1",
- "spellcaster": "npm:spellcaster@^5.0.2"
+ "spellcaster": "npm:spellcaster@^5.0.2",
+ "throttle-debounce": "npm:throttle-debounce@^5.0.2"
},
"tasks": {
"astro": "astro",
diff --git a/deno.lock b/deno.lock
index 4bc9ae3..43177f6 100644
--- a/deno.lock
+++ b/deno.lock
@@ -8,7 +8,8 @@
"npm:astro@5.4.2": "5.4.2_vite@6.2.1_zod@3.24.2",
"npm:astro@^5.4.1": "5.4.2_vite@6.2.1_zod@3.24.2",
"npm:create-astro@latest": "4.11.1",
- "npm:spellcaster@^5.0.2": "5.0.2"
+ "npm:spellcaster@^5.0.2": "5.0.2",
+ "npm:throttle-debounce@^5.0.2": "5.0.2"
},
"npm": {
"@astrojs/cli-kit@0.4.1": {
@@ -2078,6 +2079,9 @@
"yallist"
]
},
+ "throttle-debounce@5.0.2": {
+ "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A=="
+ },
"tinyexec@0.3.2": {
"integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="
},
@@ -2325,7 +2329,8 @@
"npm:@picocss/pico@^2.0.6",
"npm:@web-applets/sdk@~0.2.6",
"npm:astro@^5.4.1",
- "npm:spellcaster@^5.0.2"
+ "npm:spellcaster@^5.0.2",
+ "npm:throttle-debounce@^5.0.2"
]
}
}
diff --git a/src/applets/engine/audio/applet.astro b/src/applets/engine/audio/applet.astro
index b598dc6..0dc7e75 100644
--- a/src/applets/engine/audio/applet.astro
+++ b/src/applets/engine/audio/applet.astro
@@ -1,69 +1,302 @@
-
+
diff --git a/src/applets/engine/audio/manifest.json b/src/applets/engine/audio/manifest.json
index cc48283..9a01307 100644
--- a/src/applets/engine/audio/manifest.json
+++ b/src/applets/engine/audio/manifest.json
@@ -1,27 +1,119 @@
{
"name": "diffuse/engine/audio",
+ "title": "Diffuse Audio",
"entrypoint": "index.html",
"actions": {
- "load": {
- "title": "Load",
- "description": "Load a given audio src",
- "params_schema": {
- "type": "string",
- "description": "String to be used as the audio `src`"
- }
- },
"pause": {
"title": "Pause",
- "description": "Indicate the active audio should be paused",
+ "description": "Pause a track",
"params_schema": {
- "type": "null"
+ "type": "object",
+ "properties": {
+ "trackId": {
+ "type": "string"
+ }
+ },
+ "required": ["trackId"]
}
},
"play": {
"title": "Play",
- "description": "Indicate the active audio should be playing",
+ "description": "Play a track",
+ "params_schema": {
+ "type": "object",
+ "properties": {
+ "trackId": {
+ "type": "string"
+ },
+ "volume": {
+ "type": "number"
+ }
+ },
+ "required": ["trackId", "volume"]
+ }
+ },
+ "render": {
+ "title": "Render",
+ "description": "Determine the active set of audio elements",
+ "params_schema": {
+ "type": "object",
+ "properties": {
+ "play": {
+ "type": "object"
+ },
+ "tracks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "id": { "type": "string" },
+ "isPreload": { "type": "boolean" },
+ "mimeType": { "type": "string" },
+ "progress": { "type": "number" },
+ "url": { "type": "string" }
+ },
+ "required": ["id", "isPreload", "url"]
+ }
+ ]
+ }
+ }
+ },
+ "required": ["tracks"]
+ }
+ },
+ "reload": {
+ "title": "Reload",
+ "description": "Make sure the audio node with the given track id is loading properly. This should be used when for example, the internet connection comes back and the loading of the track depended on said internet connection.",
+ "params_schema": {
+ "type": "object",
+ "properties": {
+ "play": {
+ "type": "boolean"
+ },
+ "progress": {
+ "type": "number"
+ },
+ "trackId": {
+ "type": "string"
+ }
+ },
+ "required": ["percentage", "trackId"]
+ }
+ },
+ "seek": {
+ "title": "Seek",
+ "description": "Seek a track to a given position",
+ "params_schema": {
+ "type": "object",
+ "properties": {
+ "percentage": {
+ "type": "number",
+ "description": "A number between 0 and 1 that determines the new current position in the audio"
+ },
+ "trackId": {
+ "type": "string"
+ }
+ },
+ "required": ["percentage", "trackId"]
+ }
+ },
+ "volume": {
+ "title": "Volume",
+ "description": "Set the volume of all tracks, or a specific track.",
"params_schema": {
- "type": "null"
+ "type": "object",
+ "properties": {
+ "trackId": {
+ "type": "string"
+ },
+ "volume": {
+ "type": "number",
+ "description": "A number between 0 and 1 that determines the new volume of all audio elements"
+ }
+ },
+ "required": ["volume"]
}
}
}
diff --git a/src/applets/engine/audio/types.ts b/src/applets/engine/audio/types.ts
new file mode 100644
index 0000000..7ebe8e9
--- /dev/null
+++ b/src/applets/engine/audio/types.ts
@@ -0,0 +1,22 @@
+export interface State {
+ nowPlaying: Record;
+}
+
+export interface Track {
+ id: string;
+ isPreload: boolean;
+ mimeType?: string;
+ progress?: number;
+ url: string;
+}
+
+export interface TrackState {
+ duration: number;
+ id: string;
+ loadingState: "initialisation" | "loading" | "loaded" | {
+ error: { code: number };
+ };
+ isPlaying: boolean;
+ isPreload: boolean;
+ progress: number;
+}
diff --git a/src/applets/themes/pilot/ui/audio/applet.astro b/src/applets/themes/pilot/ui/audio/applet.astro
index 41397ec..4d61be1 100644
--- a/src/applets/themes/pilot/ui/audio/applet.astro
+++ b/src/applets/themes/pilot/ui/audio/applet.astro
@@ -48,14 +48,14 @@
flex: 1;
flex-direction: column;
max-width: var(--container-lg);
- padding: var(--space-sm) var(--space-md);
+ margin-top: var(--space-2xs);
+ padding: var(--space-2xs) var(--space-md);
}
.controls {
align-items: center;
display: flex;
justify-content: center;
- margin-bottom: var(--space-2xs);
& .controls__playpause {
font-size: var(--fs-lg);
@@ -65,6 +65,7 @@
.time {
align-self: stretch;
display: flex;
+ padding: var(--space-2xs) 0;
}
progress {
@@ -91,10 +92,7 @@