How to play .mp3 file from resources in C#? - c#

I put music.mp3 in resources and then I added Windows Media Player to references. I wrote this code:
WindowsMediaPlayer wmp = new WindowsMediaPlayer();
wmp.URL = "music.mp3";
wmp.controls.play();
It doesn't work. How can I play .mp3 file from resources?

I did it:
WindowsMediaPlayer wmp = new WindowsMediaPlayer();
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PostGen.Resources.Kalimba.mp3");
using (Stream output = new FileStream ("C:\\temp.mp3", FileMode.Create))
{
byte[] buffer = new byte[32*1024];
int read;
while ( (read= stream.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
wmp.URL = "C:\\temp.mp3";
wmp.controls.play();
We have to delete this temporary file:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
File.Delete("C:\\temp.mp3");
}

I wrapped mp3 decoder library and made it available for .net developers. You can find it here:
http://sourceforge.net/projects/mpg123net/
Included are the samples to convert mp3 file to PCM, and read ID3 tags.
Read your resource, convert it to PCM and output it to waveOut class that is available as interop .NET component. No need to create temp files.
waveOut classes available also on sourceforge:
http://windowsmedianet.sourceforge.net/

Or Tyr this;
var file = $"{Path.GetTempPath()}temp.mp3";
if (!File.Exists(file))
{
using (Stream output = new FileStream(file, FileMode.Create))
{
output.Write(Properties.Resources.Kalimba, 0, Properties.Resources.Kalimba.Length);
}
}
var wmp = new WindowsMediaPlayer { URL = file };
wmp.controls.play();

Related

Naudio How to play a MP3 in a byte[] variable

I read a Mp3 Sound from a database and I save it in a byte[] variable, I can save the byte in a file and play it, but I want to play the file directly without save the file in the disk.
I am developing in WPF.
byte[] array = Word_Sounds_DB.Records[0].Sound1;
FileStream fs = new FileStream("a.mp3",FileMode.Create);
{
fs.Write(array, 0, array.Length);
}
fs.Close();
using (var ms = File.OpenRead("a.mp3"))
using (var rdr = new Mp3FileReader(ms))
using (var wavStream = WaveFormatConversionStream.CreatePcmStream(rdr))
using (var baStream = new BlockAlignReductionStream(wavStream))
using (var waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
{
waveOut.Init(baStream);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(100);
}
}
Use a MemoryStream instead of FileStream's. Also pay attention to MemoryStream's read/write position after setting it up for consumption by NAudio (see here for some related info: memorystream(byte[]) vs memorystream.write(byte[])).

How to access a binary resource file from a location in the application package in UWP (Windows 10)

Under Windows 8.1 (Silverlight), my phone oriented C# application was using the following code to access a binary file from my application package:
BinaryWriter fileWriter = new BinaryWriter(new IsolatedStorageFileStream("myWorkingStreamIOfile.pcm", FileMode.Create, fileStorage));
var uri = new Uri("assets/ myFileInMyProjectAssets.pcm", UriKind.Relative);
var res = App.GetResourceStream(uri);
long fileLength = res.Stream.Length;
BinaryReader fileReader = new BinaryReader(res.Stream);
var buffer = new byte[1024];
int readCount = 0;
while (readCount < fileLength)
{
int read = fileReader.Read(buffer, 0, buffer.Length);
readCount += read;
fileWriter.Write(buffer, 0, read);
}
But “GetResourceStream” is not available anymore under UWP. Any help on how the above can be achieve under Window 10 would be very welcomed.
Thanks!
The main difference is how to open the files. In the example below I open the file from /Assets folder inside the application package (remember to set file to Build Action as Content and Copy to output directory) and then I copy the binary content to a file in the local app data folder, in the same way as in your code.
Also I omitted the checks, but StorageFile.GetFileFromApplicationUriAsync() will throw an exception if the file is not found.
// Create or overwrite file target file in local app data folder
var fileToWrite = await ApplicationData.Current.LocalFolder.CreateFileAsync("myWorkingStreamIOfile.pcm", CreationCollisionOption.ReplaceExisting);
// Open file in application package
var fileToRead = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/myFileInMyProjectAssets.pcm", UriKind.Absolute));
byte[] buffer = new byte[1024];
using (BinaryWriter fileWriter = new BinaryWriter(await fileToWrite.OpenStreamForWriteAsync()))
{
using (BinaryReader fileReader = new BinaryReader(await fileToRead.OpenStreamForReadAsync()))
{
long readCount = 0;
while (readCount < fileReader.BaseStream.Length)
{
int read = fileReader.Read(buffer, 0, buffer.Length);
readCount += read;
fileWriter.Write(buffer, 0, read);
}
}
}
Here is a good resource on the URI format for universal apps: https://msdn.microsoft.com/en-us/library/windows/apps/jj655406.aspx

Copy and update content of actively recording Wav file to a new file

I have an active audio recording happening in WAV format with NAudio Library.
private void RecordStart() {
try {
_sourceStream = new WaveIn {
DeviceNumber = _recordingInstance.InputDeviceIndex,
WaveFormat =
new WaveFormat(
44100,
WaveIn.GetCapabilities(_recordingInstance.InputDeviceIndex).Channels)
};
_sourceStream.DataAvailable += SourceStreamDataAvailable;
if (!Directory.Exists(_recordingInstance.AudioFilePath)) {
Directory.CreateDirectory(_recordingInstance.AudioFilePath);
}
WaveFileWriter _waveWriter = new WaveFileWriter(
_recordingInstance.AudioFilePath + _recordingInstance.AudioFileName,
_sourceStream.WaveFormat);
_sourceStream.StartRecording();
}
catch (Exception exception) {
Log.Error("Recording failes", exception);
}
}
private void SourceStreamDataAvailable(object sender, WaveInEventArgs e) {
if (_waveWriter == null) return;
_waveWriter.Write(e.Buffer, 0, e.BytesRecorded);
_waveWriter.Flush();
}
I want to copy the latest available content to another location. The copied file should be in WAV format, and should be able to play the available duration. Update the destination file, whenever more content is available.
I have Tried the following sample code (using NAudio) with a static WAV file, but the solution is not working.
The resulting WAV file created is corrupted - not in the correct format.
using (WaveFileReader reader = new WaveFileReader(remoteWavFile))
{
byte[] buffer = new byte[reader.Length];
int read = reader.Read(buffer, 0, buffer.Length);
}
When the recording is in progress, the code throws an exception "File is in use by another application".
I have solved the problem with help of NAudio Library itself.
When we only use the WaveFileReader class of NAudio. It will throw the exception - "file is in use by another application".
So I had to create a file stream, which opens the source file - live recording file, with File.Open(inPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) then pass this stream as an input of WaveFileReader.
Then create a WaveFileWritter class of NAudio, with the same WavFormat of the reader.
copied below is the code, i have used.
public static void CopyWavFile(string inPath, string outPath){
using (var fs = File.Open(inPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
using (var reader = new WaveFileReader(fs)){
using (var writer = new WaveFileWriter(outPath, reader.WaveFormat)){
reader.Position = 0;
var endPos = (int)reader.Length;
var buffer = new byte[1024];
while (reader.Position < endPos){
var bytesRequired = (int)(endPos - reader.Position);
if (bytesRequired <= 0) continue;
var bytesToRead = Math.Min(bytesRequired, buffer.Length);
var bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0){
writer.Write(buffer, 0, bytesRead);
}
}
}
}
}
}

How to merge MP3 files in WP8 (edit)

I have list of MP3 files that I would like to merge them into one file. I downloaded files locally into isolated storage, but I have no idea how to merge them. Google doesn't help either. I don't know if its possible in WP8. (2) If not possible what specific solution you could advice (I also have my files in web).
I write below code for merging, but this always writes the last file.
string[] files = new string[] { "001000.mp3", "001001.mp3", "001002.mp3", "001003.mp3", "001004.mp3", "001005.mp3", "001006.mp3", "001007.mp3" };
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
string newFileName = "001.mp3";
foreach (string _fileName in files)
{
if (storage.FileExists(_fileName))
{
byte[] bytes = new byte[1];
using (var f = new IsolatedStorageFileStream(_fileName, FileMode.Open, storage))
{
bytes = new byte[f.Length];
int byteCount;
using (var isfs = new IsolatedStorageFileStream(newFileName, FileMode.OpenOrCreate, storage))
{
while ((byteCount = f.Read(bytes, 0, bytes.Length)) > 0)
{
isfs.Write(bytes, 0, byteCount);
isfs.Flush();
}
}
}
}
}
}
How can i add (merge) files to end of the newly created file?
I added isfs.Seek(0, SeekOrigin.End); before writing to file. This is how we can simply merge same bitrate mp3 files.
the code looks like below:
using (var isfs = new IsolatedStorageFileStream(newFileName, FileMode.OpenOrCreate, storage))
{
isfs.Seek(0, SeekOrigin.End); //THIS LINE DID SOLVE MY PROBLEM
while ((byteCount = f.Read(bytes, 0, bytes.Length)) > 0)
{
isfs.Write(bytes, 0, byteCount);
isfs.Flush();
}
}
Please improve my code if it seems to be longer.

How to play .mp3 file from online resources in C#?

my question is very similar to this question
I have music urls. Urls like http://site.com/audio.mp3 . I want play
this file online, like youtube. Do you know a class or code can do
this ?
How can I play an mp3 online without downloading all for to play it?
to play the file cache will be created but at least play the file immediately
I found the solution with the library NAudio
http://naudio.codeplex.com/
SOLUTION
public static void PlayMp3FromUrl(string url)
{
using (Stream ms = new MemoryStream())
{
using (Stream stream = WebRequest.Create(url)
.GetResponse().GetResponseStream())
{
byte[] buffer = new byte[32768];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
}
ms.Position = 0;
using (WaveStream blockAlignedStream =
new BlockAlignReductionStream(
WaveFormatConversionStream.CreatePcmStream(
new Mp3FileReader(ms))))
{
using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
{
waveOut.Init(blockAlignedStream);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing )
{
System.Threading.Thread.Sleep(100);
}
}
}
}
}`
I FOUND THE ANSWER HERE
Play audio from a stream using C#
Many libraries like IrKlang provide streaming audio support, if you're looking for minimal development effort I'd suggest you take a look at it!
http://www.ambiera.com/irrklang/

Categories

Resources