libvlc media player in C# (part 2)

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 finalizers or use the System.IDisposable interface with the Dispose(bool disposing) pattern.

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()
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()
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()
    public IntPtr Drawable
            return drawable;
            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()
            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();
        private void Open_Click(object sender, EventArgs e)
            if (openFileDialog1.ShowDialog() != DialogResult.OK)
            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)
        private void Pause_Click(object sender, EventArgs e)
        private void Stop_Click(object sender, EventArgs e)


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 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

Tags: , ,

191 Responses to “libvlc media player in C# (part 2)”

  1. RocketMan says:

    Thank you for your Oct. 8, 2012 reply about plugins path not the same for VLC V 2.0 or higher. This presents a problem for me (since I want to use your C# code sample with VLC 2.0.2 or higher. Can you please provide a C# code sample with the plugins folder correctly specified and/or not specified, so that I can have a test application to play video in?

    Thanks in advance,

  2. Th says:

    Thanks for the great code here.

    But how do you play xspf playlists?
    The playlist is loaded but not startet…
    Option –playlist-autostart doesn’t work. Any hints?


  3. Thomas says:

    thanks for your great example.
    How do you play playlists (xspf)? I didn’t get it to work. Does someone have an example?

    Thanks in advance

  4. Dear George,

    Thanks for this. I love the simple approach. It was exactly what I was looking for – a clear example of how to begin, rather than 2 weeks of reading someone else’s massive project source code: to figure out if it was any good to start with.


  5. Anwar says:

    Dear Friends,

    If somebody have a sample project using LibVlc version 2.0.2 or above in c# then please help me out by posting the link or comment here.


  6. Cristian says:

    Just compiled the code and got an error…

    PInvokeStackImbalance was detected
    Message: A call to PInvoke function ‘MyLibVLC!MyLibVLC.LibVlc::libvlc_new’ has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

    How can we fix this?

  7. George Helyar says:

    Hi Cristian,

    Do you have the same problem when using the zipped example? The code in the post has not been kept up to date as libvlc changes.

    That said, this function should not have changed. It takes the standard argc/argv pair that the main function takes. You should just need to pass it a string array and 32 bit integer containing the length of that array.

    This could also be down to 32 vs 64 bit differences (at the time of writing there was no x64 build but there is now) or could be down to using a different version of the libvlc dlls when compiling and running the program.

  8. Hello,

    To use libvlc 2 and up (I’m using 2.0.2, shipped with vlc 2.0.5), you need to remove the reference to the plugins path. Instead, use the VLC_PLUGIN_PATH environment variable.

    Otherwise, the plugins folder needs to be in the same folder as libvlc.dll.


  9. Mitch says:

    I downloaded both versions and have not succeded in debugging either.

    Please could you update this to work with 2012 as nothing I try from here works.


  10. Jerry Pile says:

    In addition to removing the reference to the plugins as mentioned by Mike Blakemore, I had to use the libvlc_media_new_path function rather than the libvlc_media_new_location function (this function requires the medial file to be in URI syntax). The sample is working fine for me with version 2.0.6 of the library. I am running VS 2010 on a 64 bit XP box. Thanks to George for this great sample!

  11. Vincent says:

    Hello George,

    I am a newbie to C# and I have downloaded the VLC 1.1.2 project to work on my own project. (I installed VLC 1.1.2 player) I used VS 2010 C# Express to convert and open the project. I have compiled the project and there was no error. However upon running the project, it flagged an error “unable to find an entry point named ‘libvlc_exception_init” in DLL ‘libvlc’. I am using the project files as downloaded from the website and I am not sure how to solve this problem. Any advise rendered will be very helpful. Thanks!

  12. George Helyar says:

    Hi Vincent,

    Exceptions have changed since I wrote part 1 of this, which was written for 0.98a. The 1.1.2 version should not have libvlc_exception_init at all. Please check that you have downloaded the correct file.

    Once you have the correct file, the appropriate version of libvlc.dll and libvlccore.dll should be available to your executable (e.g. in same directory).

    As 1.1.2 is also quite out of date now, once you have it working you should consider using it to learn from and moving to a newer version of libvlc. Some of the comments here should be able to help you if you have any problems.

  13. Ed Vergara says:

    Hi Ringo,

    I have downloaded what I think is the latest source code ( and have compiled it successfully.

    When I run it, I get a Vlc Exception in the VlcInstance class on this line:
    Handle = LibVlc.libvlc_new(args.Length, args);
    The instantiation returns a Handle of zero.
    Here’s the detail
    MyLibVLC.VlcException was unhandled
    Message=VLC Exception
    at MyLibVLC.VlcInstance..ctor(String[] args) in D:\MyLibVLC_112\MyLibVLC\VLC.cs:line 85
    at MyLibVLC.Form1..ctor() in D:\MyLibVLC_112\MyLibVLC\Form1.cs:line 29
    at MyLibVLC.Program.Main() in D:\MyLibVLC_112\MyLibVLC\Program.cs:line 17
    at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()

    BTW, I have VLC v2.0.8 installed on my Win7 x64 computer. I also tried it with the dll’s from v2.0.8 with same result. I’m running in on VS 2010 spk1

    Any ideas what the problem might be?

  14. George Helyar says:


    You should handle any exceptions that are generated in your application. The native function is returning a null pointer (zero handle). Read the libvlc documentation to find out why.

    This is often due to bad arguments (the documentation currently says that arguments should be not be used, but they were required in previous versions – videolan tend to break things like this with updates without warning) or an incorrect DLL. The 1.1.2 project may not be compatible with libvlc 2.0.8 without changes and the plugins directory is also required (in libvlc 2.x plugins for the correct version should be in a “plugins” directory, which should be in the same directory as your executable – the plugins path argument no longer seems to work).

    Please read other comments here for more information.

  15. Tim says:

    Any plans to migrate the project files to VLC 2.x? I am getting ready to under take the same joys of creating a viable “simple” build for VLC 2.08 x64 and then modify it to meet my needs. Thank you for your contributions to the community.

  16. George Helyar says:

    I really don’t like the attitude of the videolan/x264 devs even though the software is good, but I may migrate it to 2.x at some point for the sake of people reading this. It isn’t a big job and there are a couple of comments here that say how to do it.

    For now, you should have no problem modifying it for 2.x or even just starting from scratch, since the point of these posts were to show how to make it rather than provide yet another one for use.

  17. shmk says:

    George please write this for VLC2.x .


  18. G Reina says:


    Any idea how to implement this code for Unity3D? They really need a VLC plugin library and I’d pay good money to see it happen.


  19. Is there a easy media event which might be added to capture audio tracks buffers? Your signal is incredible -hard to believe that it has been simplified so much. I am looking to interface with hdhomerun.

  20. Kevin says:

    string[] args = new string[] {
    “-I”, “dummy”, “–ignore-config”,
    @”–plugin-path=C:\Program Files (x86)\VideoLAN\VLC\plugins”,

    “–aspect-ratio=16:9″ <= not work


  21. Vivek says:

    I have tried above code and its working.

    When tried same approach with the VLC 2.1.3,[after modifying the API signature as per the latest code in VLC 2.1.3]
    it always return null for libvlc_new() API. As plugins path can’t be set through the command line arguments, I have tried setting it through environment variable with no success.

    is anyone facing the same issue? Any suggestion what might be done to set plugin path programmatically for latest VLC.

  22. George Helyar says:

    Hi Vivek,

    As far as I know you just need the plugins in ./plugins/ relative to your executable. I’m not sure if there is still a way to specify an alternate path.

    When new() returns null, it has thrown an exception. You need to check for the exception from the libvlc API to find out what has gone wrong.

  23. rajan says:

    how can save stream in file.

  24. Jeff says:

    Hi George,

    Your code runs fine when I have VLC 1.0.2 installed on my computer and I reference the plugin path but when I uninstall VLC from my computer and just want to use the dll files to run the program, there is a command line error. Was your code originally ever able to run without VLC installed on your computer?


  25. George Helyar says:

    Hi Jeff,

    It should run as long as you have the plugins directory, which is most of the VLC installation anyway. You may be able to use a subset of the libraries. You used to be able to supply a path to this, as shown in the code, but with VLC 2.x it seems that it has to be ./plugins (where . is the current directory). It also has to use the correct version of the libvlc and plugin dlls.

  26. George says:

    Hi George,

    I’m using VLC to stream my desktop screen right now and I’m currently using the VLC media player installed on my computer and not just the libraries. I was wondering, in your code, would I just have to edit the “string args” inside Form1.cs and add in my parameters to have it provide the same functionality?

    Thank you,


  27. George Helyar says:

    Hi George,

    You should be able to do this. “args” should be the same as VLC’s command line arguments. However, this post is quite dated and you may have to make some changes for it to work.

    The most common pitfalls are the plugins directory and the versions of the dlls.

  28. Calvin says:

    I was just wondering, what is the function inside the libvlc.dll files to execute the vlc commands stored inside “string args”.


  29. George Helyar says:

    Hi Calvin,

    You pass the command line arguments to libvlc_new, although it is now recommended that you don’t pass any because they can change between versions and passing bad arguments can cause the function to fail.

  30. John Gao says:

    Hey George

    I’m currently a University Student who is working on my fourth year design project and it incorporates video streaming. Right now I’m using the vlc.exe and running the command “-vvv -I dummy screen:// :screen-fps=25 :sout=#transcode{vcodec=h264}:http{mux=ffmpeg{mux=flv},dst=:8080/live}” straight from command prompt to launch a http stream. However, this was only for testing purposes and I want to integrate my C# app with LibVLC and start streaming straight by using the LibVLC source code. I know you might be busy but I would really appreciate it if you could help me with this issue.

    If you could, could you please reply to this message or email me back at ***

    Thanks for your time,


  31. John Gao says:

    Right now, I have managed to create a media player using the .dll files from the latest version of VLC but I’m just having trouble finding the methods in order to create an http stream.


  32. George Helyar says:

    Hi John,

    I have not tried streaming with libvlc as the http server, but from what I’ve read you should be able to start the libvlc instance with the arguments that you would be using for the server on the command line, then play the media as normal to begin streaming. It may look as though it has not done anything, but you could use netstat to check if it is listening on the given port and try connecting with the client that you are currently using. If you are not using a GUI, you may need to do this in a worker thread and prevent the process from exiting as it shouldn’t block.

  33. John Gao says:

    Hi George,

    If I run my command in command prompt using vlc.exe, it streams fine, but when I changed the string args[] parameters, nothing seems to be streaming. Are there additional methods I have to call in order for this stream to work?


  34. George Helyar says:

    As far as I know there are no additional functions used to stream or transcode.

    All of the examples I could find simply passed the arguments to libvlc_new.

    For example, transcoding.

  35. John Gao says:

    So your saying, VlcInstance instance = new VlcInstance(string arguments) should do it?


  36. John Gao says:

    This is what I have right now

    string[] args = new string[] {
    “-vvv”, “-I”, “dummy”, @”–plugin-path=C:\Program Files (x86)\VideoLAN\VLC\plugins”
    ,”screen://”, “:screen-fps=25″, “:sout=#transcode{vcodec=h264}:http{mux=ffmpeg{mux=flv},dst=:8080/live}”

    VlcInstance instance = new VlcInstance(args);

  37. George Helyar says:

    Hi John,

    Check that it will actually play as a player without streaming or transcoding first. Once it visibly plays, you should be able to add the streaming and transcoding by changing these arguments.

    Some of the arguments may be bad anyway. For example, when I wrote these pages for VLC 0.8.6 you were required to supply a --plugin-path but now you can’t, you just need to put the plugin directory with your executable, so that the plugin path is .\plugins relative to your executable.

    In fact the libvlc documentation now actually says that you should not supply any arguments to libvlc_new at all. It says that argc should always be 0 and argv should always be null. However, supplying these arguments to libvlc_new may be the only way you can stream from libvlc, as there are no dedicated functions to do it, unless these functions are part of a plugin dll.

    If you have not already done so, you could ask on the libvlc forums (probably ask in C and translate to C# yourself), but in my experience the videolan developers are not particularly friendly or helpful.

    If you have no luck streaming from libvlc, you could either just start a vlc process or use a better streaming library that streams over something like rtp/rtsp. Media should probably be transcoded in advance so that you don’t have to deal with it and just have a library of media that is ready to stream, but if you really want to transcode on the fly you can pipe to and from ffmpeg on the command line or with libavcodec etc or use x264.

  38. someone says:

    Just a heads up: It still seems to work well with Version 2.0.5.
    I had to set the calling convention to cdecl though ([DllImport(“libvlc”, CallingConvention = CallingConvention.Cdecl)])

    Thanks for the article, George, it helped me a lot.

  39. Felix says:

    Hey George,

    I can’t say how much this helped me. Thanks for your article. As “someone” said if you want to use a current version of .NET (4.5) you have to change the calling convention to cdecl to get it working with 2.1.5 VLC DLL’s otherwise you’ll get a PInvokeStackImbalance Exception.

  40. hamid says:

    hey George
    thank you so much for your great code here
    it helped me so much and i can play two simultaneous videos
    but unfortunately i cant set separate options for them.
    when i define args and args1 just one of them takes effect on player
    would you please help me??
    thank you so much

  41. George Helyar says:

    Hi Hamid,

    You should just need two separate VLC instances, but I have not tried.

    The current VLC documentation recommends not using args and instead adding your settings programmatically. You should really only need two players rather than two instances, depending on what setting you want to change. My code is a bit dated now, but it was just intended to show that it’s quite simple to look at the documentation and write your own pinvoke interop for it.

Leave a Reply