views:

231

answers:

1

I have a small Silverlight app which downloads all of the images and text it needs from a URL, like this:

if (dataItem.Kind == DataItemKind.BitmapImage)
{
    WebClient webClientBitmapImageLoader = new WebClient();
    webClientBitmapImageLoader.OpenReadCompleted += new OpenReadCompletedEventHandler(webClientBitmapImageLoader_OpenReadCompleted);
    webClientBitmapImageLoader.OpenReadAsync(new Uri(dataItem.SourceUri, UriKind.Absolute), dataItem);
}
else if (dataItem.Kind == DataItemKind.TextFile)
{
    WebClient webClientTextFileLoader = new WebClient();
    webClientTextFileLoader.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClientTextFileLoader_DownloadStringCompleted);
    webClientTextFileLoader.DownloadStringAsync(new Uri(dataItem.SourceUri, UriKind.Absolute), dataItem);
}

and:

void webClientBitmapImageLoader_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.SetSource(e.Result);
    DataItem dataItem = e.UserState as DataItem;

    CompleteItemLoadedProcess(dataItem, bitmapImage);
}

void webClientTextFileLoader_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    DataItem dataItem = e.UserState as DataItem;
    string textFileContent = e.Result.ForceWindowLineBreaks();
    CompleteItemLoadedProcess(dataItem, textFileContent);
}

Each of the images and text files are then put in a dictionary so that the application has access to them at any time. This works well.

Now I want to do the same with mp3 files, but all information I find on the web about playing mp3 files in Silverlight shows how to embed them in the .xap file, which I don't want to do since I wouldn't be able to download them dynamically as I do above.

How can I download and play mp3 files in Silverlight like I download and show images and text?

+1  A: 

You would download the MP3 as binary stream and store the result in a byte array. Its this byte array you would store in your dictionary.

At the point that you want to assign the byte array to a MediaElement you would use code like this:-

void SetMediaElementSource(MediaElement me, byte[] mp3)
{
  me.SetSource(new MemoryStream(mp3));
}
AnthonyWJones
worked nicely, after the MediaElement is in the dictionary, I just have to pull it out and call .Play() on it, thanks
Edward Tanguay
so the MediaElement plays **once** but how do I get it to play **twice** http://stackoverflow.com/questions/2489906/after-playing-a-mediaelement-how-can-i-play-it-again
Edward Tanguay
@Edward: I'd be nervous about keeping too many MediaElements alive at one time. If fact you might need to look at the memory costs of your whole dictionary strategy to make sure it does end up being too expensive.
AnthonyWJones
but what is the alternative in silverlight if I want, e.g. 50 sounds (language education app) to play immediately on hover, click, etc. It seems to me a better user experience to have a 10-second load wait at the beginning (and save them in isolated storage for the subsequent times) then for the user to constantly have to wait on hover, click for sounds to load, right?
Edward Tanguay
@Edward: Alternatives may not be necessary but you should be aware that if you burden the client memory too much you could end up with a worse experience for the user rather than better. One alternative is to let the browser cache do its job, do enough at startup to get these resources downloaded to the client, with appropriate cache headers so that subsequest "real" requests to a resource load from local cache. That may not work for all types of media in which case byte arrays or even some Isolated storage may offer some alternatives if you want to reduce the app's memory footprint.
AnthonyWJones