Share via


How to play mp3 file from my.resources

Question

Wednesday, January 14, 2015 8:19 AM

Hello

Is it possible to play mp3 file from my.resources ?

I  tried to use the windows media play control but i had to provide the path of the mp3 file and i want to pass  my.resources.music not the path.  

Thanks 

All replies (8)

Thursday, January 15, 2015 5:55 PM ✅Answered | 1 vote

"It works but sometimes it hangs  and plays after 10 ,15 seconds. no message error is raised."

  I take it you must be writing all the mp3 files to the hard drive before playing any of them, right? It does take a few seconds to load a new audio file from the Url path into memory and start playing it. There is not much you can do about that though.

 Also, unless you have set the axWindowsMediaPlayer.settings.autoStart to False somewhere in you code, you should not need to use the controls.play() method to start the new song. Just setting the Url to the filename should start playing the next song automatically.

If you say it can`t be done then i`ll try it


Wednesday, January 14, 2015 8:55 AM

check this forum:

http://stackoverflow.com/questions/25713065/play-mp3-from-my-resources-using-wmplib-windowsmediaplayer-from-released-applica

Fouad Roumieh


Wednesday, January 14, 2015 11:18 AM | 2 votes

Hi,

 You can not play the mp3 directly from the Resources. You need to write the mp3 to the hard drive and then play it. Below is an example.

Public Class Form1
    Dim MyMp3PathName As String = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MySong.mp3")

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        IO.File.WriteAllBytes(MyMp3PathName, My.Resources.MySong) 'Save the song to My Documents as MySong.mp3
        AxWindowsMediaPlayer1.URL = MyMp3PathName 'Start playing the song
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If IO.File.Exists(MyMp3PathName) Then IO.File.Delete(MyMp3PathName) 'Delete the song when closing if you want to
    End Sub
End Class

If you say it can`t be done then i`ll try it


Thursday, January 15, 2015 10:03 AM

thanks

it works ,so i wrote a little application.I have a list of string for the paths of each mp3 files

a button ,each time  is clicked a mp3 file is choosen randomaly and play.

It works but sometimes it hangs  and plays after 10 ,15 seconds. no message error is raised.

When it  hangs , i see the task manager  vshost32.exe not responding 

Thanks in advance 

Imports WMPLib
 Private wmp As WindowsMediaPlayer = New WindowsMediaPlayer
  Private Sub Button1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseClick
        Dim rnd As New Random
        Dim x As Integer
        x = rnd.Next(0, listmusics.Count)
        wmp.URL = listmusics(x)
        Try
            wmp.controls.play()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
 
 
    End Sub

Thursday, January 15, 2015 6:49 PM

thanks

it works ,so i wrote a little application.I have a list of string for the paths of each mp3 files

a button ,each time  is clicked a mp3 file is choosen randomaly and play.

It works but sometimes it hangs  and plays after 10 ,15 seconds. no message error is raised.

When it  hangs , i see the task manager  vshost32.exe not responding 

Thanks in advance 

Imports WMPLib
 Private wmp As WindowsMediaPlayer = New WindowsMediaPlayer
  Private Sub Button1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseClick
        Dim rnd As New Random
        Dim x As Integer
        x = rnd.Next(0, listmusics.Count)
        wmp.URL = listmusics(x)
        Try
            wmp.controls.play()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
 
 
    End Sub

If that is all of the code in your application and attempting to play an .MP3 file (which all of them are already on disk) is causing VSHost to not respond then I should think you have issues other than anything to do with Visual Studio or the application which is supposed to play the .MP3 file.

Since all of the .MP3 files are already on disk on your PC when you select a string (URL) to play and it takes 10 to 15 seconds for anything to occur your system is either really busy or is short on RAM or has a really slow Disk or a really slow bus or any combination of all those and possibly other issues also.

Your app is being hosted in Visual Studio when this occurs. What happens if you exit Visual Studio and run the .exe that is in the debug folder for the apps project folder? Does this happen then also?

How about if you use Windows Media Player to play the same MP3 files? Is there an issue with delay then also?

La vida loca


Thursday, January 15, 2015 7:03 PM | 1 vote

Hi,

 You can not play the mp3 directly from the Resources. You need to write the mp3 to the hard drive and then play it. Below is an example.

Public Class Form1
    Dim MyMp3PathName As String = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MySong.mp3")

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        IO.File.WriteAllBytes(MyMp3PathName, My.Resources.MySong) 'Save the song to My Documents as MySong.mp3
        AxWindowsMediaPlayer1.URL = MyMp3PathName 'Start playing the song
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If IO.File.Exists(MyMp3PathName) Then IO.File.Delete(MyMp3PathName) 'Delete the song when closing if you want to
    End Sub
End Class

If you say it can`t be done then i`ll try it

@IronRazerz

I don't know if it's possible but there's a capability called VirtualFile that works with VirtualPathProvider and I searched for information Google search results for "Use VirutalPathProvider with embedded resources" about possibly using that for embedded media files in order to play them with WMP without writing them to disk first.

It seems possible but then it may be a dead end. I got tired after reading all kinds of threads and code about it which didn't seem to go in the direction I was looking for.

Links like this EmbeddedResourcePathProvider - Binary-Only ASP.NET 2.0 make it sound like it could work by providing WMP with a virtual file link or something. But I don't really know. I was only interested cause of all the threads wanting to run embedded media files directly to WMP without having to write them to disk first.

La vida loca


Thursday, January 15, 2015 7:36 PM

I suceeded 

  i set axWindowsMediaPlayer.settings.autoStart to true and use the url and remove

 axWindowsMediaPlayer.controls.play() 


Friday, January 16, 2015 9:49 PM | 1 vote

Shay,

Now that this has been answered, I wanted to add something to this thread mainly because I  feel sure that the subject line you’ve used will draw attention to others in time. It’s a fairly common question that I’ve seen here over the years, stated in one way or another.

I’d like to state that I’ve never been a fan of embedding a lot of anything in the resources and certainly .mp3 files, even though they’re tremendously smaller than their CD quality counterparts, are not small! You can easily find it not compiling due to an OOM error. Also though, it makes for a large compilation to then have to distribute with your program.

I also won’t address the copyright infringement part of this – I’ll assume that whoever reads this has full rights to distribute whatever mp3 files they’ve embedded (yea, sure! … I had to say that though).

*****

Prologue

When I saw this thread in the forum it reminded me of several others in the past and I thought about a way to embellish doing what you’re setting out to do: Play an MP3 audio file which is in the resources.

It seems there should be a ‘better way’, to do that, at least to some extent. That’s what my post here today is about: An embellished way to get at those resources and to present the MP3 audio files to the user (then, of course, play them in the program).

Fair warning though, the following will get somewhat involved and I can see how someone might get lost in all of it, so before I go into the nitty gritty, I’d like show what the end result looks like:

When the user first runs the program, they’ll see this:

The “Getting Embedded Music” doesn’t actually take all that long but that’s being done inside a BackgroundWorker anyway. Once that part is done, they’ll next see this:

When the user double-clicks a row, they’ll first see the following:

The files are being saved to a temporary folder which is created in the program’s Application Data folder, and they’re given intentionally ambiguous names with no file extension.

You might want to change that by adding the correct file extension but from my standpoint, I can’t know what type files are in your resources, so all I can do is to look to see if the resource manager is reporting back that it’s a binary file; that is, a byte-array type resource. Given that, I don’t add a file extension because I don’t know what the file actually is.

I’ll go more into this in a bit, but once the user dismisses that warning message, they’ll then see and hear the audio file playing:

*****

The Fundamental Basis Of This Idea

The idea is to find all of the byte array type files in the resources and then extract them – all of them – to  local files in a temporary folder. The fact is, when you add a resources into a program, you lose the reference to where it came from and likewise, what its original file name (and extension) was. To an extent then, I’m “flying blind” in this – all I can actually know is that it’s a binary file.

So the next part of this concept is to try to read the file AS a file which has ID3 tags in it. If it does, then get some of that ID3 tag information and add it to the “yes this is an audio file” list along with that specific tag data.

The name of the group (or artist) and the track name that you saw earlier are from that. Additionally though, I wanted to get the duration of each track and that’s done with a different class. If it can retrieve the name of the group (or artist), the name of the track, and the duration of the audio, then it’s considered to be an audio file and it’s added; if not, it’s rejected.

If one or more of those extracted binary files does NOT have all three of the minimums that I just mentioned, it’s then deleted from the temporary folder (they’ll all be deleted in time, explained shortly).

So that’s the basis: Look to see if it has the ID3 tags and a duration time and if so, keep track of that information and show it in the DataGridView as seen earlier.

When the program first starts up, it looks to see if that temporary folder exists. If it does, that temporary folder and all contents of it are deleted, then it’s re-created. When the program is shut off, the same thing happens BUT – there will be one file left there which I can’t touch: The last audio file played.

It’s set up that on start-up if there’s an exception thrown, a message box will display the exception but on shut-down, no message box is shown (because I know it will leave that one file there and there’s nothing that you or the user can do about it).

The Details – Where The Rubber Meets The Road

None of this is difficult but because it’s multi-part and involves some specialized classes, I can see how someone might can get lost in this next part. If you (or any reader who later reads this) become confused about any of it, just ask here and I’ll do my best to explain.

*****

This actually involves first creating the resources (those MP3 audio files) in a class then compiling that class – along with its resources – into a .dll file. In your program that you display to the user, you’ll then reference that .dll file.

I explained this in somewhat good detail in this post of a while back and the only things that’s changed now is the code that you’ll see there. Please follow the directions that I showed in that post, but in a while here, I’ll give you the new class/code to use. The new one will look for all resources, not just image types (which is what that thread is about).

You do have to be cautious about how many you add. It’s easy to end up with not being able to compile that to a .dll file because you’ll see compile errors indicating that it’s too large for the memory.

In this example, I’m calling the .dll file “MediaResources” and you might want to use that name in your first run of this also. That way when I get to the form’s code, everything will work. In my example here, I only have ten (10) audio files:

Not many at all huh … but in terms of file size, it’s not small:

What I suggest you to do is when you’re adding the resources, add them one at a time and compile it. Did it work? Good – now add another and repeat. At some point it WON’T compile and now you know what the upper boundary is (if it’s documented somewhere, I’ve never found it) and you’ll then know also to remove that last resource.

I’ll add this also: Even though you can’t put many in one .dll file, I can’t think of a reason you’re limited to JUST that one .dll file. I haven’t tried it but it should work. That said though, I’ll go back to what I said early on though: Think about having to distribute this Brobdingnagian program though!

*****

Once you have that done, then the rest is comparatively easy.

In your project, add a reference to that .dll file. You’ll then want to add three more classes to the project by using Add>>Existing and browsing to the .vb classes which I’ll give you following:

I have all four (4) of the classes (three you’ll add to your project and the one for the .dll) zipped up and uploaded here. For completeness, the code for each of those classes is shown below:

 

Id3TagReader.vb

MP3FileInfoReader.vb

AudioInResources.vb

 

…and the one for the .dll file:

MyResources.vb

 

The best way to copy from each of those is to click the link at the top of each of those pages and you’ll see a plain unformatted text file of each one, respectively. Download and extract the zip file though, and you won’t need to do that – just add them to your project like I explained earlier.

*****

Now the code for the two forms:

Form1.vb

PlaySelectedAudioFile.vb

 

 

Ok, now we’re done!

I hope you and others who will later read this find it useful and like I said, if any of it is confusing, just let me know. :)

Still lost in code, just at a little higher level.

:-)