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.
Related
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();
}
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();
}
My code creates a power point presentation and three audio files.
I want to know the length of those audio files after the presentation is created so I use:
double duration = 0;
WindowsMediaPlayer wmp = new WindowsMediaPlayer();
IWMPMedia mediainfo = wmp.newMedia(file);
duration = mediainfo.duration;
wmp.close();
return duration;
To create the audio files I use
public void CreateAudio(string text)
{
y++;
synth = new SpeechSynthesizer();
AudioStream = new FileStream(folder + #"\audio\a" + #y.ToString() + #".wav", FileMode.OpenOrCreate);
//synth.SpeakCompleted += new EventHandler<SpeakCompletedEventArgs>(synth)
synth.SetOutputToWaveStream(AudioStream);
synth.SpeakAsync(text);
}
private void synth_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
{
synth.Dispose();
}
The problem is that after the presentation is created, only the shortest audio file returns a length, the rest return 0.
If I check manually, I see 3 audio files with a valid length property, but the program doesn't read that for some reason.
My attempt at disposing the synth didn't change a thing, nor did using syth.speak so I must have done something terribly wrong at using and managing my objects and memory but I don't know what or where.
If I use the code to check the length of the audio files created in a different code for example, it works perfectly, just when I create them and want to check their length something goes wrong.
How can I hardcode the code in order to pull the .wav file from the project?
As well as where should I put the .wav file?
The code I am currently using is:
private void timer2_Tick(object sender, EventArgs e)
{
SoundPlayer simpleSound = new SoundPlayer(#"c:\Windows\Media\dj.wav");
simpleSound.Play();
}
I just want the path #"c:\Windows\Media\dj.wav" to be for that content folder... So that when I deploy the application to another computer it comes with it....
Use GetManifestResourceStream.
var path = "MyApplicationNamespace.Content.dj.wav";
var assembly = Assembly.GetExecutingAssembly();
using( var soundStream = assembly.GetManifestResourceStream( path ) )
using( var soundPlayer = new SoundPlayer( soundStream ) )
{
soundPlayer.Play();
}
The string passed to GetManifestResourceStream must be fully qualified with your application's root namespace and the directory tree the wave file resides in.
You also need to set the Build Action for the wave file to Embedded Resource in the properties window.
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 ();