Help with Emscripten and SDL2_mixer

Hello, I am trying to make a webapp that uses SDL2_mixer to create sound. I have been able to use SDL2 and SDL2_image in the code and it works fine. However, as soon as I include SDL2_mixer, the program breaks and the console says: Mix_Init: no sound/music loaders supported (). My current compile command is: emcc source/main.c -o main.html -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s USE_SDL_MIXER=2 -s SDL2_IMAGE_FORMATS=["png"] -s ALLOW_MEMORY_GROWTH=1 --preload-file assets . However I have tried a lot of different variations but they all give me that same error.(like including -sUSE_OGG=1, -sUSE_VORBIS=1, or SDL2_MIXER_FORMATS=‘[“ogg”]’) I have searched around and it seems like I could find very few tutorial or examples of SDL2_mixer being used with emscripten (most tutorials seem to end once an image is on the screen). Any advice or examples someone could give me would be much appreciated.

Also, I am on windows if that matters. I also the python library http to create localhost to test my code on the browser.

Last time I used Emscripten, I managed to get SDL_Mixer to work quite easily together with Emscripten.

I used the following command when building the project:
emcc /mySourceFilesSpecifiedHere/ -o test.html -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' -s USE_SDL_TTF=2 -s USE_FREETYPE=1 -s USE_SDL_MIXER=2 -s USE_OGG=1

To start up SDL_Mixer, I do this:

const int result = Mix_Init(MIX_InitFlags::MIX_INIT_OGG);

if((result & MIX_InitFlags::MIX_INIT_OGG) == 0)
	printf("Error: failed to initialize SDL_Mixer. %s\n", Mix_GetError());

	return false;

if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 2048) == -1)
#ifdef _DEBUG
	printf("Error: failed to open audio device. %s\n", Mix_GetError());

	return false;

Can you confirm that you’re doing it the same way?

Hi thanks for the response! I have some similar code to that, but I still have the same error. I start getting the error as soon as I add the -sUSE_SDL_MIXER=2 flag. It happens when even when I don’t use any code involving the mixer. This doesn’t seem to happen when I add the flag -sUSE_TTF=2 even when I don’t use it. Maybe I need try using an older version of emscripten. I think I will try to do that.

Here is my code below where I did attempt to use the mixer:

#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#include <emscripten.h>
#include <stdlib.h>

SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *texture = NULL;
SDL_Rect destinationRect = {100, 100, 0, 0};

Mix_Music *music = NULL;

void playMusic() {
Mix_PlayMusic(music, 0);

void render_loop() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {

SDL_RenderCopy(renderer, texture, NULL, &destinationRect);


int main() {


if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) < 0) {
    printf("Failed to initialize SDL_mixer: %s\n", Mix_GetError());
    return 1;

music = Mix_LoadMUS("assets/test_song.ogg");
if (!music) {
    printf("Failed to load music: %s\n", Mix_GetError());
    return 1;
window = SDL_CreateWindow("SDL2_image Example",
                          800, 600,
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

SDL_Surface *surface = IMG_Load("assets/triangle.png");
if (!surface) {
    printf("Failed to load image: %s\n", IMG_GetError());
    return 1;

destinationRect.w = surface->w;
destinationRect.h = surface->h;

texture = SDL_CreateTextureFromSurface(renderer, surface);
if (!texture) {
    printf("Failed to create texture: %s\n", SDL_GetError());
    return 1;

emscripten_set_main_loop(playMusic, 0, 1);
emscripten_set_main_loop(render_loop, 0, 1);


return 0;


Hi, I was able to get it working. I had to revert to an older version of the emsdk(I used 3.1.44). I think there must be a bug of some sort.

I couldn’t see any obvious error in your code so it might, like you wrote, be a bug in the newest version of Emscripten.

Nice that you got it working :slight_smile:

Thanks for the help! Your compile command helped identify it!

Also the most it seem like both builds 3.1.53(the current build) and 3.1.52 have this issue. Build 3.1.51 seems to work.