Friday, January 23, 2009

What I Learned Today - How To Play Multiple Media Files In Silverlight

So I am trying to write a learning game for children in Silverlight and I wanted to prompt the user with two concatenated MP3 audio files, so file 1 would play: "Can you find the letter" and file 2 would complete the request by playing: "A" or "B". So the full sentence should sound something like "Can you find the letter A?". Silverlight kept playing both files at the same time, or it wouldn't play them at all, or it would play one of them the first time and the other one the second time, it was very weird. And because I wanted to selected the file that I wanted each time the user progressed in the game I didn't want to have to specify each of my sound files in the XAML, I wanted to be able to do it all programatically, but all of the examples I found were for defining multiple MediaElement objects in the XAML and then calling them from the code behind.

So what I ended up finally doing was specifying two MediaElements in my XAML like so:

<mediaelement name="StaticMediaElement" autoplay="False" />
<mediaelement name="DynamicMediaElement" autoplay="False" />

Then in my code behind I had to do a little fenagling but it was worth it because it worked beautifully:

private void InitializeGame()
{
StaticMediaElement.MediaOpened += new RoutedEventHandler(StaticMediaElement_MediaOpened);
StaticMediaElement.MediaEnded += new RoutedEventHandler(StaticMediaElement_MediaEnded);
}

private void PromptForLetter()
{
DynamicMediaElement.Source = new Uri(String.Format("/Sounds/Letter{0}.mp3", selectedLetter), UriKind.Relative);
StaticMediaElement.Source = new Uri("/Sounds/CanYouFindTheLetter1.mp3", UriKind.Relative);
}

void
StaticMediaElement_MediaOpened(object sender, RoutedEventArgs e)
{
((MediaElement)sender).Play();
}
void
StaticMediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
DynamicMediaElement.Play();
StaticMediaElement.Stop();
}


So what this does is it loads up the static media file and waits for it to finish loading before it tries to play it, and while it's doing that it also loads up the dynamic media file and as soon as the MediaEnded event fires for the static file it kicks off the dynamic file. This allows the two sound files to play one right after the other with very little delay in between them.

I was really banging my head against the wall trying to figure this out and that's what I learned today.

No comments: