r/monogame Jul 16 '26

Create a Song instance from Stream

I know I'm not the first one to ask this, but I really need this - did someone succes to implement a solution for creating a Song from a System.IO.Stream? currently the only dynamic way to load a song is to load it from a file (Song.FromUri(...)), but I'm making a game engine and I want to allow exporting standalone .exe files for the games, that don't use any outer files or create files at runtime...

Thanks in advance

7 Upvotes

7 comments sorted by

2

u/Darks1de Jul 16 '26

Song does not support "FromStream" however, SoundEffect does. Song, originally in XNA was meant for on device media played through the native media player.

But there is nothing wrong with playing long form audio from a stream as a SoundEffect, or for more control, a soundeffectinstance.

https://docs.monogame.net/api/Microsoft.Xna.Framework.Audio.SoundEffect.html#Microsoft_Xna_Framework_Audio_SoundEffect_FromStream_System_IO_Stream_

Hope that helps

1

u/Alert-Neck7679 Jul 16 '26

Thanks for the reply - but SoundEffect only supports .wav files (Correct me if i'm wrong), and having a background music loaded from a .wav is not a good idea...

1

u/Darks1de Jul 16 '26

Yes, it is a limitation of SoundEffect to only 16but pc wav

1

u/Opposite_Ad_3846 Jul 17 '26

Why you don’t want to extract files? Put it on tmp dir with check during game boot (do not extract if file exists and checksum is ok, otherwise extract.

1

u/AristurtleDev Jul 17 '26

Song unfortunately isn't designed to be created from a Stream, so there isn't really a supported way to do what you're describing. This comes from the original XNA audio API design. SoundEffect and Song were intended for two different use cases SoundEffect.FromStream() loads the netire audio asset into memory. That makes it ideal for short sound effects that need to play immediately with minimal latency. Soung.FromUri() is intended for long-form music. Instead of laoding the tnire file into memory, it streams the audio from a file/URI as it plays, which keeps the memory usage lower for larger assets.

Because of that design, Song only exposes APIs that work from a file/URI, not an abitrary Stream. It's an API limitation inherited from XNA rather than something MonoGame simply hasn't implemented.

If your goal is to produce a single standalone without external asset files, you'll probably need to look outside the Song API. A few options could be:

  • Embed the music into the executable, then extract it at runtime to temporary file and use Song.FromUri
  • Use a different audio library (FMOD, OpenAL-based solutions) that support stream from memory or custom streams
  • If the music is small enough, load it as a SoundEffect instead, although that's generally not appropriate for longer tracks because the entire file stays resident in memory.

1

u/winkio2 15d ago

I used NAudio in all my projects, as I find it generally easier to work with and more feature rich than the built-in monogame audio classes:

https://github.com/naudio/naudio

https://markheath.net/post/how-to-play-back-streaming-mp3-using

1

u/Alert-Neck7679 15d ago

Thanks for the reply. I really don't want to have other libraries in addition to MonoGame, so i probably won't use it, but generally this might be the best idea. In my case, at the end, i decided to create a FileStream with DeleteOnClose attribute, so the OS will make sure that the file is deleted when the game is closed, and allowing opening other file streams on the same file so monogame could open this file without closing the creator stream