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
Related
I am using a mashup of examples found online to send the audio from a MP3 file to a discord channel via Discord.net 2.0 (c#).
It took forever to get any audio at all to send... and now that I at least get that working, the audio is super-fast - like chipmunks on speed.
As background, while I am using a static mp3 file here, I will actually be using the google cloud text to speech engine to generate the stream ill be sending - but wanted to get it working with a known file first.
I am not new to developing, but I am new to working with audio of any kind. I understand how audio works - and in this case the problem should be one related to the bitrate, but that does not seem to be the case as I manually set the bitrate of the stream to the bitrate of the file (and I have tried changing it to no effect).
Furthermore, I am supremely confused about the while loop you will see in my code below. I have never used a while loop like that... though it does seem to work, though I can't for the life of me figure out why, since the variable in the condition does not seem to change. I feel like I am missing something very simple and just can't seem to figure it out. Any help is greatly appreciated!
I have tried just about every block of code related to this that i can find on the net, as well as numerous iterations of my own code thrown in. None have been successful.
'''
bool playing = false;
AudioOutStream dstream = null;
CancellationTokenSource cancellationToken = new CancellationTokenSource();
try
{
var reader = new Mp3FileReader(path);
var naudio = WaveFormatConversionStream.CreatePcmStream(reader);
dstream = client.CreatePCMStream(AudioApplication.Voice, 32000);
playing = true;
await naudio.CopyToAsync(dstream,50);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
if (e.InnerException != null)
Debug.WriteLine(e.InnerException.Message);
}
while (!playing) ;
Console.ReadLine();
cancellationToken.Cancel();
Debug.WriteLine("Pre-Flush");
dstream.Flush();
Debug.WriteLine("POST-FLUSH");
'''
The code above is the "nuts and bolts" of the streaming code. There is a lot more above and below related to it, but mostly channel/guild management and cleanup, command handling etc.
This block of code was purported to be working by another stackoverflow post, but I suspect it was for discord.net 1.0, which may be why I have an issue.
This code DOES play the file, but so fast that it is incomprehensible. The file contains approx 4 seconds of audio, but it plays in a fraction of a second. After it finishes playing, it never exits the while loop, which at least makes sense to me. That said, without the while, or modifying the while to attempt to detect when the stream is finished, have all failed. This is the only way i can get any audio at all to play.
The expected result would be for the audio to play at the right bitrate and then exit and flush as expected.
Any kick in the right direction will be greatly appreciated!
Have you made sure that you have all the libraries loaded correctly? This is a common cause of audio problems in discord bots.
Here is an answer I posted for another question.
These are a few things I pulled from the official Discord API guild.
Windows 64-bit: https://dsharpplus.emzi0767.com/natives/vnext_natives_win32_x64.zip
Windows 32-bit: https://dsharpplus.emzi0767.com/natives/vnext_natives_win32_x86.zip
FFmpeg for Windows: https://dsharpplus.emzi0767.com/natives/index.html#ffmpeg-for-windows
Other OS's:
GNU/Linux: https://dsharpplus.emzi0767.com/articles/vnext_setup.html#gnulinux-1
OS X: https://dsharpplus.emzi0767.com/articles/vnext_setup.html#mac-os-x-1
FreeBSD: https://dsharpplus.emzi0767.com/articles/vnext_setup.html#freebsd
Note for D.NET users: You need to rename libopus.dll to opus.dll before use, otherwise audio client will still complain about missing libraries.
Have you checked the bitrate of the audio you're sending ?
This is a problem I had while creating the stream. I was sending the wav data too fast and created that chipmunk voice. You have to make sure the data you read from your audio file and the data you send to the Discord AudioStream are strictly exactly the same.
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
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.
I'm trying to use the DirectShot.Net wrapper from "http://directshownet.sourceforge.net/" to extract frames from a number of video files.
Whenever I run the DxScan sample app. I get a "No combination of intermediate filters could be found to make the connection." This happens for WMV files, MP4 files, AVI files. Any media I point at the sample app.
If I open any of the videos using the GSpot codec tool and ask it to render the graph, it does so without problem. So the machine is definitely capable of playing the content.
I'm on Win 7 64 bit. The same error is thrown targeting x64, x86 or Auto. Including running Visual Studio as an Administrator.
I've modified the sample code to try and find the correct pin containing the video media type as suggested by Romain R below.
I'm using:
IEnumPins epins;
capFilter.EnumPins(out epins);
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
IEnumMediaTypes mtypes;
pins[0].EnumMediaTypes(out mtypes);
AMMediaType[] types = new AMMediaType[1];
while(mtypes.Next(1, types, new IntPtr()) == 0){
var majorType = types[0].majorType;
if (majorType == MediaType.Video)
{
//This is never reached
}
}
}
For MP4 files, it's never hitting the commented line above. However for WMV files, the demo will now run correctly.
Presumably, this is because it isn't finding an appropriate MP4 file filter. Which is obscure as the content will play fine in windows media player.
Is this a likely cause?
DxScan sample is building a filter graph in an unreliable way, in particular is makes an assumption that the first pin it grabs from the source filter supplied for a media file is a video pin. It is not always the case. A better graph building approach should be working out fine. You might want to step through to find out at what line you have an error. Most likely, it is going to be connection of Sample Grabber Filter input pin.
UPD. Note that it might so happen that original filter has no input pins, it requires additional filters in between, so called parser/demultiplexer filters which convert streams into video frames and audio samples. DirectShow API offers Render* methods to assist in graph building in terms of suggesting required links of this chain and direct connection DxScan is doing might or might not work out.
That is, DxScan might be not the best sample to start from, MSDN samples/reference for native API are perhaps better for taking off the ground with DirectShow.
Your playground and primary research and API exploration tool should be GraphEdit from Windows SDK (GraphStudio, or GraphStudioNext as alternate improved options), not a DirectShow.NET wrapper library sample.
Which is obscure as the content will play fine in windows media player.
WMP does not use DirectShow for playback.
I have got problem, I need to download graphics from next site
http://www.kakioka-jma.go.jp/cgi-bin/plot/plotSetNN.pl?lang=en
I am using PowerShell, I need to create POST request to Plot the image (see Plot button). The problem that I do now know how it's can be done in PowerShell. Before I used function 'System.Net.WebClient' for downloading, and created url for it with
I googled and find how POST request may be done in C#, and I tried to built them in one script. http://www.everfall.com/paste/id.php?2ppnztfqx3we
But it's not working, it's even do not print "Hello World", and I do not know how to get it's work.
But the main question - not get this code to work, but to find the easiest way to load that graphics, and it would be good if it would on Powershell.
I have seen "Http Rest" script, but it's to hard even to understand does it do what I need, I even do not talk about to modificate it's for my work. I need the simplest way, because my knowledge in programming it now good.
I wrote a series a while back on Splatting (a language technique in PowerShell V2). The last item in the series provides a wrapper on the Net.WebClient class that makes it easier to send requests via Post.
The blog explains a lot about how the client object works, and you can read that if you want:
http://blogs.technet.com/b/heyscriptingguy/archive/2010/10/22/make-windows-powershell-your-web-client.aspx
Or you can download the script directly from the Script Center Repository:
http://gallery.technet.microsoft.com/ScriptCenter/en-us/7e7b6bf2-d067-48c3-96b3-b38f26a1d143
Hope this Helps,
It sounds like curl could be useful for you. It will deal with the trickier aspects of posting data to a web service.
I've used it myself to download text and parse through it with PowerShell. I had a batch file to call curl, the batch file was called from a powershell script. Sounds the long way around but it worked quickly and I didnl't have to put much time in!
I'm on my phone and don't have any examples here, if you interested I can have a look for them later.
HTH,
Matt