22

I'm trying to play a sound inside a .Net Core console application and I can't figure this out.

I am looking for something managed inside the .Net Core environment, maybe like regular .Net :

// Not working on .Net Core    
System.Media.SoundPlayer player = new System.Media.SoundPlayer(@"c:\mywavfile.wav");
player.Play();

Found an issue on dotnet core Github where they talk about it.

https://github.com/dotnet/core/issues/74

They say there is no high-level API for audio playback but the issue is 9 months old, so I hope there is something new ?

dbraillon
  • 1,742
  • 2
  • 22
  • 34
  • Then simply ask in that thread. .NET Core aims to solve server scenarios at first, and how many servers have sound cards then? – Lex Li Mar 17 '17 at 01:29
  • 3
    Why do you want it from .Net core? In console applications you can use Console.Beep and otherwise I'd take a look at Naudio. – MetaColon Mar 23 '17 at 07:02
  • 1
    Because I'd like to create an assistant that can talk and listen and take advantage of .net core to be able to run from it from almost everywhere – dbraillon Mar 23 '17 at 07:13

5 Answers5

9

There is now a way to do it with NAudio library (since 1.9.0-preview1) but it will only works on Windows.

So using NAudio, here the code to play a sound in .NET Core assuming you are doing it from a Windows environment.

using (var waveOut = new WaveOutEvent())
using (var wavReader = new WaveFileReader(@"c:\mywavfile.wav"))
{
   waveOut.Init(wavReader);
   waveOut.Play();
}

For a more global solution, you should go for @Fiodar's one taking advantage of Node.js.

Ofer Zelig
  • 17,068
  • 9
  • 59
  • 93
dbraillon
  • 1,742
  • 2
  • 22
  • 34
  • 1
    Should "waveOut.Init(mp3Reader);" be "waveOut.Init(wavReader);"? – Ozraptor Jul 18 '19 at 07:24
  • 2
    As an FYI, I found I needed to put a Thread.Sleep(n) immediately after playing the sound file, with a sleep duration of at least the length of the sound being played. This was in a simple dotnet core 2.2 console app running on Windows 10. – Ozraptor Jul 20 '19 at 07:02
  • FYI as of writing this, the latest version of NAudio is 2.1.0, but from he looks of it they ***still*** do not support anything other than windows. There is an item in the latest release notes which says "Improved targeting to make it easier to use on non-Windows platforms" but I have no idea what this means, because there is not a single mention anywhere of any platform other than windows. See https://github.com/naudio/NAudio – Mike Nakis Jan 26 '23 at 15:25
6

As a workaround until .NET Core has audio support, you could try something like this:

public static void PlaySound(string file)
{
    Process.Start(@"powershell", $@"-c (New-Object Media.SoundPlayer '{file}').PlaySync();");
}

Of course this would only work on Windows with PowerShell installed, but you could detect which OS you are on and act accordingly.

joshcomley
  • 28,099
  • 24
  • 107
  • 147
  • 1
    This is horrible, terrible, awful, inadequate, and inapt, but it does solve the immediate problem at hand with minimal effort, i.e. without having to run down rabbit holes. Hopefully, one day Microsoft will provide a proper solution. – Mike Nakis Jan 26 '23 at 15:53
2

Add package System.Windows.Extensions to your project.

Unknow
  • 29
  • 1
1

The best solution for me was to use VLC Media Player. It available on Windows and Linux (maybe mac i suppose ?). So, with this code it's ok (run on windows + linux. I don't know for MAC) :

        public static void Play(string sound)
    {
        string program = "vlc.exe";

        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            program = "cvlc";

        string path = GetPathSound(sound);

        var pi = new ProcessStartInfo(path)
        {
            Arguments = Path.GetFileName(path) + " --play-and-exit",
            UseShellExecute = true,
            WorkingDirectory = Path.GetDirectoryName(path),
            FileName = program,
            Verb = "OPEN",
            WindowStyle = ProcessWindowStyle.Hidden
        };

        Process p = new Process();
        p.StartInfo = pi;
        p.Start();
        p.WaitForExit();
    }
user944696
  • 61
  • 1
  • 7
0

There is a platform-independent way of doing it. Essentially, all of the sound-playing functionality that was available in .NET Framework was Windows-specific; therefore none of it made it into .NET Core.

However, the good news is that Node.js has countless libraries that can play sound on various systems and there is a library available for ASP.NET Core which can talk to Node.js code directly. It's called NodeServices. Don't be put off by the fact that it's only available on ASP.NET Core. Essentially, ASP.NET Core, unlike the .NET Framework version of ASP.NET, is nothing more than a thin layer of web hosting functionality running on top of a standard console app. You don't necessarily have to use it as a web app, but it will provide you with many useful extras, such as an easy to use dependency injection library.

More

This article describes how NodeServices work. It is really straight-forward.

  • 6
    Thanks for sharing but that is outside the .Net Core environment – dbraillon Mar 14 '18 at 18:12
  • 1
    It does not have to be outside .NET Core environment. Any OS and CPU that can run .NET Core can also run Node.js. NodeServices allow you to run .NET Core and Node.js code in the same process. The library runs Node.js code in a completely interactive manner and doesn't just do "fire and forget". For example, after launching Node.js code, it will not get to the next C# statement until Node.js code either errored or called back with the result. Results returned from Node.js become fully usable in .NET Code. You have full control of Node,js app from your .NET application. – Fiodar Sazanavets Mar 15 '18 at 20:14
  • I was looking to solve exactly the same problem and, as far as I know, the only other solution is to use a wrapper library for a native third-party DLL. However, in this case, you have to compile or find an environment-specific version of the original library, most of which are strictly licensed. NodeServices were much easier to use. My specific scenario was remotely playing sound from a .NET Core app on Raspberry Pi and this is how I solved it. – Fiodar Sazanavets Mar 15 '18 at 20:22
  • Alright, I will take a look at it. Thanks by the way. – dbraillon Mar 15 '18 at 21:57