I am trying to convert my .net project to .net core (IoT core). Everything is working except my "system.media" block as .net core doesn't come with system.media at all. My options to this is to use NAudio apparently. However, I have no clue how to make NAudio play audio from a Stream.
This is the current code I am trying to convert with NAudio. Any suggestions?
public void PlayAudio(object sender, GenericEventArgs<Stream> args)
{
SoundPlayer player = new SoundPlayer(args.EventData);
player.PlaySync();
args.EventData.Dispose();
}
I tried with this code but got no success.
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);
}
}
}
}
Have you tried using the AudioGraph APIs? These are a great way to play audio on IoT Core. I've used it with success on a Raspberry Pi.
Related
I am trying to make an mp3 player by streaming. The mp3 file which is on the internet source can be played in real-time in this project. Also I want to make it supports Pause, Stop, Forward, Backward. To get these features, I need to write a flexible player.
So I wrote this code:
WaveOut outer;
AcmMp3FrameDecompressor decompressor;
BufferedWaveProvider provider;
public void Play()
{
Task.Run(() =>
{
var response = WebRequest.Create(url).GetResponse();
var responseStream = response.GetResponseStream();
Mp3Frame frame;
byte[] buffer = new byte[30000];
int bytesRead = 0;
MemoryStream ms = new MemoryStream();
ReadFullyStream fully = new ReadFullyStream(ms);
do
{
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, bytesRead);
frame = Mp3Frame.LoadFromStream(fully);
if (decompressor == null)
{
decompressor = CreateFrameDecompressor(frame) as AcmMp3FrameDecompressor;
provider = new BufferedWaveProvider(decompressor.OutputFormat);
provider.BufferDuration = TimeSpan.FromSeconds(50);
outer = new WaveOut();
outer.Init(provider);
outer.Play();
}
int decompressed = decompressor.DecompressFrame(frame, buffer, 0);
provider.AddSamples(buffer, 0, decompressed);
}
while (bytesRead > 0);
});
}
In the code above it throws an exception because of the frame is null. It means LoadMp3FromStream doesn't work for MemoryStream. How can I fix it?
If you get a null MP3 frame then this simply means it could not find an MP3 frame in the input data. So are you sure it's valid MP3 you are passing in.
Also you may want to check out my blog post about playing streaming MP3 and see if that code works for your 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);
}
}
}
}
}
}
what i am trying to do is stream audio from this site (http://www.dubstep.net/track/5436). which at this point im not to sure if it is possible to stream the audio from the site.
i have tried to use naudio with this code
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);
}
}
}
}
}
but since this site doesn't have a .mp3 after it this will not work..
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/
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();