How to play WAV file from Properties.Resources using C# - c#

How can I play a wav file from Properties.Resources?
I try some code, but every time my Priperties.Resource.myFile put me byte[] but my code need string path, not byte[] array.
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.SoundLocation = #"myFile.wav";
player.Play();
I don't want to use some temp file. It is possible play direct from Resource?
Thanks for your advice!

Two ways can do so as far as I know, see below:
Use file path
First put the file in the root folder of the project, then no matter you run the program under Debug or Release mode, the file can both be accessed for sure.
var basePath = System.AppDomain.CurrentDomain.BaseDirectory;
SoundPlayer player = new SoundPlayer();
player.SoundLocation = Path.Combine(basePath, #"./../../Reminder.wav");
player.Load();
player.Play();
Use resource
Follow below animate, add "Exsiting file" to the project.
SoundPlayer player = new SoundPlayer(Properties.Resources.Reminder);
player.Play();
The strength of this way is:
Only the folder "Release" under the "bin" directory need to be copy when run the program.

So, Can I play WAV file from Resource?
You can use the Stream property like this:
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.Stream = new MemoryStream(data);
player.Play();
Where data is the byte[] that you got from the resource file.
UPDATE:
Properties.Resources.myFile should actually be a stream, so use it directly like this:
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.Stream = Properties.Resources.myFile;
player.Play();

For me (VS 2022, .net 6, C # 10) it worked:
Import the "myFile.wav" file into the main directory.
Change in: Properties (myFile.wav) - Copy to Output Directory to: Copy always.
Later it was enough to:
System.Media.SoundPlayer player = new System.Media.SoundPlayer("myFile.wav");
player.Load ();
player.Play ();

Related

Cant play created mp3 file, but can play existing file

I am trying to play a file with the written content of my stream to it. It's really strange because if i just go in and play it manually, that works but whenever i try to play it with the program, there is no sound comming from the clip. (There is content in the file). I downloaded a music file just for test and swapped that name with the "fileName" string variable and that works fine playing the file with the program.
public void PlayAudio(object sender, GenericEventArgs<Stream> args)
{
string fileName = $"{ Guid.NewGuid() }.mp3";
using (var file = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), fileName)))
{
args.EventData.CopyTo(file);
file.Flush();
}
WaveOut waveOut = new WaveOut();
Mp3FileReader reader = new Mp3FileReader(fileName); // If i change "fileName" to my music test file, the program can play it fine. But whenever i switch to the created file name from the Stream. It doesnt play it :O
waveOut.Init(reader);
waveOut.Play();
}
I need to use NAudio because this is going to be running on .net core. So i cant use SoundPlayer just for general information.
Background on project. Before i needed it to .net core, i was just running this code which works perfectly. Plays up the audio directly from the api. However, now i cant use this because .net core doesnt support system.media. hens why i have figured out that i need to load the data into a file, mp3 or wav doesnt mather for me and then play that file up with the content inside.
public void PlayAudio(object sender, GenericEventArgs<Stream> args)
{
SoundPlayer player = new SoundPlayer(args.EventData);
player.PlaySync();
args.EventData.Dispose();
}
I managed to solve it. I do not really know what i did. Because i am certain that i tried this earlier. I did restart pc etc but ye it works now ..
public void PlayAudio(object sender, GenericEventArgs<Stream> args)
{
string fileName = $"{ Guid.NewGuid() }.wav";
using (var file = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), fileName)))
{
args.EventData.CopyTo(file);
file.Flush();
Console.WriteLine(fileName);
}
WaveOut waveOut = new WaveOut();
WaveFileReader reader = new WaveFileReader(fileName);
waveOut.Init(reader);
waveOut.Play();
}

Trouble pathing an audio file using WMPLib

I'm new to C# and pathing files have troubled me for a while.
The file structure to the audio files is as follows:
C:\Users\Username\Documents\Program\Form\WindowsFormApp\Audio Files\name.mp3
My visual studio forms are in:
C:\Users\Username\Documents\Program\Form\WindowsFormApp
I tried referencing audio files by using the following URL:
soundplayer.URL = #"Audio Files\name.mp3";
However, that did not work.
I then placed the folder Audio Files inside practically every other folder. It still did not work.
I tried:
soundplayer.URL = #"..\\Audio Files\name.mp3";
That did not work as well. I cannot simply do the entire path of the audio because it is different on each computer.
How do I path this correctly?
Well, in your case, it would be as follows
using System.IO;
using WMPLib;
WindowsMediaPlayer player;
private void button1_Click(object sender, EventArgs e)
{
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), #"Audio Files\name.mp3");
player = new WindowsMediaPlayer();
FileInfo fileInfo = new FileInfo(path);
player.URL = fileInfo.Name;
player.controls.play();
}
Where
//This function gets the current route of your project and combines it with the subfolder path where your music file is
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), #"Audio Files\name.mp3");

c#, mp3 and file path

Hello I am new at c# and I am doing a small game that I need to play mp3 files.
I've been searching about this and using wmp to do it, like this:
WindowsMediaPlayer myplayer = new WindowsMediaPlayer();
myplayer.URL = #"c:\somefolder\project\music.mp3";
myplayer.controls.play();
I am able to play the file successfully with the full path of the mp3 file. The problem is that I can't find a way to use the file directly from the project folder, I mean, if I copy the project to another computer the path of the mp3 file will be invalid and no sound will be played. I feel that I am at a dead end now, so if someone can help me I would appreciate it! Thanks in advance
Another simple option to use would be:
WindowsMediaPlayer myplayer = new WindowsMediaPlayer();
string mp3FileName = "music.mp3";
myplayer.URL = AppDomain.CurrentDomain.BaseDirectory + mp3FileName;
myplayer.controls.play();
This will play the MP3 from the directory that your executable is located in. It is also important to note that no reflection is needed, which can add unnecessary performance cost.
As a follow up to the comment about embedding the MP3 as a resource, the following code can be implemented once it has been added:
Assembly assembly = Assembly.GetExecutingAssembly();
string tmpMP3 = AppDomain.CurrentDomain.BaseDirectory + "temp.mp3";
using (Stream stream = assembly.GetManifestResourceStream("YourAssemblyName.music.mp3"))
using (Stream tmp = new FileStream(tmpMP3, FileMode.Create))
{
byte[] buffer = new byte[32 * 1024];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
// Creates a temporary MP3 file in the executable directory
tmp.Write(buffer, 0, read);
}
}
WindowsMediaPlayer myplayer = new WindowsMediaPlayer();
myplayer.URL = tmpMP3;
myplayer.controls.play();
// Checks the state of the player, and sends the temp file path for deletion
myplayer.PlayStateChange += (NewState) =>
{
Myplayer_PlayStateChange(NewState, tmpMP3);
};
private static void Myplayer_PlayStateChange(int NewState, string tmpMP3)
{
if (NewState == (int)WMPPlayState.wmppsMediaEnded)
{
// Deletes the temp MP3 file
File.Delete(tmpMP3);
}
}
Add the MP3 file to your project. Also flag it to always copy to output folder. Here you have a tutorial of how to do it (How to include other files to the output directory in C# upon build?). Then you can reference this way:
You have to use:
using System.Windows.Forms;
And then you can use like this:
WindowsMediaPlayer myplayer = new WindowsMediaPlayer();
myplayer.URL = Application.StartupPath + "\music.mp3";
myplayer.controls.play();
This should work for any machine, provided your mp3 & exe are in same folder.
string mp3Path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + mp3filename

How to play a sound that was imported into C# WPF project?

I have an issue with trying to play sound in my WPF application. When I reference the sound from its actual file location, like this,
private void playSound()
{
//location on the C: drive
SoundPlayer myNewSound = new SoundPlayer(#"C:\Users\...\sound.wav");
myNewSound.Load();
myNewSound.Play();
}
it works fine. However, I recently imported the same sound into my project, and when I try to do this,
private void playSound()
{
//location imported in the project
SoundPlayer myNewSound = new SoundPlayer(#"pack://application:,,,/sound.wav");
myNewSound.Load();
myNewSound.Play();
}
it produces an error and the sound won't play. How can I play the sound file imported into my project?
Easiest/shortest way for me is to change Build Action of added file to Resource, and then just do this:
SoundPlayer player = new SoundPlayer(Properties.Resources.sound_file);//sound_file is name of your actual file
player.Play();
You are using pack Uri as argument, but it needs either a Stream or a filepath .
As you have added the file to your project, so change its Build Action to Content , and Copy To Output Directory to Always.
using (FileStream stream = File.Open(#"bird.wav", FileMode.Open))
{
SoundPlayer myNewSound = new SoundPlayer(stream);
myNewSound.Load();
myNewSound.Play();
}
You can do it with reflection.
Set the property Build Action of the file to Embedded Resource.
You can then read it with:
var assembly = Assembly.GetExcetutingAssembly();
string name = "Namespace.Sound.wav";
using (Stream stream = assembly.GetManifestResourceStream(name))
{
SoundPlayer myNewSound = new SoundPlayer(stream);
myNewSound.Load();
myNewSound.Play();
}

Getting a media file from resources

I have added a notification sound for some text message as a reference of the Main file of my project and try to make it work as follows
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("SignInSound.wav");
System.Media.SoundPlayer player = new System.Media.SoundPlayer(s);
player.Play();
I have the sound played, but it is not absolutely the one I added. Instead standard windows sound is played.
Any ideas?
Update
The issue is in getting the file from resources
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("SignInSound.wav");
Judging by the documentation, your resource stream is bad.
The Play method plays the sound using a new thread. If you call Play
before the .wav file has been loaded into memory, the .wav file will
be loaded before playback starts. You can use the LoadAsync or Load
method to load the .wav file to memory in advance. After a .wav file
is successfully loaded from a Stream or URL, future calls to playback
methods for the SoundPlayer will not need to reload the .wav file
until the path for the sound changes.
If the .wav file has not been
specified or it fails to load, the Play method will play the default
beep sound.
So the problem is that GetManifestResourceStream() is not doing what you think it's doing.
Solution (based on ResourceManager)
var thisType = this.GetType();
var assembly = thisType.Assembly;
var resourcePath = string.Format("{0}.{1}", assembly.GetName().Name, thisType.Name);
var resourceManager = new ResourceManager(resourcePath, assembly);
var resourceName = "SignInSound";
using ( Stream resourceStream = resourceManager.GetStream(resourceName) )
{
using ( SoundPlayer player = new SoundPlayer(resourceStream) )
{
player.PlaySync();
}
}
It seems that the System.Media.SoundPlayer class has a very limited amount of WAV formats it supports.
I have tried using the string path constructor, and it works with some .wav files, while it fails with others.
Here is some sample code. If you're using Windows 7, you can check it for yourself, just make a default new Windows Forms Application and add one button to it.
Notice how the code works for the "success" string, and throws an InvalidOperationException for the "fail" string.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
System.Media.SoundPlayer player;
public Form1()
{
InitializeComponent();
string success = #"C:\Windows\Media\Windows Battery Critical.wav";
string fail = #"C:\Windows\Media\Sonata\Windows Battery Critical.wav";
player = new System.Media.SoundPlayer(success);
}
private void button1_Click(object sender, EventArgs e)
{
player.Play();
}
}
}
Notice that the file under "success" has a bit rate of 1411 kbps, while the other one has 160 kbps.
Try your code with a WAV file with a bit rate of 1411 kbps and let us know how it works.

Categories