I gave some simplified VLC media player code in part 1 to show how easy it was to do and how most wrapper libraries make a mountain out of a mole hill. In that entry, I briefly touched on using some classes to make it easier and safer to implement actual programs with this.
The first thing to do is write a wrapper for the exceptions, so that they are handled nicely in C#. For a program using the library, exceptions should be completely transparent and should be handled in the normal try/catch blocks without having to do anything like initialise them or check them.
Another thing to do is to move all of the initialisation functions into constructors and all of the release functions into destuctors or use the System.IDisposable interface.
Here is the code listing for the 4 classes used (VlcInstance, VlcMedia, VlcMediaPlayer and VlcException). Note that the first 3 of these are very similar and that the main difference is that the media player class has some extra functions for doing things like playing and pausing the content.
class VlcInstance : IDisposable { internal IntPtr Handle; public VlcInstance(string[] args) { VlcException ex = new VlcException(); Handle = LibVlc.libvlc_new(args.Length, args, ref ex.Ex); if (ex.IsRaised) throw ex; } public void Dispose() { LibVlc.libvlc_release(Handle); } } class VlcMedia : IDisposable { internal IntPtr Handle; public VlcMedia(VlcInstance instance, string url) { VlcException ex = new VlcException(); Handle = LibVlc.libvlc_media_new(instance.Handle, url, ref ex.Ex); if (ex.IsRaised) throw ex; } public void Dispose() { LibVlc.libvlc_media_release(Handle); } } class VlcMediaPlayer : IDisposable { internal IntPtr Handle; private IntPtr drawable; private bool playing, paused; public VlcMediaPlayer(VlcMedia media) { VlcException ex = new VlcException(); Handle = LibVlc.libvlc_media_player_new_from_media(media.Handle, ref ex.Ex); if (ex.IsRaised) throw ex; } public void Dispose() { LibVlc.libvlc_media_player_release(Handle); } public IntPtr Drawable { get { return drawable; } set { VlcException ex = new VlcException(); LibVlc.libvlc_media_player_set_drawable(Handle, value, ref ex.Ex); if (ex.IsRaised) throw ex; drawable = value; } } public bool IsPlaying { get { return playing && !paused; } } public bool IsPaused { get { return playing && paused; } } public bool IsStopped { get { return !playing; } } public void Play() { VlcException ex = new VlcException(); LibVlc.libvlc_media_player_play(Handle, ref ex.Ex); if (ex.IsRaised) throw ex; playing = true; paused = false; } public void Pause() { VlcException ex = new VlcException(); LibVlc.libvlc_media_player_pause(Handle, ref ex.Ex); if (ex.IsRaised) throw ex; if (playing) paused ^= true; } public void Stop() { VlcException ex = new VlcException(); LibVlc.libvlc_media_player_stop(Handle, ref ex.Ex); if (ex.IsRaised) throw ex; playing = false; paused = false; } } class VlcException : Exception { internal libvlc_exception_t Ex; public VlcException() : base() { Ex = new libvlc_exception_t(); LibVlc.libvlc_exception_init(ref Ex); } public bool IsRaised { get { return LibVlc.libvlc_exception_raised(ref Ex) != 0; } } public override string Message { get { return LibVlc.libvlc_exception_get_message(ref Ex); } } }
Using these classes is even easier than before, can use proper exception handling (removed for brevity) and cleans up better at the end. In this example, I have added an OpenFileDialog, which is where the file is loaded.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace MyLibVLC { public partial class Form1 : Form { VlcInstance instance; VlcMediaPlayer player; public Form1() { InitializeComponent(); openFileDialog1.FileName = ""; openFileDialog1.Filter = "MPEG|*.mpg|AVI|*.avi|All|*.*"; string[] args = new string[] { "-I", "dummy", "--ignore-config", @"--plugin-path=C:\Program Files (x86)\VideoLAN\VLC\plugins", "--vout-filter=deinterlace", "--deinterlace-mode=blend" }; instance = new VlcInstance(args); player = null; } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if(player != null) player.Dispose(); instance.Dispose(); } private void Open_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() != DialogResult.OK) return; using (VlcMedia media = new VlcMedia(instance, openFileDialog1.FileName)) { if (player != null) player.Dispose(); player = new VlcMediaPlayer(media); } player.Drawable = panel1.Handle; } private void Play_Click(object sender, EventArgs e) { player.Play(); } private void Pause_Click(object sender, EventArgs e) { player.Pause(); } private void Stop_Click(object sender, EventArgs e) { player.Stop(); } } }
Update:
I have just corrected a minor bug (the wrong release function being called on the player handle) and uploaded the full Visual Studio 2005 project. You can download the full project here (or see 1.1.2 version below). It comes with the libvlc.dll and libvlccore.dll for VLC 1.0.1 in the bin\x86\Debug directory so if you have a version other than this, just overwrite those files.
Update for VLC 1.1.2:
You can now download the VLC 1.1.2 compatible version. There were some changes to the way libvlc handles exceptions that needed to be corrected. Other than that, there were a couple of minor function name changes.
Please use these posts as a starting point to use your own code though. These posts are intended to stop people from being reliant on the already existing, large, overcomplicated and quickly outdated libraries. They are not intended to be just another library for people to blindly use without understanding how it works. You can use this to learn how to write your own native interop code on a well designed library then adapt it for your own changes and keep it up to date with whichever version of VLC you want. This also means you never have to use the terrible code on pinvoke.net for other libraries, as you can write your own from the original documentation and it will almost always be better.
Bugfix: VlcException should use Marshal.PtrToStringAnsi not Marshal.PtrToStringAuto
Hello George,
thank you for great job, in the latest version of your project ( 1.1.2 ) , When form_closed called I get an exception[1], I think that this error may relate to vlc 1.1.2 dll’s but as I seen nobody didn’t face that problem.
I want to write it, since maybe your suggestions can work
Note: I try in several computers.
[1]
An unhandled exception of type ‘System.AccessViolationException’ occurred in System.Windows.Forms.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Thank you, Helyar.
First make sure you’re using the correct DLLs for your version of VLC. The current version of VLC is 1.1.4 now and while the code may still compile and work, small changes may lead to strange errors. You should be able to just compile and run against the 1.1.4 dlls without needing to change the C#, if you are using them.
If the error is due to a release function, you can check first that the handle is not null (IntPtr.Zero) before calling release, and also wrap the C# calls to the release functions in try/catch blocks. Since there is nothing you can do if it cannot be released, you can usually just use an empty catch block here (but do so with caution, as it may hide real problems)
This gui needs exception handling added. I have not added it because the intention of this post is to show how simple it is to write your own libvlc code in .net, not to provide a robust player application.
Hi George,
Thank you for helping me to understands the concepts about this vlc project. I learned a lot from your code. But I am stuck at this personal little project. I want to create a little media player almost just like vlc player but slightly different and also in C# b/c that’s the language that I want to learn more of.
Can you help me b/c I am currently don’t know where in insert some code into libvlcnet project. Do you mind helping me? Please email me at **** if you can spear some time to teach me? I can email the project to you.
Thank you!
Hello George again
,
I intensively researched but there is no bug report related to “crop filter” and “fullscreen” on version 1.1.2, this settings[1] worked great under your old wrapper. I’m sure that plugins and libvlc.dll ‘s are correct. Is this somehow related to C# ?
[1]
string crop = “800×600+0+0″;
string[] args = new string[] {
“-I”, “dummy”, //”–ignore-config”,
@”–plugin-path=C:\Program Files\VideoLAN\VLC\plugins”,
“–fulscreen”,
“–vout-filter”,
“crop”,
“–crop-geometry”,
crop
};
Hi ubaltaci,
I noticed the same thing regarding fullscreen. If using –fullscreen didn’t work on the command line, it is possible that the command line for it has just changed. I did notice, however, that double clicking on a video no longer enters fullscreen mode (even if you don’t set a “drawable” handle, so it pops up its own window) and other similar features that were very useful, and this is something to do with changes to libvlc, not the C# wrapper. You may be able to reproduce some of these features by writing them yourself but if it is important, you may just want to stick to a previous version of VLC.
See something like libvlc_set_fullscreen
Hi george,
I’m very grateful for your help, just for noticing that maybe other persons are facing this problem returns previous version. Previous version works great in case of “fullscreen”, “cropping” and “marquee”.
Thanks again.
Hi George Halyar,
I am looking at your code and I do see that you pass the video handle to panel1…but I would like to pass that same video handle to another separate form name called “frmVideoWindow with a panel name called “videoPanel”. The reason is that I like the video be in a separate window, and the player controls in another window. Is this the same idea as passing a string from one form to another form?
Thank you,
E
I have tried to view full screen but could not. please give me your code.
thanks!
I’m looking for fast/slow forward/backward features with specifying an indicator like 2x, 4x, 8x? Which functions help me do this?
problem was solved
I couldn’t get the 1.0.1 version to work at all even though I had the plugins. The 1.1.2 version works fine, and i have vlc 1.1.2 installed.
So that brings up the question, if the vlclib.dll vlclibcore.dll and plugins folder are local to the application, will it work on a computer without vlc player installed? or even on a machine that has a newer version of VLC player?
I assumed it would, but me experiences seem to show otherwise..
Any input on this?
Function used to display the file name on the video screen in VLC?
[img]http://img6.uploadhouse.com/fileuploads/6624/6624386bdc213089b5c1ef5656c148432daf12f.jpg[/img]
Thank You!
@kermit
Please check the LibVLC documentation. You are just as capable of checking it as me. At a guess I would say maybe
libvlc_video_set_marquee_stringbut this is just a guess.Try it or ask on the libvlc forum instead, which is a better place to ask anyway.
thanks George Helyar!
I’ve tried (http://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__video.html # g3ee417cfaf35a8b96385bd3e3968650b) But it does not work. Please your help
thank you!
How can we play the VLC player with a memory steam? Is it possible?
anyone know please help??!!! using (libvlc_video_set_marquee_string)
With the object of the VLC video screen you can add to a DataGridView, listview?
thank you!
I want to add the features of trackbar,Volume control and forward ,backward feature. Please suggest how can i add this method.
I am getting this exception while setting the Media Player position in following methods .
[DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
[SuppressUnmanagedCodeSecurity]
public static extern void libvlc_media_player_set_position(IntPtr player, float pos);
public void SetPosition(IntPtr Handle, float i_pos)
{try{
LibVlc.libvlc_media_player_set_position(Handle, i_pos);
}catch
{
// throw below mentioned exception here.
}
}
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Please help me resolve this issue….
how to open two video windows simultaneously.
player.Drawable = fromwindow1.Panel1.Handle ‘This line does not work
player.Drawable = fromwindow2.Panel1.Handle ‘only works with fromwindow2
Please help me
Thanks
Tom
@kermit I already told you to ask on the VLC forum, not here.
@rishi A quick google search found this for playing from a memory stream but alternatively you can just write it to a file and start playing even before the whole file is written, if it is a stream which doesn’t need to be complete to play (e.g. mpg, ts, m2ts but not avi). This is relatively simple and means your hard drive becomes your cache for rewinding, pausing etc.
@Tom When you set the component for it to draw to, you are overwriting it each time. A player can only draw to one place. Try creating a second MediaPlayer object and drawing that to the other form component. You will have to control it separately too.
@Mukesh For adding features, read the documentation and ask on the forum. For the memory corruption error, this happens when you read from or write to memory that you shouldn’t be accessing. Remove anything you don’t need (e.g. SuppressUnmanagedCodeSecurity is a performance tweak with risks – don’t use it unless it is already stable without) and move your error handling into the application, not the library class. The
libvlc_media_player_set_positionfunction itself will not throw any errors. You need to read the output of interop calls and throw exceptions yourself, which can then be handled in your code. As a non-static method of VlcMediaPlayer, Handle should always be the handle of that media player, so your method should look more like this:note that if you add
libvlc_media_player_get_positionto this, a return value of -1 is an error (and standard rules about equality operations on floating point numbers apply).The likely reason for the error is either that float is the wrong type so you’re writing more than you should be or that the handle is wrong (either null or a handle to something else), so you’re not even writing to valid memory. You may also need to check that the video is actually playing before you set the position, as many operations do not work until the video is loaded and playing.
hi George Helyar
I see people ask the forum but did not see anyone answer
Please help
I managed to get it all working, including position, volume control, and snapshot. But I couldn’t get the libvlc fullscreen to work. I managed to hack one together by adding the panel I was using for the video to a new form and filling the screen. I can’t quite figure out how to capture a double-click on the video. Since 1x doesn’t support that be default anymore, I can’t figure out how to make it work at all.
Thanks for help getting started with this.
how can VLC Video Screen print. Right now I just print out a black screen
Please…..
thank you!
your project does not play the video file (format .DAT)
http://www.megaupload.com/?d=4KMRQRGF
http://www.megaupload.com/?d=FJ7RTI5M
Please check
Thanks
@myduyen
On the VLC 1.1.2 version of this project it does seem to crash, while VLC 1.1.2 itself can play them fine (they are actually CDXA/RIFF files with MPEG-1 audio and video streams)
Debugging shows that it crashes on libvlc_media_player_play, even though the handle is valid and it does not return a -1. This means that the bug is likely in libvlc itself and you should report it there.
However, before you report it, try writing your own VLC code from scratch using the latest VLC trunk (1.2.0 git) to see if it has already been fixed.
For a temporary solution, convert these files to a better format. Both CDXA and MPEG-1 are very old. You should be able to convert them in ffmpeg (or SUPER, or handbrake, etc) which will reduce their size and increase their compatibility without sacrificing quality. The x264 encoder is probably the best encoder out there at the moment.
Nobody here????
I tried to do this
Dim args As String() = New String() {“-I”, “–no-overlay”, “dummy”, “–ignore-config”, “–plugin-path=F:\plugins”}
But that does not work
thank you!
@jonson
That is Visual Basic .net. This project is in C#. You need to either convert the whole project to VB.net or compile the C# section as a DLL and reference it from your VB.net project.
In addition, “F:\plugins” is probably not a valid VLC plugins path (since VLC installs as .\VideoLAN\VLC\plugins). Get it working with a normal VLC install before trying to use just a plugins directory on its own.
@George Helyar
I’m saying this problem
how can VLC Video Screen print. Right now I just print out a black screen
Pleaseā¦..
thank you!
use libvlc_video_take_snapshot
@George Helyar, thanks for this great starter on vlc wrapper. But have you dealt with libvlc_playlist_play? I am a little bit confuse on it. I have a listbox control with the file paths for the files I want to play. So do I have to create a new “instance” for every file each time it plays? And put the playlist in a loop to play each file in the listbox?
thank you!
@Evan, libvlc_playlist_play is deprecated. Try looking at the media list player to play a media list.
With the libvlc model, there is one instance of libvlc, a player for each medium you want played (if you wanted 2 videos to be played at the same time you may be able to do this with 2 players) and media for everything you want to be played. So, if you wanted many things to be played but only one at a time you would use a single player with many media. The “media list player” functions make this a bit easier, but I have not used them here.
@George Helyar
I mean to use the software “TechSmith Camtasia Studio” to record the activity on the screen
thank you!
@jonson
If your problem is with Camtasia, then take it up with Camtasia. This is out of scope for libvlc and they are likely blocking it on purpose to prevent copyright violation.
If you want to rip videos, there are much better ways than recording a player’s output anyway.
Thanks for the excellent pair of articles. It’s refreshing to see a well-written piece that uses straightforward language and stays on topic while being highly informative. Much appreciated!
Hello,
Does anybody has any idea on how to toggle Left and Right audio channel? I read that it uses libvlc_audio_set_channel and then one of the Enumerator below. But I have no idea on how to piece it together. I can toggle audio tracks, but now sure how to toggle audio channel. Any code example would be very help.
Enumerator:
libvlc_AudioChannel_Error
libvlc_AudioChannel_Stereo
libvlc_AudioChannel_RStereo
libvlc_AudioChannel_Left
libvlc_AudioChannel_Right
libvlc_AudioChannel_Dolbys
@Evan
the enumeration is defined in libvlc_media_player.h as
So you should be able to just use
libvlc_audio_set_channel(Handle, 3)where Handle is the IntPtr handle of a VlcMediaPlayer and 3 is the left audio channel. As in the documentation, it returns “0 on success, -1 on error”Hi George,
I used the libvlc_audio_set_channel(Handle, 3) to test and it’s not working for me. This is what I have:
[DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
[SuppressUnmanagedCodeSecurity]
public static extern int libvlc_audio_set_channel(IntPtr libvlc_mediaplayer, int i);
LibVlcInterop.libvlc_audio_set_channel(descriptor, 3);
In debug mode..I have the player handle..but it just crash when I run the line LibVlcInterop.libvlc_audio_set_channel(descriptor, 3);
Please help…I am been stuck at this for a fews days..and can’t find any help or good sample code to test with.
Thanks.
Hello,
where would you put “libvlc_set_fullscreen” in the code ? i keep getting exceptions ( Memory volation ).
i did the following :
[DLLImport("libvlc")]
public static external void libvlc_set_fullscreen( IntPtr player, Boolean bo);
then anywhere i put this code ” Libvlc.Libvlc_set_fullscreent(Handle,true); ”
i get an error . Any idea ? Thank you . Sam E
Hi,
Just a hint: to get this working with my Visual C# 2010 (Express), I had to change all the DllImport entries to use CallingConvention = CallingConvention.Cdecl. Without this, I would get an error that the call had “unbalanced the stack”… But by adding this, everything started working great. Thanks for your nice work!
HI,
Does anybody know how to make it stream an avi file. I have tried adding this
“-vvv “D:\\Intro.avi” –sout udp:239.255.12.42 –ttl 12″ to the args line but it does not work.
This works with the command line in VLC
Hi, thanks to you George !
Great job !
lot of nice clean work. but have you tried to play an rtsp:// stream. i tried it and it didn’t work. didn’t core dump just didn’t play.
i’m going to step through and see if i can figure it out. Streaming live is where it’s at. your clean player code and runtime loading would be a nice thing.
dave carlson
software engineer
valencia, ca. u.s.a
I am using want to use function “SEEK” all user mode help
Hi,
This is a great tutorial to learn vlc api. Thanks for posting this.
Does anyone have an example on how to create a playlist and play those files using the C Sharp example given in this
tutorial?
Thanks
Hi!
Thanks for sharing this code, but i have a little problem with it. Import in VS2008, build succed, libvlc.dll libvlccore.dll is near the MyLibVLC.exe but when i try to debug your program i got an error:
VLCException was unhandled @ if (Handle == IntPtr.Zero) throw new VlcException();
VlcException should use Marshal.PtrToStringAnsi not Marshal.PtrToStringAuto, changed it but still not working, what am i missing?
@sh4 Unhandled exceptions mean you need to catch that VlcException that was thrown in “throw new VlcException();” in your own code.
Libraries throw exceptions. It is up to the application that uses the library to decide how to deal with it. You need to use try/catch blocks in your own code as appropriate.
The PtrToString functions are just for getting libvlc’s internal error message into a readable format for printing in .net, you still need to actually handle the errors. While Java forces you to handle exceptions and won’t compile if you don’t (checked exceptions), if you don’t handle exceptions in C# it just crashes the application when they occur (unchecked exceptions). See more here.
hi
how to play a dvd with your project (http://www.helyar.net/files/MyLibVLC_112.zip)
Thank you!
I just found your site. You just became my new hero. Thanks for all your work and info.
Hi George Helyar !
I also want to know how to change audio channel using( libvlc_audio_set_channel )
I’ve been searching this code for a long time. If you can help me I will be vary happy.
When I try your project i have an error like this (Attempted to read or write protected memory. This is often an indication that other memory is corrupt.) in
public VlcInstance(string[] args)
{
VlcException ex = new VlcException();
Handle = LibVlc.libvlc_new(args.Length, args, ref ex.Ex); <<——– here
if (ex.IsRaised) throw ex;
}
Thank You
If you are getting an error when initialising libvlc, it is nothing to do with setting the audio channel. I have already answered several questions on initialisation errors. Please read all of the other comments.
Hint: compile against and use the same version of VLC as you have installed on your system. Also, download the project files rather than copying code off the post itself. They are more up to date.
Not only have I already answered the initialisation question, I have also already answered the audio channel question.