AXWindowsMediaPlayer not finding embedded resource MP3 - c#

I have a embedded resource file (MP3 to be exact) that plays a short boop. I wanted it for easy transport of the file since I have a lot more of them that I'm looking to add in.
When I try to play it, WMP just says it cannot find the file.
I'm using axWindowsMediaPlayer1.URL = #"ultraelecguitar.Properties.Resources.pitchedbeep"; to access it. It is added in the resource manager, and marked as a embedded resource. When I run my program with the file in the directory, it works just fine. When I don't, it doesn't work at all.

If you save resource as temporary file then you could provide it's path as url.
static void Main(string[] args)
{
var wmp = new WMPLib.WindowsMediaPlayer();
wmp.URL = CreateTempFileFromResource("ConsoleApplication1.mp3.somefile.mp3");
Console.ReadKey();
}
private static string CreateTempFileFromResource(string resourceName)
{
var tempFilePath = Path.GetTempFileName() + Path.GetExtension(resourceName);
using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
using (var tempFileStream = new FileStream(tempFilePath, FileMode.Create))
{
resourceStream.CopyTo(tempFileStream);
}
return tempFilePath;
}

Related

XML file from ZIP Archive is incomplete in C#

I've work with large XML Files (~1000000 lines, 34mb) that are stored in a ZIP archive. The XML file is used at runtime to store and load app settings and measurements. The gets loadeted with this function:
public static void LoadFile(string path, string name)
{
using (var file = File.OpenRead(path))
{
using (var zip = new ZipArchive(file, ZipArchiveMode.Read))
{
var foundConfigurationFile = zip.Entries.First(x => x.FullName == ConfigurationFileName);
using (var stream = new StreamReader(foundConfigurationFile.Open()))
{
var xmlSerializer = new XmlSerializer(typeof(ProjectConfiguration));
var newObject = xmlSerializer.Deserialize(stream);
CurrentConfiguration = null;
CurrentConfiguration = newObject as ProjectConfiguration;
AddRecentFiles(name, path);
}
}
}
}
This works for most of the time.
However, some files don't get read to the end and i get an error that the file contains non valid XML. I used
foundConfigurationFile.ExtractToFile();
and fount that the readed file stops at line ~800000. But this only happens inside this code. When i open the file via editor everything is there.
It looks like the zip doesnt get loaded correctly, or for that matter, completly.
Am i running in some limitations? Or is there an error in my code i don't find?
The file is saved via:
using (var file = File.OpenWrite(Path.Combine(dirInfo.ToString(), fileName.ToString()) + ".pwe"))
{
var zip = new ZipArchive(file, ZipArchiveMode.Create);
var configurationEntry = zip.CreateEntry(ConfigurationFileName, CompressionLevel.Optimal);
var stream = configurationEntry.Open();
var xmlSerializer = new XmlSerializer(typeof(ProjectConfiguration));
xmlSerializer.Serialize(stream, CurrentConfiguration);
stream.Close();
zip.Dispose();
}
Update:
The problem was the File.OpenWrite() method.
If you try to override a file with this method it will result in a mix between the old file and the new file, if the new file is shorter than the old file.
File.OpenWrite() doenst truncate the old file first as stated in the docs
In order to do it correctly it was neccesary to use the File.Create() method. Because this method truncates the old file first.

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();
}

How can I write to a specific location in Windows Phone 8

When I press a button, I want it to overwrite a file to a specific folder.
I use this code:
private void btnArial_Click(object sender, RoutedEventArgs e)
{
string cssDocument = "body{font-family:\"Arial\";}";
//I want to write file style.css to folder css inside html
string path = Package.Current.InstalledLocation.Path + "\\Html\\css\\style.css";
if (File.Exists(path))
{
StreamWriter writer = new StreamWriter(path);
writer.Write(cssDocument);
writer.Close();
}
changeStyle(new FontFamily("Arial"));
}
When I tested on emulator and actual devide, it worked properly.
But when I submit app to store, it got error - the app exits when I press that button.
The install directory (Package.Current.InstalledLocation) is a read-only location. Unfortunately, due to the way that Visual Studio optimizes development-time deployment, it is set to read-write when the app is deployed from VS. That's why you see a difference in behavior after you submit the app to the store.
If you need to modify a file in your install directory, you must first copy it over to a writeable location - eg. your Local folder.
I prefer using Isolated storage in WP8 to write files and it never fails. Also you can use Windows.Storage apis.
private async void MyButton_Click(object sender, RoutedEventArgs e)
{
string cssDocument = "body{font-family:\"Arial\";}";
// using Windows.Storage
StorageFolder folder = ApplicationData.Current.LocalFolder;
folder = await folder.CreateFolderAsync("HTML", CreationCollisionOption.OpenIfExists);
folder = await folder.CreateFolderAsync("CSS", CreationCollisionOption.OpenIfExists);
StorageFile file = await folder.CreateFileAsync("style.css", CreationCollisionOption.ReplaceExisting);
using (var writer = new StreamWriter(await file.OpenStreamForWriteAsync()))
{
writer.Write(cssDocument);
}
// using using System.IO.IsolatedStorage;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.DirectoryExists("HTML/CSS"))
store.CreateDirectory("HTML/CSS");
using (var writer = new StreamWriter(store.OpenFile("HTML/CSS/style.css", FileMode.Create)))
{
writer.Write(cssDocument);
}
}
changeStyle(new FontFamily("Arial"));
}
Exactly..
Write the file in Isolated storage. Its easier and pretty straight forward. The files here can be accessed, viewed, modified, removed, replaced in a very clear way. I personally prefer the Isolated Storage.

C# Play MP3 file using NAudio from Resource

I have a Windows Forms Application where I'm trying to simply play an MP3 file from the Resource using the NAudio library.
I believe what needs to be done is to stream the file somehow, here is an example of NAudio, unfortunately it accepts File path string as an argument.
private WaveStream CreateInputStream(string fileName)
{
WaveChannel32 inputStream;
if (fileName.EndsWith(".mp3"))
{
WaveStream mp3Reader = new Mp3FileReader(fileName);
inputStream = new WaveChannel32(mp3Reader);
}
else
{
throw new InvalidOperationException("Unsupported extension");
}
volumeStream = inputStream;
return volumeStream;
}
To play the file:
waveOutDevice = new WaveOut();
mainOutputStream = CreateInputStream("C:\\song.mp3");
Works fine with normal files, how would I go about files that are located in the Resources?
Thank you.
The Mp3FileReader class can be constructed from either a filename or a System.IO.Stream. So what you need is to read the MP3 resource as a stream. How you do that depends on how you've added the resource.
Resources added using the Properties/Resources.resx file (managed through the application properties dialog) are accessible through the Properties.Resources object. Known resource types (images, etc) should be represented here by their appropriate types, but MP3 files are accessed as byte[]. You can create a MemoryStream from the resource and use that to construct the Mp3FileReader like so:
MemoryStream mp3file = new MemoryStream(Properties.Resources.MP3file);
Mp3FileReader mp3reader = new Mp3FileReader(mp3file);
Other resource methods differ in the details of how you get the stream, but apart from that are basically the same. If you add an MP3 file to your project with the Embedded Resource build action, you can use the following:
public Stream GetResourceStream(string filename)
{
Assembly asm = Assembly.GetExecutingAssembly();
string resname = asm.GetName().Name + "." + filename;
return asm.GetManifestResourceStream(resname);
}
...
Stream mp3file = GetResourceStream("some file.mp3");
Mp3FileReader mp3reader = new Mp3FileReader(mp3file);
WPF resources are different again, using the pack:... uri format and Application.GetResourceStream.
In all cases you should, of course, dispose the Stream once you're done reading it.
Convert it to .wav using http://media.io/
then all u need to do is
(new System.Media.SoundPlayer(ProjectName.Properties.Resources.wavfilename)).Play();

Categories