C# Play MP3 file using NAudio from Resource - c#

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

Related

Is there a function that takes a filename from the Image object

I'm using the Movie Maker Library Timeline SDK Control 6.0 dll
And to add a photo you need a STRING of a file name. So far everything is fine
But I want to insert a function that gets an IMAGE object
But the library does not have a function that cables an IMAGE object
What I need is to get the file name out of the IMAGE object
That is: string fileName = image
Image img = default;
using (WebClient client = new WebClient())
{
string url = textBox1.Text;
Stream stream = client.OpenRead(url);
img = Image.FromStream(stream);
axTimelineControl1.AddImageClip(trackIndex: 1, fileName :img.ToString(),
clipStartTime: axTimelineControl1.GetMediaDuration(img.ToString()), clipStopTime: 4);
}
You've got a small bit of an "XY problem" here--you're asking the wrong question. Your axTimelineControl1 expects an image's file name. This implies that it also expects there to be an image saved to disk with that file name.
But all you have is a remote image, behind some URL. client.OpenRead(url) downloads the image into a Stream, but you can't do anything with that directly.
So, you don't want to take that image, and put it into a WinForms Image object. Instead, you want to save that image to disk with a file name, and then give that file name to your axTimelineControl1.
You have a few options for doing that:
1) You could take the Stream you got from client.OpenRead(), turn it into a FileStream and save it to disk.
2) You could use the WebClient to download the image directly to disk, and then give the image's file name to the axTimelineControl1.
Let's do 2) instead. It'll save a few steps.
First, create the file.
string fileName = System.IO.Path.GetTempFileName();
System.IO.File.Create(fileName).Close();
We're creating a "Temp" file here--these are meant to be treated as disposable. Note that Windows doesn't clean them up for you, so once you're done with it, your program should delete it. System.IO.File.Create() gives us a FileStream object, but we don't need it, so we Close() it right away, so that the WebClient will be able to write to our file.
Next, we download our image, and tell WebClient to save it to our newly-created Temp file:
// Defining my own URL here. Feel free to substitute your own.
string url = "https://derpicdn.net/img/view/2018/5/18/1735426.jpeg";
using (var client = new WebClient())
{
client.DownloadFile(url, fileName);
}
Now we have an image on disk, and we can tell the Movie Maker SDK Control where to find it:
float duration = axTimelineControl1.GetMediaDuration(fileName);
axTimelineControl1.AddImageClip(
trackIndex: 1,
fileName: fileName,
clipStartTime: duration,
clipStopTime: 4);
And that should do it.
The entire code listing:
string fileName = System.IO.Path.GetTempFileName();
System.IO.File.Create(fileName).Close();
// Defining my own URL here. Feel free to substitute your own.
string url = "https://derpicdn.net/img/view/2018/5/18/1735426.jpeg";
using (var client = new WebClient())
{
client.DownloadFile(url, fileName);
}
float duration = axTimelineControl1.GetMediaDuration(fileName);
axTimelineControl1.AddImageClip(
trackIndex: 1,
fileName: fileName,
clipStartTime: duration,
clipStopTime: 4);
Don't forget to clean up your temp file!

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

Writing to a file in Windows Phone

I am having trouble creating an IO stream.
I found the example below but for some odd reason the GetResourceStream is not an available in the Application class. Am I missing a reference to some API?
var resource = Application.GetResourceStream(new Uri(#"/YOURASSEMBLYNAME;component/Stations.txt", UriKind.Relative));
StreamReader streamReader = new StreamReader(resource.Stream);
string x = streamReader.ReadToEnd();
If you need to read a String from your file (as I see in your example), you can use:
StorageFile textFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///YOUR FILE PATH"));
String text = await FileIO.ReadTextAsync(textFile );
You can use the methods inside the FileIO class to write to the file as well, both from a text and from a binary buffer.
If you really want to use a buffer stream, you can get it with:
IRandomAccessStream accessStream = await textFile.OpenAsync(FileAccessMode.ReadWrite);

Sevenzip extractFile(String file, Stream stream) method stream parameter. c#

I am trying to access a file in a .7z file. I know the name of the file in the zip folder and that it exists in the .7z file. Previously I've used the ExtractArchive(templocation) which just dumps all the files into a temporary location. Now I want to be able to grab a specific file without extracting the whole .7z file.
7Zip has a class called the SevenZipExtractor that has a method ExtractFile. I would think that is what I am looking for, but I can't find any decent documentation on it.
What I need clarification on is how to go about getting the Stream parameter passed in correctly.
I am using code like this;
//this grabs the zip file and creates a FileInfo array that hold the .7z file (assume there is only one)
DirectoryInfo directoryInfo = new DirectoryInfo(ApplicationPath);
FileInfo[] zipFile = directoryInfo.GetFiles("*.7z");
//This creates the zipextractor on the zip file I just placed in the zipFile FileInfo array
using (SevenZip.SevenZipExtractor zipExtractor = new SevenZip.SevenZipExtractor(zipFile[0].FullName))
//Here I should be able to use the ExtractFile method, however I don't understand the stream parameter, and I can't find any good documentation on the method itself. What is this method looking for?
{
zipExtractor.ExtractFile("ConfigurationStore.xml", Stream stream);
}
Setup a FileStream that SevenZip can write out to:
DirectoryInfo directoryInfo = new DirectoryInfo(ApplicationPath);
FileInfo[] zipFile = directoryInfo.GetFiles("*.7z");
using (SevenZip.SevenZipExtractor zipExtractor = new SevenZip.SevenZipExtractor(zipFile[0].FullName))
{
using (FileStream fs = new FileStream("", FileMode.Create)) //replace empty string with desired destination
{
zipExtractor.ExtractFile("ConfigurationStore.xml", fs);
}
}

Categories