Ok so there are a couple inherent understandings
1) I know the SoundPlayer class, despite being able to load System.IO.Stream interfaces, is 100% incapable of playing more than one sound at once, despite all the multithreading and multiple-property usage.
2) I know WMPLib is the go to answer for playing multiple files. Sadly, it requires a URL, and according to MSDN, that URL cannot point to a resource. WindowsMediaPlayer class is also incapable of loading IO.Stream interfaces.
3) I saw a hack where you write out a temporary audio file to disk and have WMPlib play that, and to that I say "polite pass"
Simply put, I do not want users messing with the source audio files. I intend to distribute just the executable and not a zip containing a tonn of files. This is why I opted for the .resx
Is there not another audio player available to C# that can take an IO.Stream that is capable of playing more than one thing at a time?
My little program is a text adventure, and I intend to have a little ambient loop playing in the background while some sound effects play to reflect what's happening on the screen.
Related
I’m developing an UWP app that should be able to play videos transferred through a custom TCP protocol implementation.
Videos are MP4, so there’s no need to decode frames.
My current solution is to download the file first, and then allow the user to play it, but with big files this is quite annoying.
As a workaround I tried to implement IRandomAccessStream to feed the MediaPlayer while the file gets downloaded, but this isn’t a good solution for sure as there’s no buffering (and the video is just laggy on bad networks) nor visual download progress in the TransportControls.
I know it is possible to create a custom MediaStreamSource, but it requires known encoding properties to be created and anyway it sounds like an overkill to have to decode frames by myself to feed it.
So I’m wondering if there’s any solution to my problem.
I developed a socket based p2p system where i stream mp4 video from a client to a server. The video data are transferred using byte[].
The transfer works, however i am struggling to figure out how i could play, in continuous, a mp4 file being transferred to another PC? The PC application, that would play the file, is in WPF.
I tried using a MediaElement to play the file, being written to the disk, but for some reason it doesnt play at all. I can play it with VideoLan tho.
Any hint of where to look? I am lost from here!
Thanks in advance!
Its going to be different with every player. Mp4 is probably the worst possible container for this application. The container is designed to be used with random access media, such has a hard disk. The player has the ability, and sometimes requirement to seek around within the file, and not just plat start to finish. Either you need to make the protocol mp4 aware (parse the file, and download the block that will most like be needed next), or use a streamable container such as TS, or flv.
Its is also possible that the player knows the file is incomplete. The atoms sizes are encoded within the file. If the file size doest match, the combined atom sizes, the player could assume a corrupt file.If this is what is happening, you can try to pre allocate the file. it may trick the player enough to play
Is it possible that the System.Media.SoundPlayer can not play Windows System Sounds found in c:\Windows\Media??
I have the code:
using (var soundPlayer =
new SoundPlayer(#"c:\Windows\Media\Landscape\Windows Notify.wav"))
{
soundPlayer.Play();
}
Yet when I run this code I get the error:
Sound API only supports playing PCM wave files.
Am I missing something? Is there a way to play these files from a WPF application? (without converting them to PCM)
The SystemSounds class contains the following predefined system sounds:
Asterisk
Beep
Exclamation
Hand
Question
So for example, to play the Stop:
System.Media.SystemSounds.Hand.Play();
All other sounds require you read the desired sound from the registry and play it with code like this:
SoundPlayer simpleSound = new SoundPlayer(#"c:\Windows\Media\Landscape\Windows Notify.wav");
This was an interesting question, but has a simple answer. After reading about this problem, I tried out your code and got the same problem, so then I searched online for a solution. While not finding an exact solution, I did find the SoundPlayer not playing any bundled windows sounds PCM wav files post here on StackOverflow that showed some code that played an audio file from the Windows\Media folder successfully.
I tried that code and it worked, so then I just had to work out why your example didn't work. I checked for any differences between the audio file that did play and your notify audio file in an audio editor, but they were both definitely WAV files.
I tried playing a different audio file from the Windows\Media\Landscape folder and got the same error. I then tried playing an audio file from a different sub folder in the Windows\Media folder and still got the same error. However, I then noticed that many of the folders in the Windows\Media folder had the same audio files in.
That got me thinking and I eventually realised that all of the audio files that are in these folders are actually in the Windows\Media folder directly. So you can play the sounds, but you just have to ignore the ones in the sub folders and play the ones from the Windows\Media folder. This will work:
SoundPlayer soundPlayer = new SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
soundPlayer.Play();
However, I can't tell you why we got that strange error, but I can only assume that the files in the folder could perhaps be some kind of links to the actual files in the Windows\Media folder and simply used by the operating system for grouping them into categories... or something similar.
"Landscape" refers to a Windows "Sound Scheme" and the wav files therein are utilized by the Windows OS. As you have already determined, those files cannot be used directly.
Comparison of the filesize of the Windows Notify.wav within the Landscape directory and the Windows Notify.wav file within the base Windows\Media directory is quite sizable; 222KB vs 25.5KB ---
If you go into the 'Sound' control panel applet and browse to 'Sounds' tab, you will see a dropdown list for "Sound Scheme:" and those additional folders within Windows\Media will be displayed in that list.
I don't have links to back this up, but after countless hours in dealing with Control Panel Sounds programmatically, I would venture to guess that the 'Sound Scheme' wav files just contain relevant data (perhaps effect data) that is consumed at runtime to play the modified versions of those sounds ... I could be quite wrong about that last part; it's just a guess. Regardless, you won't be able to use those sound scheme files directly within your code.
If you must play that "Landscape" version of the Notify wav, then I'd suggest playing the sound and saving it into a new wave file in an audio editor. You can add the wave file to your installer/deployment project to play it into the Windows\Media folder and call it directly the same way that you are already.
Since the sound seems to be in a compressed format, it has to be decompressed before you can play it using SoundPlayer. You can use Windows Audio Compression Manager to decompress the sound for playback:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd742945(v=vs.85).aspx
However, that's rather complex to implement, so I discovered a nice library that does all that for you, NAudio:
http://naudio.codeplex.com/
Using NAudio seems to be slightly more involved than using System.Media.SoundPlayer, but it also appears to offer far more functionality.
I am coding a rhythm game and one of the things I really want to keep in mind is the integrity of an artist's license and copyright. I appreciate artists giving me copyright license to use in my game but I don't want people to use my game as a way of getting their music for free.
Part of the idea is to distribute the game with 1-2 songs and they can download as many as they want from my website (to keep the installer size small so people with bandwidth limits can download the game without having to worry about size limits).
What I would like to do is have a file for instance a .dbf which when double clicked will move itself to my game directory (e.g C:/Program Files/Dashie's Sky Games/Rhythms/) as a .dbf, each .dbf will essentially contain two files (the .mp3 and the .drf), the .drf will contain the things such as where the notes would be, difficulty level, where the UberDash is and so on, this would be unencrypted however only editable via the ingame editor (not around yet).
I don't want people to be able to just rename the .dbf into .zip and be able to access the .mp3
I kinda want it so that the game will open the .dbf, decrypt it or whatever and store the .mp3 and .drf into memory (or in some very obscure temporary directory). I am using bass.dll for the music library. Any ideas at all?
Very much appreciated.
End of the day if the song is stored as an MP3 or other popular format then no matter how you package it someone will in theory be able to get it.
In my opinion your best option is to zip them and change the extension (maybe not zip zip, but 7zip or rar or a not so "default" compression mechanism) and then let your program unpackage the songs. I think you have to accept that if your program can unpackage the file then a human being will be able to as well, but assume that if someone wants a song, trying to decrypt your song storage mechanism won't be their preferred way of doing so (bittorrent will be, let's be honest). You could also include a "Get this song!" button in your application which would take the user to iTunes or what have you, allowing the user to get the song legally. If Warner, EMI and the RIAA can't stop people from pirating music, you most certainly won't be able to. Just try to make it easier for the user to get the song legally.
I need to play back 30 second audio clips, 1 per second, in winforms dotnet.
I am currently loading/playing the wav files from the filesystem, which works fine on a notebook, but is causing problems on a netbook. Can I pre-load all sound files into memory, if so how?
If you use the SoundPlayer to play your files you can preload the file with SoundPlayer.Load.
SoundPlayer sp = new SoundPlayer("filename");
sp.Load(); // preload
sp.Play();
Edit:
As noted by the documentation you may also use SoundPlayer.LoadAsync to load the sound in the background.
I'm inclined to say that you would load the file into a system.io.memorystream of some sort. Hopefully the libraries that play your file, will take a memorystream or memorystream can be converted into the data structure that this library takes.
Here's a recent example that creates a .wav file (a sine) in memory entirely from scratch and plays it. What you're trying to do should be much simpler, and you should be able to derive it from the sample posted.
Real low level sound generation in C#?