Skip to content

Commit cb9144d

Browse files
authored
feat(sdk): forward audio container type on upload instead of forcing wav (#1233)
The daemon (UploadAudioStartCmd.encoding) already accepts any <container>-base64 and GStreamer playbin decodes whatever it's given, so the TS SDK shouldn't narrow valid audio to WAV. Derive the upload encoding from the audioBlob's MIME type, defaulting to wav-base64 for untyped/legacy blobs. Unblocks bundling Opus/Ogg move audio from the Marionette apps.
1 parent b678de0 commit cb9144d

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

ts/lib/reachy-mini.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
bytesToBase64,
2525
gzipBase64,
2626
clampVolume,
27+
audioUploadEncoding,
2728
} from './upload-helpers.js';
2829
import type {
2930
ApplyAudioConfigOptions,
@@ -1508,7 +1509,7 @@ export class ReachyMini extends EventTarget implements ReachyMiniInstance {
15081509
type: 'upload_audio_start',
15091510
upload_id: uploadId,
15101511
total_chunks: audioTotal,
1511-
encoding: 'wav-base64',
1512+
encoding: audioUploadEncoding(audioBlob),
15121513
description,
15131514
});
15141515
for (let i = 0; i < audioTotal; i++) {
@@ -1607,7 +1608,7 @@ export class ReachyMini extends EventTarget implements ReachyMiniInstance {
16071608
type: 'upload_audio_start',
16081609
upload_id: uploadId,
16091610
total_chunks: total,
1610-
encoding: 'wav-base64',
1611+
encoding: audioUploadEncoding(audioBlob),
16111612
description,
16121613
});
16131614
for (let i = 0; i < total; i++) {

ts/lib/upload-helpers.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,42 @@ export function clampVolume(v: number): number {
5353
const n = Math.round(Number(v) || 0);
5454
return Math.max(0, Math.min(100, n));
5555
}
56+
57+
/**
58+
* Map an audio Blob to the daemon's `"<container>-base64"` upload encoding.
59+
*
60+
* Transport is always base64; the prefix only tells the daemon which file
61+
* extension to write so GStreamer playbin picks the right demuxer (playbin
62+
* also sniffs content, so this is a hint, not a hard requirement). We forward
63+
* the Blob's own MIME type rather than forcing WAV — the daemon already decodes
64+
* any container it supports. Unknown or empty types fall back to `wav-base64`,
65+
* so legacy WAV recordings and untyped Blobs are unchanged.
66+
*
67+
* Container set mirrors the daemon's `UploadAudioStartCmd.encoding` enum and
68+
* `media.py` `ALLOWED_SOUND_EXTENSIONS`.
69+
*/
70+
export function audioUploadEncoding(blob: Blob): string {
71+
const mime = (blob.type || '').toLowerCase().split(';')[0]?.trim() ?? '';
72+
switch (mime) {
73+
case 'audio/ogg':
74+
case 'application/ogg':
75+
return 'ogg-base64';
76+
case 'audio/opus':
77+
return 'opus-base64';
78+
case 'audio/mpeg':
79+
case 'audio/mp3':
80+
return 'mp3-base64';
81+
case 'audio/flac':
82+
case 'audio/x-flac':
83+
return 'flac-base64';
84+
case 'audio/mp4':
85+
case 'audio/m4a':
86+
case 'audio/x-m4a':
87+
return 'm4a-base64';
88+
case 'audio/aac':
89+
return 'aac-base64';
90+
default:
91+
// audio/wav, audio/x-wav, audio/wave, unknown, or empty.
92+
return 'wav-base64';
93+
}
94+
}

0 commit comments

Comments
 (0)