Skip to content

Commit e553f64

Browse files
committed
Add filetype checks before playback
This allows for fallback to WASM decoding if the browser does not support the format Add matroska (MKA/MKV) checks
1 parent f37c3ae commit e553f64

File tree

1 file changed

+68
-3
lines changed

1 file changed

+68
-3
lines changed

music_html5.c

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ static int MusicHTML5_Open(const SDL_AudioSpec *spec)
173173
m4a: 'audio/mp4',
174174
aif: 'audio/x-aiff',
175175
webm: 'audio/webm',
176-
adts: 'audio/aac'
176+
adts: 'audio/aac',
177+
mkv: 'video/x-matroska',
178+
mka: 'audio/x-matroska'
177179
};
178180

179181
// Get any <audio>, doesn't matter which
@@ -198,6 +200,51 @@ static int MusicHTML5_Open(const SDL_AudioSpec *spec)
198200
return false;
199201
},
200202

203+
canPlayMagic: function(buf) {
204+
let canPlay;
205+
206+
const targets = [
207+
{ type: "audio/ogg", magic: [0x4f, 0x67, 0x67, 0x53] }, // OggS
208+
{ type: "audio/flac", magic: [0x66, 0x4c, 0x61, 0x43] }, // fLaC
209+
//{ type: "audio/midi", magic: [0x4d, 0x54, 0x68, 0x64] }, // MThd
210+
{ type: "audio/mp3", magic: [0x49, 0x44, 0x33] }, // ID3
211+
{ type: "audio/wav", magic: [0x52, 0x49, 0x46, 0x46] },
212+
{ type: "audio/mp4", magic: [0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D] },
213+
{ type: "audio/x-aiff", magic: [0x46, 0x4F, 0x52, 0x4D] },
214+
{ type: ["audio/webm", "audio/x-matroska"], magic: [0x1A, 0x45, 0xDF, 0xA3] }
215+
];
216+
217+
targets.some((target) => {
218+
const targetMagic = target.magic;
219+
const magicLength = targetMagic.length;
220+
const magic = buf.slice(0, magicLength);
221+
222+
let matching = true;
223+
for (let i = 0; i < magicLength; i++) {
224+
if (magic[i] !== targetMagic[i]) {
225+
matching = false;
226+
break;
227+
}
228+
}
229+
230+
if (matching) {
231+
const targetTypes = Array.isArray(target.type) ? target.type : [target.type];
232+
targetTypes.some((targetType) => {
233+
canPlay = Module["SDL2Mixer"].canPlayType(targetType);
234+
if (canPlay)
235+
return true;
236+
});
237+
return true;
238+
}
239+
});
240+
241+
// MP3 special case
242+
if (!canPlay && magic[0] === 0xFF && (magic[1] & 0xFE) === 0xFA)
243+
canPlay = Module["SDL2Mixer"].canPlayType("audio/mp3");
244+
245+
return canPlay;
246+
},
247+
201248
musicFinished: function(e) {
202249
const audio = e.target;
203250

@@ -293,15 +340,21 @@ static void *MusicHTML5_CreateFromRW(SDL_RWops *src, int freesrc)
293340
const context = $2;
294341

295342
const buf = new Uint8Array(Module.HEAPU8.buffer, ptr, size);
343+
344+
if (!Module["SDL2Mixer"].canPlayMagic(buf))
345+
return -1;
346+
296347
const url = Module["SDL2Mixer"].createBlob(buf);
297-
const id = Module["SDL2Mixer"].createAudio(url, context);
348+
const id = Module["SDL2Mixer"].createMusic(url, context);
298349

299350
return id;
300351
}, buf, size, music);
301352
}
302353

303354
if (id == -1)
304355
{
356+
if (freebuf)
357+
SDL_free(buf);
305358
SDL_free(music);
306359
return NULL;
307360
}
@@ -332,16 +385,28 @@ static void *MusicHTML5_CreateFromFile(const char *file)
332385
id = EM_ASM_INT({
333386
const file = UTF8ToString($0);
334387
const context = $1;
335-
let url;
336388

389+
let url;
337390
try {
338391
// Is path in FS?
339392
const buf = FS.readFile(file);
340393
url = Module["SDL2Mixer"].createBlob(buf);
394+
395+
let canPlay = Module["SDL2Mixer"].canPlayFile(file);
396+
397+
if (!canPlay)
398+
canPlay = Module["SDL2Mixer"].canPlayMagic(buf);
399+
400+
if (!canPlay)
401+
return -1;
341402
} catch(e) {
342403
// Fail silently, presume file not in FS.
343404
// Assume it's a relative or absolute URL
344405
url = file;
406+
407+
// Check audio capability by file extension
408+
if (!Module["SDL2Mixer"].canPlayFile(url))
409+
return -1;
345410
}
346411

347412
const id = Module["SDL2Mixer"].createMusic(url, context);

0 commit comments

Comments
 (0)