Play mp3 from internet without FileOpenDialog?

Aug 29, 2009 at 12:23 PM
Edited Aug 31, 2009 at 8:18 AM

Hi, I noticed in the NAudio Demo from the latest version of NAudio that if Filename is empty, then it opens a fileopendialog.
So if I paste a http link in that window and click OK, I've noticed that the FileName string looks something like this:

"C:\\Users\\User\\AppData\\Local\\Microsoft\\Windows\\Temporary Internet Files\\Content.IE5\\2FO1NTK2\\20s[1].mp3"

How does this exactly happen? I don't want an OpenFileDialog because the path I want to play is already stated elsewhere.
And in my case, I use a string which looks something like this "http://domainname.com/file.mp3"

This creates an error stating that URL is not supported. So I guess there's something I'm missing here?

Edit: I'm thinking, there must be some code somewhere which actually starts a download stream or something? Since the Filename string path ends up in Temporary Internet Files?
I've tried stepping into the code and I can't see anything of what's happening "behind" the OpenFileDialog.
Can I alter the code somewhat to make it do just that?

Edit: I found the PlayMp3FromUrl code on StackOverflow. But the thing is, I get an error stating that "WaveOut" doesn't take the number of arguments.
Has there been any changes to the WaveOut.cs since PlayMp3FromUrl was written?

This is the line which fails:
"using (WaveOut waveOut = new WaveOut(0, 500, null))"

If I remove all arguments so is says "new WaveOut())" the code compiles and I can hear the first microsecond of the mp3 file. But it freezes after that, which is probably because of the lack of arguments I guess? I think atleast that the "500" means latency settings.

Coordinator
Sep 1, 2009 at 11:18 AM

Hi,

the WaveOut constructor has indeed changed in the most recent check-in (currently getting ready for a 1.3 release, but not quite stable yet). Are you creating the WaveOut class on a background thread? In that case, you will need to supply a window handle directly or ask it to use Function callbacks.

Sep 1, 2009 at 12:45 PM
Edited Sep 1, 2009 at 12:47 PM

No, I don't think it's run in a background thread. I'm not an amazing C# programmerer at all. I'm just trying to create an application which allows me to store my own created songs, like a library. Because my head is getting pretty full :p
Anyway, I just thought I'd give it a go and so far it's gone pretty well actually, considering my complete lack of C# insight.

Btw, I do think I need to do the WaveOut class on a background thread because I tried to replace it WaveOut with DirectSoundOut and the playback worked! But the Form froze completely
.Which is probably because the current thread is busy with the download stream or something.
How can I supply a window handle or ask it to use Function callbacks? I've tried lots of stuff, but the syntax is always wrong. And I can't understand what the WaveOut class want as arguments, if any.

This is the code I'm using to download a stream, as of now:

public static void PlayMp3FromUrl(string url)
{
using (MemoryStream ms = new MemoryStream())
{
using (Stream stream = WebRequest.Create(url)
.GetResponse().GetResponseStream())
{
byte[] buffer = new byte[32768];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
}

ms.Position = 0;

using (WaveStream blockAlignedStream =
new BlockAlignReductionStream(
WaveFormatConversionStream.CreatePcmStream(
new Mp3FileReader(ms))))
{
using (WaveOut waveOut = new WaveOut(0, 500, null))
{
waveOut.Init(blockAlignedStream);
waveOut.Play();
while (blockAlignedStream.Position < blockAlignedStream.Length)
{
System.Threading.Thread.Sleep(100);
}
}
}
}
}

The code fails at using (WaveOut waveOut = new WaveOut(0, 500, null))
And the While loop is probably what's freezing the form. Could you care to explain a little further how I can do what's needed to make this work?
I'm also curious on how and where the local cache is stored when doing a WebRequest like this.
It's probably a waste if the already downloaded buffer can't be cached in some way. So I won't need to download the same stream over and over again.