Dynamic audio player for an XNA Game - c#

I am currently working on a customized media player in C#, the main purpose of this thing is to let the user to play his own music files.
I already have a player of this kind (https://bitbucket.org/_Bruce/media-player), it works fine but only wave files are supported.
This limitation bothers me because mp3 is a tiny format (about disk space).
I have already tried and more or less succeeded in this task by using the FromUri method but there is a tricky problem: if the user name of the machine contains a space the string will be not accepted by the compiler, i have tried to resolve this with Uri.EscapeUriString but Visual Studio says that a Dos path must be with a root like C:\.
The code I am trying is below or Full code here
string[] SongsToRead = Directory.GetFiles(Environment.CurrentDirectory, "*.mp3");
song song;
protected override void Initialize()
{
var var1 = Uri.EscapeUriString(SongsToRead[0]);
Song = Song.FromUri("Test", new Uri(var1));
base.Initialize();
}
Am I on the wrong side?
Thanks!

Well now that you have something to work with-
I, honestly, despite all my time working in XNA, never even knew there was a Song.FromUri(...) - I've never had any use for it.
If you're going to use XNA's built in system, just use the regular Content.Load<Song>("mysong"); method - or try loading it as a SoundEffect using SoundEffect.FromStream(new System.IO.FileStream("MyFile.mp3", System.IO.FileMode.Open)); - which is intended for .wav sounds but should be compatible with other MS-approved audio files.
If you want to avoid that because you think the Content Pipeline is annoying or SoundEffect won't work well, you have to first realize the entire XNA audio setup is rather poor as well.
I would recommend using the FMod-Ex Sound System (API) if you want dynamic control and loading-from-file-without-content-pipline of your audio.
(It's a bit complicated to setup initially, but once you get it the .dll file in the right place and the C# wrapper imported, it's a wonderfully useful thing and comparitively easy to use)
If you really want to work with your current code, the only thing I notice:
var var1 = Uri.EscapeUriString(SongsToRead[0]);
Don't do that. That converts, for example, myfolder\myfile.mp3 to myfolder%5Cmyfile.mp3, it's used for HTTP stuff. Not good here.

Related

Generating direct video youtube links in C# code (like VLC does)

I am trying to create a method, would get passed a standard youtube link (e.g. https://youtu.be/.......) and would return the direct video playback link, just like VLC does.
In VLC this is done with a luac or lua code (https://github.com/videolan/vlc/blob/master/share/lua/playlist/youtube.lua) also for some reason VLC only plays in 640x368 resolution??
I tried looking through the code itself but I know nothing of lua so I dont understand it at all, even with the comments. Is there a resource I could read on how this is done? As I understand it, the lua code runs some script from the website itself to generate this? Also there is a lot of descrambling??
Now I wouldnt be opposed to using LibVLC to generate the links, but as I mentioned above, that only works in 640x368, which I dont understand why. If it worked with the best quality available, then thats what I would use (possibly with ability to choose resolution??)
Also I dont really care about youtubes policy about this, so dont tell me "this is against youtubes TOS, dont do this" this is a personal project only. I know that youtube is very much against this, as even the rythm bot on discord had to stop operation....
So, in short, what I am looking for: A way to get the direct link to the video resource, be it by generating it from the website or scraping it from the HTML. I know that the link will be temporary, I only need it for a short while.
From https://code.videolan.org/videolan/LibVLCSharp/-/blob/3.x/docs/how_do_I_do_X.md#how-do-i-play-a-youtube-video
Core.Initialize();
using(var libVLC = new LibVLC())
{
var media = new Media(libVLC, "https://www.youtube.com/watch?v=dQw4w9WgXcQ", FromType.FromLocation);
await media.Parse(MediaParseOptions.ParseNetwork);
using (var mp = new MediaPlayer(media.SubItems.First()))
{
var r = mp.Play();
Console.ReadKey();
}
}
media.SubItems.First() will contain what you need.
As for the resolution, I don't think there is anything LibVLC can do.
But if you don't need playback, just the video links, I'd have a look at https://github.com/Tyrrrz/YoutubeExplode

How to get android's internal memory root in Unity?

I have seen many similar questions, seems like a lot of people trying to figure it out, I couldn't find any answer that would help me. I am making a simple app for Android using Unity.
I want to have a folder in android internal storage root, on my pc it looks like: huaweiP30\internal storage\videos\
I don't need to write anything to that folder, I want my app to list all the mp4 videos from that folder and be able to play them using unity video player, I want the user to be able to easily add more videos to it by just dropping them into that folder. I tested it on windows and the app is completed working as expected, all I need to do now is to give it the correct path to the internal storage.
Alternatively I could have the app list all .mp4 files on the whole storage if that's easier to do.
I I tried all the answers that I was able to find online, some of which worked for other people. Nothing has worked for me so far.
used this for testing on windows and works exactly how I want it. I just don't know what should I replace the path with to make it read from internal storage\videos\
string videosPath = "C:\Users\Admin\Downloads\";
string [] filePaths = Directory.GetFiles(videosPath,"*.mp4");
Please help me either solve it or find an alternative resolution, I appreciate any help.
Thanks in advance.
This was easier than I thought! I was researching for so long and already going crazy when all I had to do is - in my phone settings I went to permissions, memory and allowed my app to access the memory.
Then it's as simple as
string path = Application.persistentDataPath.Substring(0, Application.persistentDataPath.IndexOf("Android", StringComparison.Ordinal));
videosPath = path +"/videos/";
to get the path. without the last bit I was able to read every single video on my internal storage when I added
SearchOption.AllDirectories
here is how to make your app ask for permissions so you don't have to manually allow it.
https://docs.unity3d.com/Manual/android-RequestingPermissions.html
The sample code is about microphone but all you need to do is just change it to ExternalStorageRead/Write, don't worry about 'External', it works for internal memory too.

Obtain the current audio playback stream

So, I need to obtain the current audio playback that is happening on my pc programatically in real time. This includes all the audio(you can check this in the playback devices tab of the Sound settings). I need it because I'm doing an analysis over the stream which I then put into use in another software. Until now, I've used the 'StereoMix' option, which actually relay's the current audio as an input(something like an internal microphone). However, I can't use this method when I connect external speakers to my pc(through HDMI, PC/AUX works though).
Is there some way to obtain the audio stream no matter if external speakers are connected or not.
The programming language does not matter in the current case, everything is fine with me. However, I prefer if there is a C# / Processing solution.
EDIT:
Here's the technique(and method) I currently use to obtain the audio in http://code.compartmental.net/minim/minim_method_getlinein.html. The library/code is related to Processing: https://processing.org/.
Basically, NAudio would be a good place to look for a prospective solution. Its not quite clear what you intend to do with the audio such as if you're recording/dumping data, or simply analyzing live-data so I'm thinking NAudio is going to have something such as you're looking for, as far as getting your hands on live-data.
NAudio has an FFT, but not quite robust in the area of analysis as the JS-libs you may be accustomed to ;)
http://naudio.codeplex.com/
https://github.com/naudio/NAudio
There are plenty of examples provided to get you started, and many in the wild.
Though its pretty outdated and the API may or not look slightly different (in regard to...), the following video may provide a nice relaxing quick-start to help familiarize you with this lib.
C# Audio Tutorial 6 - Audio Loopback using NAudio

Load files into the player through C#

Don know how to go about this. I have about 12 videos which has to be added to the player and play on after the other. Right now only one video is getting played.
Following is the piece of code :
Process proc = new Process ();
foreach (string videos in Directory.GetFiles(Application.streamingAssetsPath))
{
filePath = Path.Combine (Application.streamingAssetsPath, videos);
proc.StartInfo.FileName = filePath;
proc.Start ();
}
I printed and checked files in proc.StartInfo.FileName , all the 12 videos are getting printed.But don't know how to load them into the player.
We need more details to help you out !
What video player are you using ?
Since your code starts multiple processes (bad idea IMO) and you see only one, I can assume that your player can only have one instance running and it is used again, hence you do only see one video.
Potential answer:
Probably your player accepts multiple arguments, I'll take the example of Winamp :
winamp.exe "d:\f1 race - Copy.wav" "d:\f1 race.wav"
This will start an instance of Winamp and all the files will be on the playlist.
EDIT
The same applies to WMP as well :
wmplayer.exe "d:\f1 race - Copy.wav" "d:\f1 race.wav"
Playing a folder containing medias :
It does work with Winamp but not with WMP unfortunately, so passing each media full path as above seems the only solution for WMP. I'm not sure about the maximum length you can throw
as arguments since it is not explicitly said in here.
You might wonder why dropping a folder to WMP effectively loads all the files in it ? They for sure do get all the files from the path you have dropped and add them to the playlist.
Alternatives
Maybe you should define a list of the installed media players that the user would choose the one he prefers to use. (and define a default one, in this case WMP is a good choice since there's a strong probability it is installed on the system)
You can retrieve a default application for a particular extension, see the following links :
Finding the default application for opening a particular file type on Windows
http://windevblog.blogspot.fr/2008/09/get-default-application-in-windows-xp.html
There is also the DropTarget route though it might not be straightforward, here's a sample from MSDN : http://msdn.microsoft.com/en-us/library/windows/desktop/dd940354(v=vs.85).aspx
I strongly suggest you to take a look at this small piece of software that helps in seeing/browsing/editing the default applications for a particular extension : http://defaultprogramseditor.com/ (must run as admin)

Are there any libaries to compare a small image to a screen grab and return an x,y coordinate list of where it's located?

this is a pretty rough area (fuzzy logic image comparison) that is way
above my pay grade, so to speak.
I'm trying to write a program that will detect carrots (and other veggies) onscreen from a game and return matching x,y coordinates for each found match.
The intent is to track each time the vegetable grows (5 times) and eventually automate the watering/harvesting of the vegetables (once you see the screenshots this will make more sense).
I tried using the image compare code located at
http://sites.google.com/site/serinolorenzo/blackmask
it actually works flawlessly when searching this screenshot (and desktop grabs)
http://imageshack.us/photo/my-images/24/mac8.png/
for instances this image...
http://imageshack.us/photo/my-images/249/carrotplant.png/
It does find and return multiple "Carrot Seeds" menu coordinates.
However when I get down to detecting the veggies (the meat and potatoes of what the compare needs to detect) it fails to find a match.
I've tried various "carrot" screenshot, most recently...
http://imageshack.us/photo/my-images/829/carrotlight1t.png/
to the image
http://imageshack.us/photo/my-images/408/macnolight1.png/
(I had to turn in game lighting off when I got here, to ensure colors stayed the same regardless of game time).
I thought (by going over the source code for the image compare) that black would be ignored, so I'm not sure exactly what's going on, but it just will not find a match now, even if I set the thresholds lower.
Are there any (well documented) libraries that exist to do this, as coding it from scratch is just something I can't do at the moment.
Barring that (and if whomever is reading this has the time) can you see where I'm going wrong?
The code I'm using to do the testing is...
public void tester()
{
Bitmap screenshot;
screenshot = new Bitmap(#"c:\MyMercurial\ATITDVeggieMacro\ATITDVeggieMacro\Images\macnolight1.bmp");
Bitmap searchFor;
searchFor = new Bitmap(#"c:\MyMercurial\ATITDVeggieMacro\ATITDVeggieMacro\Images\wholecarrot.bmp");
int ac1;
int ac2;
ArrayList test = BlackMask.Search(screenshot,searchFor,
0,10,75,5,80,20,100,true,out ac1,out ac2);
statusUpdate = ac1.ToString()+"good,"+ ac2.ToString()+" bad/ X=";
}
(I just update the file paths when I want to change images).
(Bonus question, how to I use relative paths to tell it to just go up two directories and then down into the Images folder, I can't at all remember the relative path shortcuts)
Thanks for any help guys, this ones got me slamming my forehead.
For intelligent image processing in .NET, you could look into using AForge.NET. There's also OpenCV, but then are no .NET bindings that I know of off hand (they appear to have some for Java though...). Once you figure out which library, I'm sure you can find additional articles via Google on their usage (besides their standard examples)
I've never played ATITD, however, if you figured out the various specs of how it was developed, that could shed some light into how you might approach this problem in an entirely different direction. For example, if their Client app links to the MS C runtime DLL, it might have been developed in C/C++ (or maybe with some other lang whose framework runs on a C/C++ core). You could end up just manipulating the memory of the program if you found out how it stores the copy of the game state in the Client memory (assuming it's just not some video feed, a la OnLive). If you figure out which rendering framework they use, OpenGL, DX, etc, you may be able to do the image capture more efficiently (and possibly without as much artifacts, like the grass and such, that you have to mask out yourself) via DLL hooks/proxies.

Categories

Resources