@@ -173,7 +173,9 @@ static int MusicHTML5_Open(const SDL_AudioSpec *spec)
173
173
m4a : 'audio/mp4' ,
174
174
aif : 'audio/x-aiff' ,
175
175
webm : 'audio/webm' ,
176
- adts : 'audio/aac'
176
+ adts : 'audio/aac' ,
177
+ mkv : 'video/x-matroska' ,
178
+ mka : 'audio/x-matroska'
177
179
};
178
180
179
181
// Get any <audio>, doesn't matter which
@@ -198,6 +200,51 @@ static int MusicHTML5_Open(const SDL_AudioSpec *spec)
198
200
return false;
199
201
},
200
202
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
+
201
248
musicFinished : function (e ) {
202
249
const audio = e .target ;
203
250
@@ -293,15 +340,21 @@ static void *MusicHTML5_CreateFromRW(SDL_RWops *src, int freesrc)
293
340
const context = $2 ;
294
341
295
342
const buf = new Uint8Array (Module .HEAPU8 .buffer , ptr , size );
343
+
344
+ if (!Module ["SDL2Mixer" ].canPlayMagic (buf ))
345
+ return -1 ;
346
+
296
347
const url = Module ["SDL2Mixer" ].createBlob (buf );
297
- const id = Module ["SDL2Mixer" ].createAudio (url , context );
348
+ const id = Module ["SDL2Mixer" ].createMusic (url , context );
298
349
299
350
return id ;
300
351
}, buf , size , music );
301
352
}
302
353
303
354
if (id == -1 )
304
355
{
356
+ if (freebuf )
357
+ SDL_free (buf );
305
358
SDL_free (music );
306
359
return NULL ;
307
360
}
@@ -332,16 +385,28 @@ static void *MusicHTML5_CreateFromFile(const char *file)
332
385
id = EM_ASM_INT ({
333
386
const file = UTF8ToString ($0 );
334
387
const context = $1 ;
335
- let url ;
336
388
389
+ let url ;
337
390
try {
338
391
// Is path in FS?
339
392
const buf = FS .readFile (file );
340
393
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 ;
341
402
} catch (e ) {
342
403
// Fail silently, presume file not in FS.
343
404
// Assume it's a relative or absolute URL
344
405
url = file ;
406
+
407
+ // Check audio capability by file extension
408
+ if (!Module ["SDL2Mixer" ].canPlayFile (url ))
409
+ return -1 ;
345
410
}
346
411
347
412
const id = Module ["SDL2Mixer" ].createMusic (url , context );
0 commit comments