Search code examples
c#xnastreammp3media-player

Converting a Stream to a Song class?


I'm trying to open a file from a dialog, then play it with the MediaPlayer in XNA, but, my opener opens the file as a Stream class, and I have no idea how to convert it to a Song class, so I can play it with the MediaPlayer, any help?

Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "mp3 files (*.mp3)|*.mp3|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;

if (openFileDialog1.ShowDialog() == DialogResult.OK) {
    try {
        if ((myStream = openFileDialog1.OpenFile()) != null) {
            using (myStream) {

            }
        }
    } catch (Exception ex) {
        MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
    }
}

Solution

  • You can't do it that way. XNA hands off music playback to an internal media player component. It cannot load music from a Stream (if I had to guess, it probably implements its own streaming). What it can do is load a music file, given a file name.

    You could do something like this:

    Song mySong = Song.FromUri(@"file:///" + openFileDialog1.FileName);
    

    It's worth pointing out that there is a known bug if the path to your file contains a space. But there is an internal method that you could use that takes a file name directly and doesn't exhibit the bug - I discuss how to use it in this answer. It is:

    internal Song(string name, string filename, int duration);
    

    It's worth pointing out that this is pretty much the same thing that the content pipeline does. If you look at the .xnb file that it produces for a Song, it is tiny - just a few bytes. And all it contains is the filename of the song to load. The song file itself is just copied in separately.