NoWar
NoWar

Reputation: 37642

Read audio file to stream with MediaPlayer (WPF)

I use MediaPlayer to play audio files

var mediaPlayer = new MediaPlayer(); 
mediaPlayer.Open(new Uri(s));
mediaPlayer.Play();

Sometimes I need to delete files that MediaPlayer is still playing. I guess I have somehow read file to stream to be get free access to it in order to delete it. I mean i sthere way to read file to stream or I have to create some temp. file to play and in this case I can delete the original one or there are other options?

How to implement it?

Thank you!

Upvotes: 3

Views: 8628

Answers (1)

Bill Tarbell
Bill Tarbell

Reputation: 5234

Actually, when you call MediaPlayer.Open it reads in the file via a stream automatically. The problem is that the stream is still open when you try to delete the file.

MediaPlayer has a .Close method on it. Calling this will close the stream that's reading in the file.

here's the documentation on the MediaPlayer class so you can see what other methods are available to use: http://msdn.microsoft.com/en-us/library/system.windows.media.mediaplayer.aspx

EDIT: If you don't mind that the player stops playback when you call Close then you can just Close & then delete your file. If you do need playback to continue then you'll need a different approach.

If you're using Silverlight then you can just load the stream directly into a MediaElement:

var bytes = File.ReadAllBytes(@"c:\yourfile.ext");
var mStream = new MemoryStream(bytes);
mediaElement1.SetSource(mStream);

Sadly, WPF does not have the same stream support. I attempted to get a Uri for the MemoryStream by writing the stream into the resource pack. Though, i couldn't get it to playback correctly in my testing. I'll include my source that i had just in case you want to fiddle with it and maybe get it to work:

  var bytes = File.ReadAllBytes(@"C:\Bill\TestWaveFiles\14043.wav");

  MemoryStream packStream = new MemoryStream()
  Package pack = Package.Open(packStream, FileMode.Create, FileAccess.ReadWrite);
  Uri packUri = new Uri("bla:");
  PackageStore.AddPackage(packUri, pack);
  Uri packPartUri = new Uri("/MemoryResource", UriKind.Relative);
  PackagePart packPart = pack.CreatePart(packPartUri, "Media/MemoryResource");
  packPart.GetStream().Write(bytes, 0, bytes.Length);
  var inMemoryUri = PackUriHelper.Create(packUri, packPart.Uri);


  mediaElement1.LoadedBehavior = MediaState.Manual;
  mediaElement1.Source = inMemoryUri;
  mediaElement1.Play();

Another option is to simply make a copy of the file before you open it. that way you can always delete the original. Though, you could also just "mark" the file to be deleted. When the user is done playing the the file then you could close & delete it.

One additional option is to use a 3rd party library called BoxedApp. It seemingly will allow you to have a "Virtual File" that contains a memory stream. You could then get a Uri that points to this virtual file and load it into the media player. Look at this answer by user1108125 to see how to use this BoxedApp library (which i've never used). https://stackoverflow.com/a/8587166/1721136

Upvotes: 4

Related Questions