c#利用libvlc.dll写了一个播放器

时间:2021-05-02 15:52:16

      最近没有事情的时候利用libvlc.dll写了一个播放器,参考了网上的一些利用libvlc.dll写播放器的例子,你可以通过SOCKET传递不同的命令来控制播放。不过可惜的是利用libvlc.dll只能在.NET FRAMEWORK2.0模式运行,更高的库不知道网上有没有。其中用到Plugin这个文件夹里的东西,在网上的一些博客至少写了代码,但是Plugin 文件夹里的东西并没有上传。通过整理我就把程序上传到网上。

其中部分代码如下:
 class VlcPlayer
    {
        private IntPtr libvlc_instance_;
        private IntPtr libvlc_media_player_;


        private double duration_;


        public VlcPlayer(string pluginPath)
        {
            string plugin_arg = "--plugin-path=" + pluginPath;
            string[] arguments = { "-I", "dummy", "--ignore-config", "--no-video-title", plugin_arg };
            libvlc_instance_ = LibVlcAPI.libvlc_new(arguments);


            libvlc_media_player_ = LibVlcAPI.libvlc_media_player_new(libvlc_instance_);
        }


        public void SetRenderWindow(int wndHandle)
        {
            if (libvlc_instance_ != IntPtr.Zero && wndHandle != 0)
            {
                LibVlcAPI.libvlc_media_player_set_hwnd(libvlc_media_player_, wndHandle);
            }
        }


        public void PlayFile(string filePath)
        {
            IntPtr libvlc_media = LibVlcAPI.libvlc_media_new_path(libvlc_instance_, filePath);
            if (libvlc_media != IntPtr.Zero)
            {
                LibVlcAPI.libvlc_media_parse(libvlc_media);
                duration_ = LibVlcAPI.libvlc_media_get_duration(libvlc_media) / 1000.0;


                LibVlcAPI.libvlc_media_player_set_media(libvlc_media_player_, libvlc_media);
                LibVlcAPI.libvlc_media_release(libvlc_media);


                LibVlcAPI.libvlc_media_player_play(libvlc_media_player_);
            }
        }


        public void Pause()
        {
            if (libvlc_media_player_ != IntPtr.Zero)
            {
                LibVlcAPI.libvlc_media_player_pause(libvlc_media_player_);
            }
        }


        public void Stop()
        {
            if (libvlc_media_player_ != IntPtr.Zero)
            {
                LibVlcAPI.libvlc_media_player_stop(libvlc_media_player_);
            }
        }


        public double GetPlayTime()
        {
            return LibVlcAPI.libvlc_media_player_get_time(libvlc_media_player_) / 1000.0;
        }


        public void SetPlayTime(double seekTime)
        {
            LibVlcAPI.libvlc_media_player_set_time(libvlc_media_player_, (Int64)(seekTime * 1000));
        }


        public int GetVolume()
        {
            return LibVlcAPI.libvlc_audio_get_volume(libvlc_media_player_);
        }


        public void SetVolume(int volume)
        {
            LibVlcAPI.libvlc_audio_set_volume(libvlc_media_player_, volume);
        }


        public void SetFullScreen(bool istrue)
        {
            LibVlcAPI.libvlc_set_fullscreen(libvlc_media_player_, istrue ? 1 : 0);
        }


        public double Duration()
        {
            return duration_;
        }


        public string Version()
        {
            return LibVlcAPI.libvlc_get_version();
        }
    }


    internal static class LibVlcAPI
    {
        internal struct PointerToArrayOfPointerHelper
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
            public IntPtr[] pointers;
        }


        public static IntPtr libvlc_new(string[] arguments)
        {
            PointerToArrayOfPointerHelper argv = new PointerToArrayOfPointerHelper();
            argv.pointers = new IntPtr[11];


            for (int i = 0; i < arguments.Length; i++)
            {
                argv.pointers[i] = Marshal.StringToHGlobalAnsi(arguments[i]);
            }


            IntPtr argvPtr = IntPtr.Zero;
            try
            {
                int size = Marshal.SizeOf(typeof(PointerToArrayOfPointerHelper));
                argvPtr = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(argv, argvPtr, false);
                return libvlc_new(arguments.Length, argvPtr);
            }
            finally
            {
                for (int i = 0; i < arguments.Length + 1; i++)
                {
                    if (argv.pointers[i] != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(argv.pointers[i]);
                    }
                }
                if (argvPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(argvPtr);
                }
            }
        }


        public static IntPtr libvlc_media_new_path(IntPtr libvlc_instance, string path)
        {
            IntPtr pMrl = IntPtr.Zero;
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(path);
                pMrl = Marshal.AllocHGlobal(bytes.Length + 1);
                Marshal.Copy(bytes, 0, pMrl, bytes.Length);
                Marshal.WriteByte(pMrl, bytes.Length, 0);
                return libvlc_media_new_path(libvlc_instance, pMrl);
            }
            finally
            {
                if (pMrl != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pMrl);
                }
            }
        }


        public static IntPtr libvlc_media_new_location(IntPtr libvlc_instance, string path)
        {
            IntPtr pMrl = IntPtr.Zero;
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(path);
                pMrl = Marshal.AllocHGlobal(bytes.Length + 1);
                Marshal.Copy(bytes, 0, pMrl, bytes.Length);
                Marshal.WriteByte(pMrl, bytes.Length, 0);
                return libvlc_media_new_path(libvlc_instance, pMrl);
            }
            finally
            {
                if (pMrl != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pMrl);
                }
            }
        }


        // ----------------------------------------------------------------------------------------
        // 以下是libvlc.dll导出函数


        // 创建一个libvlc实例,它是引用计数的
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        private static extern IntPtr libvlc_new(int argc, IntPtr argv);


        // 释放libvlc实例
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_release(IntPtr libvlc_instance);


        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern String libvlc_get_version();


        // 从视频来源(例如Url)构建一个libvlc_meida
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        private static extern IntPtr libvlc_media_new_location(IntPtr libvlc_instance, IntPtr path);


        // 从本地文件路径构建一个libvlc_media
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        private static extern IntPtr libvlc_media_new_path(IntPtr libvlc_instance, IntPtr path);


        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_release(IntPtr libvlc_media_inst);


        // 创建libvlc_media_player(播放核心)
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern IntPtr libvlc_media_player_new(IntPtr libvlc_instance);


        // 将视频(libvlc_media)绑定到播放器上
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_player_set_media(IntPtr libvlc_media_player, IntPtr libvlc_media);


        // 设置图像输出的窗口
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_player_set_hwnd(IntPtr libvlc_mediaplayer, Int32 drawable);


        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_player_play(IntPtr libvlc_mediaplayer);


        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_player_pause(IntPtr libvlc_mediaplayer);


        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_player_stop(IntPtr libvlc_mediaplayer);


        // 解析视频资源的媒体信息(如时长等)
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_parse(IntPtr libvlc_media);


        // 返回视频的时长(必须先调用libvlc_media_parse之后,该函数才会生效)
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern Int64 libvlc_media_get_duration(IntPtr libvlc_media);


        // 当前播放的时间
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern Int64 libvlc_media_player_get_time(IntPtr libvlc_mediaplayer);


        // 设置播放位置(拖动)
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_player_set_time(IntPtr libvlc_mediaplayer, Int64 time);


        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_media_player_release(IntPtr libvlc_mediaplayer);


        // 获取和设置音量
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern int libvlc_audio_get_volume(IntPtr libvlc_media_player);


        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_audio_set_volume(IntPtr libvlc_media_player, int volume);


        // 设置全屏
        [DllImport("libvlc", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
        [SuppressUnmanagedCodeSecurity]
        public static extern void libvlc_set_fullscreen(IntPtr libvlc_media_player, int isFullScreen);
    }


Play.cs文件如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text.RegularExpressions;
using System.Timers;


namespace videoplay
{
    public partial class Play : Form
    {
        private VlcPlayer vlc_player_;
        private bool is_playinig_;
        private string currentfilepath = "";
        Thread t = null;
        bool flag = true;
        private static object LockObject = new Object();
        // 定义数据检查Timer
        private static System.Timers.Timer CheckUpdatetimer = new System.Timers.Timer();
        // 检查更新锁
        private static int CheckUpDateLock = 0;
        public Play()
        {
            InitializeComponent();
            //到达时间的时候执行事件;
            string pluginPath = System.Environment.CurrentDirectory + "\\plugins\\";
            vlc_player_ = new VlcPlayer(pluginPath);
            IntPtr render_wnd = this.panel1.Handle;
            vlc_player_.SetRenderWindow((int)render_wnd);
            tbVideoTime.Text = "00:00:00/00:00:00";
            is_playinig_ = false;
            Thread th = new Thread(new ThreadStart(ListenThreadProc));
            th.IsBackground = true;
            th.Start();


        }


        ///
        /// 设定数据检查Timer参数
        ///
        internal void GetTimerStart()
        {
            // 循环间隔时间(10分钟)
            CheckUpdatetimer.Interval = 1000;
            // 允许Timer执行
            CheckUpdatetimer.Enabled = true;
            // 定义回调
            CheckUpdatetimer.Elapsed += new ElapsedEventHandler(CheckUpdatetimer_Elapsed);
            // 定义多次循环
            CheckUpdatetimer.AutoReset = true;
        }


        private void CheckUpdatetimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 加锁检查更新锁
            lock (LockObject)
            {
                if (CheckUpDateLock == 0) CheckUpDateLock = 1;
                else return;
            }


            //More code goes here.
            //具体实现功能的方法
            MethodInvoker methodInvoker = new MethodInvoker(Checktimer);
            this.Invoke(methodInvoker);
            // 解锁更新检查锁
            lock (LockObject)
            {
                CheckUpDateLock = 0;
            }
        }


        private void Checktimer()
        {


            if (is_playinig_)
            {
                if (trackBar1.Value == trackBar1.Maximum)
                {
                    vlc_player_.Stop();
                    CheckUpdatetimer.Stop();
                }
                else
                {
                    trackBar1.Value = trackBar1.Value + 1;
                    tbVideoTime.Text = string.Format("{0}/{1}",
                        GetTimeString(trackBar1.Value),
                        GetTimeString(trackBar1.Maximum));
                }
            }
        }








        private void VidepPlayAvi(string filepath)
        {
            try
            {
                is_playinig_ = true;
                vlc_player_.PlayFile(filepath);
                MethodInvoker methodInvoker = new MethodInvoker(TrackVlaue);
                this.Invoke(methodInvoker);
            }
            catch
            { }


        }


        private void TrackVlaue()
        {
            trackBar1.SetRange(0, (int)vlc_player_.Duration());
            trackBar1.Value = 0;
            CheckUpdatetimer.Start();


        }


        private void CloseVideo()
        {
            if (is_playinig_)
            {
                vlc_player_.Stop();
                trackBar1.Value = 0;
                CheckUpdatetimer.Stop();
                is_playinig_ = false;
            }
        }


        private void PauseVideo()
        {
            if (is_playinig_)
            {
                vlc_player_.Pause();
                trackBar1.Value = 0;
                CheckUpdatetimer.Stop();
                is_playinig_ = false;
            }
        }


        private void GoForwardVideo(double time)
        {
            if (is_playinig_)
            {
                vlc_player_.SetPlayTime(time);
                trackBar1.Value = (int)vlc_player_.GetPlayTime();
            }
        }


        private void SetVolumeVideo(int value)
        {
            if (is_playinig_)
            {
                vlc_player_.SetVolume(value);
            }
        }




        private string GetTimeString(int val)
        {
            int hour = val / 3600;
            val %= 3600;
            int minute = val / 60;
            int second = val % 60;
            return string.Format("{0:00}:{1:00}:{2:00}", hour, minute, second);
        }


        #region socket
        int SocketTimeOut = 500;
        bool ContinueListening = true;
        Socket sok = null;
        public void ListenThreadProc()
        {
            IPAddress ipAddress = IPAddress.Parse(System.Configuration.ConfigurationManager.AppSettings["Ipaddress"]);
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["Port"]));
            try
            {
                //创建Socket:
                sok = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sok.Bind(ipEndPoint);
                sok.Listen(100); //100: Listen Queue Size
                EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                byte[] buf = new byte[1024];
                while (ContinueListening)
                {
                    Socket s = sok.Accept();//阻塞
                    if (ContinueListening) // 当循环被通知退出时,为 false
                    {
                        ThreadPool.QueueUserWorkItem(new WaitCallback(HttpWorkerThread), s);
                    }
                }
                //关闭连接
                if (sok.Connected)
                {
                    sok.Shutdown(SocketShutdown.Both);
                }
                sok.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show("\r\n----" + e.Message + "\r\n");
            }
        }
        //delegate 


        delegate void MyDelegate(string str);    //声明代理
        delegate void MyDelegate1(double time);    //声明代理
        delegate void MyDelegate2(int  vlaue);    //声明代理


        public void HttpWorkerThread(object args)
        {
            Socket s = (Socket)args;
            if (s != null && ContinueListening)
            {
                //设置超时:
                try
                {
                    s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, SocketTimeOut * 1000);
                    s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, SocketTimeOut * 1000);
                    //开始接收TCP:


                    int rc, RecvLen = 0;
                    int clen = -1;
                    while (ContinueListening)
                    {
                        byte[] buf = new byte[1024];
                        if (clen > 0 && RecvLen >= clen) break;//超过Content-Length,退出循环
                        rc = s.Receive(buf, 0, buf.Length, SocketFlags.None);
                        if (rc > 0)
                        {
                          //接收到数据后处理操作
                        }
                        else break;
                    }
                    //关闭连接
                    s.Shutdown(SocketShutdown.Both);
                    s.Close();
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
        }
        #endregion






        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            if (is_playinig_)
            {
                vlc_player_.SetPlayTime(trackBar1.Value);
                trackBar1.Value = (int)vlc_player_.GetPlayTime();
            }
        }


        private void Play_FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseVideo();
            //关闭连接
            if (sok.Connected)
            {
                sok.Shutdown(SocketShutdown.Both);
            }
            sok.Close();
        }


        private void Play_Load(object sender, EventArgs e)
        {


            GetTimerStart();
        }
    }

}

其余的代码上传到网上,然后提供大家下载http://download.csdn.net/detail/cuiweibin5/8259681