c#, mp3 and file path - c#

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

Related

how to save a file in the directory you are currently in (COSMOS)

So I'm making a Cosmos OS and I am having some trouble. I have this code that makes a file. what it does is it asks What is the name of the file and extension then what is the files contents then makes the file. The Problem is is that it only saves to main directory of 0:\ and doesn't work when you make a file while in a directory like 0:\TEST. This is the code I have for the file creator. I want to know if it's possible to make it save the file to the directory you are currently in.
Console.Write("File Name (put in the extension name):");
var finput = Console.ReadLine().ToLower();
string fileName = finput;
// Check if file already exists. If yes, delete it.
if (File.Exists(fileName))
{
File.Delete(fileName);
}
Console.Write("File Contents:\n");
var text = Console.ReadLine().ToLower();
using (FileStream fs = File.Create(fileName))
{
// Add some text to file
Byte[] title = new UTF8Encoding(true).GetBytes(text);
fs.Write(title, 0, title.Length);
}
Console.WriteLine("File Made!");
This may be a late answer, but try this:
var dir = Directory.GetCurrentDirectory;
var file = (filename);
File.Create(dir + "\\" + file);
I haven't checked this code but it should be something like this. This (should) do the same as your code above.

Unzip .zip file from Assets folder to Internal Storage (Xamarin.Android)

So the question is pretty simple. I'm using Xamarin.Android and I have a zip file in the Assets folder named "MyZipFile.zip", which I want extracted to the following path: System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
It sounds simple enough, but I cannot figure out how to read the Asset into memory through the AssetManager and then unzip it at the targeted location.
Is there a simple way to do this?
The Android Java framework includes a Java.Util.Zip package, so without adding any additional app libraries, I directly use it instead of using C# framework code, thus no bloat that linking can not remove.
So basically you are creating an asset stream and feeding that to a ZipInputStream and iterating over each ZipEntry in that zip stream to either create directories or files to your destination path.
UnZipAssets
public void UnZipAssets(string assetName, string destPath)
{
byte[] buffer = new byte[1024];
int byteCount;
var destPathDir = new Java.IO.File(destPath);
destPathDir.Mkdirs();
using (var assetStream = Assets.Open(assetName, Android.Content.Res.Access.Streaming))
using (var zipStream = new ZipInputStream(assetStream))
{
ZipEntry zipEntry;
while ((zipEntry = zipStream.NextEntry) != null)
{
if (zipEntry.IsDirectory)
{
var zipDir = new Java.IO.File(Path.Combine(destPath, zipEntry.Name));
zipDir.Mkdirs();
continue;
}
// Note: This is deleting existing entries(!!!) for debug purposes only...
#if DEBUG
if (File.Exists(Path.Combine(destPath, zipEntry.Name)))
File.Delete(Path.Combine(destPath, zipEntry.Name));
#endif
using (var fileStream = new FileStream(Path.Combine(destPath, zipEntry.Name), FileMode.CreateNew))
{
while ((byteCount = zipStream.Read(buffer)) != -1)
{
fileStream.Write(buffer, 0, byteCount);
}
}
Log.Debug("UnZipAssets", zipEntry.Name);
zipEntry.Dispose();
}
}
}
Usage:
UnZipAssets("gameModLevels.zip", Path.Combine(Application.Context.CacheDir.AbsolutePath, "assets"));
Note: Even through the asset/zip steam is fast, depending upon number/size of the zip entries and the speed of the flash the entry is being written to, this should be done on a background thread as not to block UI thread and cause an ANR

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

AXWindowsMediaPlayer not finding embedded resource MP3

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

WP8/VS2013 MediaLibrary Songs collection is empty

I'm having a play with writing a mp3 player app for WP8, using MediaLibrary to handle the phone's own mp3 collection.
I want to test the result in the phone emulator on VS2013, but when I use the following code:
using (MediaLibrary library = new MediaLibrary())
{
SongCollection songs = library.Songs;
Song song = songs[0];
MediaPlayer.Play(song);
}
The song collection is empty, presumably because VS doesn't have any knowledge of a media library with songs in.
Is there any way to test this in the emulator using a fake medialibrary or for VS to use windows' media library? I just want to see (or hear) the code working before I proceed :)
I have managed to find a workaround!
If you add an mp3 file to the app's assets, the following code will add the mp3 to the media player library:
private void AddSong()
{
Uri file = new Uri("Assets/someSong.mp3", UriKind.Relative);
//copy file to isolated storage
var myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
var fileStream = myIsolatedStorage.CreateFile("someSong.mp3");
var resource = Application.GetResourceStream(file);
int chunkSize = 4096;
byte[] bytes = new byte[chunkSize];
int byteCount;
while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
{
fileStream.Write(bytes, 0, byteCount);
}
fileStream.Close();
Microsoft.Xna.Framework.Media.PhoneExtensions.SongMetadata metaData = new Microsoft.Xna.Framework.Media.PhoneExtensions.SongMetadata();
metaData.AlbumName = "Some Album name";
metaData.ArtistName = "Some Artist Name";
metaData.GenreName = "test";
metaData.Name = "someSongName";
var ml = new MediaLibrary();
Uri songUri = new Uri("someSong.mp3", UriKind.RelativeOrAbsolute);
var song = Microsoft.Xna.Framework.Media.PhoneExtensions.MediaLibraryExtensions.SaveSong(ml, songUri, metaData, Microsoft.Xna.Framework.Media.PhoneExtensions.SaveSongOperation.CopyToLibrary);
}
I also needed to add:
using System.IO.IsolatedStorage;
I would love to claim credit for this, but I found the answer here:
http://social.msdn.microsoft.com/forums/wpapps/en-US/f5fa73da-176b-4aaa-8960-8f704236bda5/medialibrary-savesong-method
By default the media library on the emulator is empty. I also do not think it is possible to automagically hook up your dev machine's music folder to the emulator to test that way. It might be possible to manually configure the emulated phone with an email account! and save music onto it that way, but even if that worked you'd have to do it each and every time you restart the emulator.
Best way to test would be t deploy to a real device.

Categories