基于VLC的Unity视频播放器(一)

2023-11-14

思路来自 http://blog.csdn.net/yechen2320374/article/details/52226294

 

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.IO;
using System.Threading;

namespace Net.Media
{
    //定义替代变量
    using libvlc_media_t = System.IntPtr;
    using libvlc_media_player_t = System.IntPtr;
    using libvlc_instance_t = System.IntPtr;

    public class MediaPlayer
    {
        #region 全局变量
        //数组转换为指针
        internal struct PointerToArrayOfPointerHelper
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
            public IntPtr[] pointers;
        }

        //vlc库启动参数配置
        //private static string pluginPath = System.Environment.CurrentDirectory + "\\Plugins\\VLC\\plugins\\";

        private static string pluginPath = @UnityEngine.Application.dataPath + "/Plugins/";
        
        private static string plugin_arg = "--plugin-path=" + pluginPath;
        //用于播放节目时,转录节目
        //private static string program_arg = "--sout=#duplicate{dst=std{access=file,mux=ts,dst=d:/test.ts}}";
        private static string[] arguments = { "-I", "dummy", "--ignore-config", "--no-video-title", plugin_arg };//, program_arg };

        #region 结构体
        public struct libvlc_media_stats_t
        {
            /* Input */
            public int i_read_bytes;
            public float f_input_bitrate;

            /* Demux */
            public int i_demux_read_bytes;
            public float f_demux_bitrate;
            public int i_demux_corrupted;
            public int i_demux_discontinuity;

            /* Decoders */
            public int i_decoded_video;
            public int i_decoded_audio;

            /* Video Output */
            public int i_displayed_pictures;
            public int i_lost_pictures;

            /* Audio output */
            public int i_played_abuffers;
            public int i_lost_abuffers;

            /* Stream output */
            public int i_sent_packets;
            public int i_sent_bytes;
            public float f_send_bitrate;
        }
        #endregion

        #endregion

        #region 公开函数
        /// <summary>
        /// 创建VLC播放资源索引
        /// </summary>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static libvlc_instance_t Create_Media_Instance()
        {
            libvlc_instance_t libvlc_instance = IntPtr.Zero;
            IntPtr argvPtr = IntPtr.Zero;

            try
            {
                if (arguments.Length == 0 ||
                    arguments == null)
                {
                    return IntPtr.Zero;
                }

                //将string数组转换为指针
                argvPtr = StrToIntPtr(arguments);
                if (argvPtr == null || argvPtr == IntPtr.Zero)
                {
                    return IntPtr.Zero;
                }

                //设置启动参数
                libvlc_instance = SafeNativeMethods.libvlc_new(arguments.Length, argvPtr);
                if (libvlc_instance == null || libvlc_instance == IntPtr.Zero)
                {
                    return IntPtr.Zero;
                }

                return libvlc_instance;
            }
            catch
            {
                return IntPtr.Zero;
            }
        }

        /// <summary>
        /// 释放VLC播放资源索引
        /// </summary>
        /// <param name="libvlc_instance">VLC 全局变量</param>
        public static void Release_Media_Instance(libvlc_instance_t libvlc_instance)
        {
            try
            {
                if (libvlc_instance != IntPtr.Zero ||
                    libvlc_instance != null)
                {
                    SafeNativeMethods.libvlc_release(libvlc_instance);
                }

                libvlc_instance = IntPtr.Zero;
            }
            catch (Exception)
            {
                libvlc_instance = IntPtr.Zero;
            }
        }

        /// <summary>
        /// 创建VLC播放器
        /// </summary>
        /// <param name="libvlc_instance">VLC 全局变量</param>
        /// <param name="handle">VLC MediaPlayer需要绑定显示的窗体句柄</param>
        /// <returns></returns>
        public static libvlc_media_player_t Create_MediaPlayer(libvlc_instance_t libvlc_instance, IntPtr handle)
        {
            libvlc_media_player_t libvlc_media_player = IntPtr.Zero;

            try
            {
                if (libvlc_instance == IntPtr.Zero ||
                    libvlc_instance == null ||
                    handle == IntPtr.Zero ||
                    handle == null)
                {
                    return IntPtr.Zero;
                }

                //创建播放器
                libvlc_media_player = SafeNativeMethods.libvlc_media_player_new(libvlc_instance);
                if (libvlc_media_player == null || libvlc_media_player == IntPtr.Zero)
                {
                    return IntPtr.Zero;
                }

                //设置播放窗口            
                //SafeNativeMethods.libvlc_media_player_set_hwnd(libvlc_media_player, (int)handle);

                return libvlc_media_player;
            }
            catch
            {
                SafeNativeMethods.libvlc_media_player_release(libvlc_media_player);

                return IntPtr.Zero;
            }
        }

        /// <summary>
        /// 释放媒体播放器
        /// </summary>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        public static void Release_MediaPlayer(libvlc_media_player_t libvlc_media_player)
        {
            try
            {
                if (libvlc_media_player != IntPtr.Zero ||
                    libvlc_media_player != null)
                {
                    if (SafeNativeMethods.libvlc_media_player_is_playing(libvlc_media_player))
                    {
                        SafeNativeMethods.libvlc_media_player_stop(libvlc_media_player);
                    }

                    SafeNativeMethods.libvlc_media_player_release(libvlc_media_player);
                }

                libvlc_media_player = IntPtr.Zero;
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                libvlc_media_player = IntPtr.Zero;
            }
        }

        /// <summary>
        /// 播放网络媒体
        /// </summary>
        /// <param name="libvlc_instance">VLC 全局变量</param>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        /// <param name="url">网络视频URL,支持http、rtp、udp等格式的URL播放</param>
        /// <returns></returns>
        public static bool NetWork_Media_Play(libvlc_instance_t libvlc_instance, libvlc_media_player_t libvlc_media_player, string url)
        {
            IntPtr pMrl = IntPtr.Zero;
            libvlc_media_t libvlc_media = IntPtr.Zero;

            try
            {
                if (url == null ||
                    libvlc_instance == IntPtr.Zero ||
                    libvlc_instance == null ||
                    libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }
                UnityEngine.Debug.Log("url:" + url);
                pMrl = StrToIntPtr(url);
                if (pMrl == null || pMrl == IntPtr.Zero)
                {
                    return false;
                }

                //播放网络文件
                libvlc_media = SafeNativeMethods.libvlc_media_new_location(libvlc_instance, pMrl);

                if (libvlc_media == null || libvlc_media == IntPtr.Zero)
                {
                    return false;
                }

                SafeNativeMethods.libvlc_media_parse(libvlc_media);
                long duration = SafeNativeMethods.libvlc_media_get_duration(libvlc_media);
                UnityEngine.Debug.Log("duration: " + duration / 1000);

                //将Media绑定到播放器上
                SafeNativeMethods.libvlc_media_player_set_media(libvlc_media_player, libvlc_media);

                //释放libvlc_media资源
                SafeNativeMethods.libvlc_media_release(libvlc_media);
                libvlc_media = IntPtr.Zero;
                if (0 != SafeNativeMethods.libvlc_media_player_play(libvlc_media_player))
                {
                    return false;
                }

                //休眠指定时间
                Thread.Sleep(500);

                return true;
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                //释放libvlc_media资源
                if (libvlc_media != IntPtr.Zero)
                {
                    SafeNativeMethods.libvlc_media_release(libvlc_media);
                }
                libvlc_media = IntPtr.Zero;

                return false;
            }
        }

        public static void SetFormart(libvlc_media_player_t libvlc_media_player, string formart, int width, int height, int pitch)
        {
            SafeNativeMethods.libvlc_video_set_format(libvlc_media_player, StrToIntPtr(formart), width, height, pitch);
        }

        public static int GetMediaWidth(libvlc_media_player_t libvlc_media_player)
        {
            int width = SafeNativeMethods.libvlc_video_get_width(libvlc_media_player);
            UnityEngine.Debug.Log("width: " + width);
            return width;
        }

        public static int GetMediaHeight(libvlc_media_player_t libvlc_media_player)
        {
            int height = SafeNativeMethods.libvlc_video_get_height(libvlc_media_player);
            UnityEngine.Debug.Log("height: " + height);
            return height;
        }



        /// <summary>
        /// 暂停或恢复视频
        /// </summary>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        /// <returns></returns>
        public static bool MediaPlayer_Pause(libvlc_media_player_t libvlc_media_player)
        {
            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                if (SafeNativeMethods.libvlc_media_player_can_pause(libvlc_media_player))
                {
                    SafeNativeMethods.libvlc_media_player_pause(libvlc_media_player);

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                return false;
            }
        }

        /// <summary>
        /// 停止播放
        /// </summary>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        /// <returns></returns>
        public static bool MediaPlayer_Stop(libvlc_media_player_t libvlc_media_player)
        {
            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                SafeNativeMethods.libvlc_media_player_stop(libvlc_media_player);

                return true;
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                return false;
            }
        }

        /// <summary>
        /// 快进
        /// </summary>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        /// <returns></returns>
        public static bool MediaPlayer_Forward(libvlc_media_player_t libvlc_media_player)
        {
            double time = 0;

            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                if (SafeNativeMethods.libvlc_media_player_is_seekable(libvlc_media_player))
                {
                    time = SafeNativeMethods.libvlc_media_player_get_time(libvlc_media_player) / 1000.0;
                    if (time == -1)
                    {
                        return false;
                    }

                    SafeNativeMethods.libvlc_media_player_set_time(libvlc_media_player, (Int64)((time + 30) * 1000));

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                return false;
            }
        }

        /// <summary>
        /// 快退
        /// </summary>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        /// <returns></returns>
        public static bool MediaPlayer_Back(libvlc_media_player_t libvlc_media_player)
        {
            double time = 0;

            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                if (SafeNativeMethods.libvlc_media_player_is_seekable(libvlc_media_player))
                {
                    time = SafeNativeMethods.libvlc_media_player_get_time(libvlc_media_player) / 1000.0;
                    if (time == -1)
                    {
                        return false;
                    }

                    if (time - 30 < 0)
                    {
                        SafeNativeMethods.libvlc_media_player_set_time(libvlc_media_player, (Int64)(1 * 1000));
                    }
                    else
                    {
                        SafeNativeMethods.libvlc_media_player_set_time(libvlc_media_player, (Int64)((time - 30) * 1000));
                    }

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                return false;
            }
        }

        /// <summary>
        /// VLC MediaPlayer是否在播放
        /// </summary>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        /// <returns></returns>
        public static bool MediaPlayer_IsPlaying(libvlc_media_player_t libvlc_media_player)
        {
            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                return SafeNativeMethods.libvlc_media_player_is_playing(libvlc_media_player);
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                return false;
            }
        }

        /// <summary>
        /// 录制快照
        /// </summary>
        /// <param name="libvlc_media_player">VLC MediaPlayer变量</param>
        /// <param name="path">快照要存放的路径</param>
        /// <param name="name">快照保存的文件名称</param>
        /// <returns></returns>
        public static bool TakeSnapShot(libvlc_media_player_t libvlc_media_player, string path, string name)
        {
            try
            {
                string snap_shot_path = null;

                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                //if (!Directory.Exists(path))
                //{
                //    Directory.CreateDirectory(path);
                //}

                snap_shot_path = path + "\\" + name;

                if (0 == SafeNativeMethods.libvlc_video_take_snapshot(libvlc_media_player, 0, snap_shot_path.ToCharArray(), 1024, 576))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                return false;
            }
        }

        /// <summary>
        /// 获取信息
        /// </summary>
        /// <param name="libvlc_media_player"></param>
        /// <returns></returns>
        public static bool GetMedia(libvlc_media_player_t libvlc_media_player)
        {
            libvlc_media_t media = IntPtr.Zero;

            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                media = SafeNativeMethods.libvlc_media_player_get_media(libvlc_media_player);
                if (media == IntPtr.Zero || media == null)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message);
                return false;
            }
        }

        /// <summary>
        /// 获取已经显示的图片数
        /// </summary>
        /// <param name="libvlc_media_player"></param>
        /// <returns></returns>
        public static int GetDisplayedPictures(libvlc_media_player_t libvlc_media_player)
        {
            libvlc_media_t media = IntPtr.Zero;
            libvlc_media_stats_t media_stats = new libvlc_media_stats_t();
            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return 0;
                }

                media = SafeNativeMethods.libvlc_media_player_get_media(libvlc_media_player);
                if (media == IntPtr.Zero || media == null)
                {
                    return 0;
                }

                if (1 == SafeNativeMethods.libvlc_media_get_stats(media, ref media_stats))
                {
                    return media_stats.i_displayed_pictures;
                }
                else
                {
                    return 0;
                }
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// 设置全屏
        /// </summary>
        /// <param name="libvlc_media_player"></param>
        /// <param name="isFullScreen"></param>
        public static bool SetFullScreen(libvlc_media_player_t libvlc_media_player, int isFullScreen)
        {
            try
            {
                if (libvlc_media_player == IntPtr.Zero ||
                    libvlc_media_player == null)
                {
                    return false;
                }

                SafeNativeMethods.libvlc_set_fullscreen(libvlc_media_player, isFullScreen);

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static void SetCallbacks(libvlc_media_player_t libvlc_media_player,VideoLockCB lockcb,VideoUnlockCB unlockcb, VideoDisplayCB displaycb, IntPtr opaque)
        {
            try
            {
                SafeNativeMethods.libvlc_video_set_callbacks(libvlc_media_player, lockcb, unlockcb, displaycb, opaque);
                UnityEngine.Debug.Log("SetCallbacks");
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError(e.Message); 
            }
        }

        #endregion


        public delegate IntPtr VideoLockCB(IntPtr opaque, IntPtr planes);
        public delegate void VideoUnlockCB(IntPtr opaque, IntPtr picture, IntPtr planes);
        //显示图片
        public delegate void VideoDisplayCB(IntPtr opaque, IntPtr picture);



        #region 私有函数
        //将string []转换为IntPtr
        public static IntPtr StrToIntPtr(string[] args)
        {
            try
            {
                IntPtr ip_args = IntPtr.Zero;

                PointerToArrayOfPointerHelper argv = new PointerToArrayOfPointerHelper();
                argv.pointers = new IntPtr[11];

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

                int size = Marshal.SizeOf(typeof(PointerToArrayOfPointerHelper));
                ip_args = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(argv, ip_args, false);

                return ip_args;
            }
            catch (Exception)
            {
                return IntPtr.Zero;
            }
        }

        //将string转换为IntPtr
        private static IntPtr StrToIntPtr(string url)
        {
            try
            {
                if (string.IsNullOrEmpty(url))
                {
                    return IntPtr.Zero;
                }

                IntPtr pMrl = IntPtr.Zero;
                byte[] bytes = Encoding.UTF8.GetBytes(url);

                pMrl = Marshal.AllocHGlobal(bytes.Length + 1);
                Marshal.Copy(bytes, 0, pMrl, bytes.Length);
                Marshal.WriteByte(pMrl, bytes.Length, 0);

                return pMrl;
            }
            catch (Exception)
            {
                return IntPtr.Zero;
            }
        }
        #endregion

        #region 导入库函数
        [SuppressUnmanagedCodeSecurity]
        internal static class SafeNativeMethods
        {
            // 创建一个libvlc实例,它是引用计数的
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern libvlc_instance_t libvlc_new(int argc, IntPtr argv);

            // 释放libvlc实例
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_release(libvlc_instance_t libvlc_instance);

            //获取libvlc的版本
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern String libvlc_get_version();

            //从视频来源(例如http、rtsp)构建一个libvlc_meida
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern libvlc_media_t libvlc_media_new_location(libvlc_instance_t libvlc_instance, IntPtr path);

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

            //释放libvlc_media
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_media_release(libvlc_media_t libvlc_media_inst);

            // 创建一个空的播放器
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern libvlc_media_player_t libvlc_media_player_new(libvlc_instance_t libvlc_instance);

            //从libvlc_media构建播放器
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern libvlc_media_player_t libvlc_media_player_new_from_media(libvlc_media_t libvlc_media);

            //释放播放器资源
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_media_player_release(libvlc_media_player_t libvlc_mediaplayer);

            // 将视频(libvlc_media)绑定到播放器上
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_media_player_set_media(libvlc_media_player_t libvlc_media_player, libvlc_media_t libvlc_media);

            // 设置编码
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_video_set_format(libvlc_media_player_t libvlc_media_player, IntPtr chroma, Int32 width, Int32 height, Int32 pitch);





           


            // 视频每一帧的数据信息
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_video_set_callbacks(libvlc_media_player_t libvlc_mediaplayer,
                VideoLockCB lockCB,
                VideoUnlockCB unlockCB,
                VideoDisplayCB displayCB,
                IntPtr opaque);
             
            // 设置图像输出的窗口
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_media_player_set_hwnd(libvlc_media_player_t libvlc_mediaplayer, Int32 drawable);

            //播放器播放
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern int libvlc_media_player_play(libvlc_media_player_t libvlc_mediaplayer);

            //播放器暂停
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_media_player_pause(libvlc_media_player_t libvlc_mediaplayer);

            //播放器停止
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_media_player_stop(libvlc_media_player_t libvlc_mediaplayer);

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

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern Int32 libvlc_video_get_width(libvlc_media_player_t libvlc_mediaplayer);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern Int32 libvlc_video_get_height(libvlc_media_player_t libvlc_mediaplayer);

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

            // 当前播放时间
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern Int64 libvlc_media_player_get_time(libvlc_media_player_t libvlc_mediaplayer);

            // 设置播放时间
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_media_player_set_time(libvlc_media_player_t libvlc_mediaplayer, Int64 time);

            // 获取音量
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern int libvlc_audio_get_volume(libvlc_media_player_t libvlc_media_player);

            //设置音量
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_audio_set_volume(libvlc_media_player_t libvlc_media_player, int volume);

            // 设置全屏
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_set_fullscreen(libvlc_media_player_t libvlc_media_player, int isFullScreen);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern int libvlc_get_fullscreen(libvlc_media_player_t libvlc_media_player);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern void libvlc_toggle_fullscreen(libvlc_media_player_t libvlc_media_player);

            //判断播放时是否在播放
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern bool libvlc_media_player_is_playing(libvlc_media_player_t libvlc_media_player);

            //判断播放时是否能够Seek
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern bool libvlc_media_player_is_seekable(libvlc_media_player_t libvlc_media_player);

            //判断播放时是否能够Pause
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern bool libvlc_media_player_can_pause(libvlc_media_player_t libvlc_media_player);

            //判断播放器是否可以播放
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern int libvlc_media_player_will_play(libvlc_media_player_t libvlc_media_player);

            //进行快照
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern int libvlc_video_take_snapshot(libvlc_media_player_t libvlc_media_player, int num, char[] filepath, int i_width, int i_height);

            //获取Media信息
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern libvlc_media_t libvlc_media_player_get_media(libvlc_media_player_t libvlc_media_player);

            //获取媒体信息
            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
            internal static extern int libvlc_media_get_stats(libvlc_media_t libvlc_media, ref libvlc_media_stats_t lib_vlc_media_stats);
        }
        #endregion
    }
}

 

 

 

 

 

 

using Net.Media;
using System; 
using System.Runtime.InteropServices;
using UnityEngine;
public class Test : MonoBehaviour
{
    //视频宽
    public int width;
    //视频高
    public int height;
    public Texture2D texture;
    public Material mat;
    IntPtr libvlc_instance_t;
    IntPtr libvlc_media_player_t;
    IntPtr handle;

    private MediaPlayer.VideoLockCB _videoLockCB;
    private MediaPlayer.VideoUnlockCB _videoUnlockCB;
    private MediaPlayer.VideoDisplayCB _videoDisplayCB;

    private const int _width = 1024;
    private const int _height = 576;
    private const int _pixelBytes = 4;
    private const int _pitch = 1024 * _pixelBytes;
    private IntPtr _buff = IntPtr.Zero;

    private float fireRate = 0.02F;
    private float nextFire = 0.0F;
    bool ready = false;
    // Use this for initialization
    void Start()
    {
        if (_videoLockCB == null)
            _videoLockCB = new MediaPlayer.VideoLockCB(VideoLockCallBack);
        if (_videoUnlockCB == null)
            _videoUnlockCB = new MediaPlayer.VideoUnlockCB(VideoUnlockCallBack);
        if (_videoDisplayCB == null)
            _videoDisplayCB = new MediaPlayer.VideoDisplayCB(VideoDiplayCallBack);

        texture = new Texture2D(1024, 576, TextureFormat.RGBA32, false);
        mat.mainTexture = texture;
        _buff = Marshal.AllocHGlobal(_pitch * _height);
        handle = new IntPtr(1);

        libvlc_instance_t = MediaPlayer.Create_Media_Instance();

        libvlc_media_player_t = MediaPlayer.Create_MediaPlayer(libvlc_instance_t, handle);
         
        MediaPlayer.SetCallbacks(libvlc_media_player_t, _videoLockCB, _videoUnlockCB, _videoDisplayCB, IntPtr.Zero);
         
        //"file:///"+Application.streamingAssetsPath+"/test.mp4");rtmp://live.hkstv.hk.lxdns.com/live/hks
        //bool ready = MediaPlayer.NetWork_Media_Play(libvlc_instance_t, libvlc_media_player_t, "rtsp://127.0.0.1:8554/1");
        ready = MediaPlayer.NetWork_Media_Play(libvlc_instance_t, 
            libvlc_media_player_t,
            "file:///" + Application.streamingAssetsPath + "/test.mp4");
        Debug.Log(ready);

        width = MediaPlayer.GetMediaWidth(libvlc_media_player_t);
        height = MediaPlayer.GetMediaHeight(libvlc_media_player_t);
        //"ARGB"
        MediaPlayer.SetFormart(libvlc_media_player_t, "ARGB", _width, _height, _width * 4);

        Debug.Log(MediaPlayer.MediaPlayer_IsPlaying(libvlc_media_player_t));
        Debug.Log(Application.dataPath);
    }


    // Update is called once per frame
    void Update()
    { 
        //if (ready && Time.time > nextFire)
        //{ 
            //Debug.Log(Islock());
            if (Islock())
            {
                texture.LoadRawTextureData(_buff, _buff.ToInt32());
                texture.Apply(); 
            }
            //nextFire = Time.time + fireRate;
        //}
    }

    private void OnGUI()
    {
        if(GUI.Button(new Rect(0,0,100,100),"Take"))
        {
          Debug.Log (MediaPlayer.TakeSnapShot(libvlc_media_player_t, @Application.streamingAssetsPath, "testa.jpg"));
        }
         
    }

    private IntPtr VideoLockCallBack(IntPtr opaque, IntPtr planes)
    {
        Lock(); 
        Marshal.WriteIntPtr(planes, _buff);//初始化 
        //Debug.Log("Lock");
        return IntPtr.Zero;
    }
    private void VideoUnlockCallBack(IntPtr opaque, IntPtr picture, IntPtr planes)
    {
        Unlock();
        //Debug.Log("Unlock");
    }
    private void VideoDiplayCallBack(IntPtr opaque, IntPtr picture)
    {
        if (Islock())
        {
            //Debug.Log("Islock");
            //texture.LoadRawTextureData(picture, picture.ToInt32());
            //texture.Apply();
            //fwrite(buffer, sizeof buffer, 1, fp);  
        }
    }


    bool obj = false;
    private void Lock()
    {
        obj = true;
    }
    private void Unlock()
    {
        obj = false;
    }
    private bool Islock()
    {
        return obj;
    }

    private void OnDestroy()
    {

    }

    [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
    private static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);

    private void OnApplicationQuit()
    {
        try
        {
            Debug.Log(MediaPlayer.MediaPlayer_IsPlaying(libvlc_media_player_t));

            if (MediaPlayer.MediaPlayer_IsPlaying(libvlc_media_player_t))
            {
                MediaPlayer.MediaPlayer_Stop(libvlc_media_player_t);
            }

            MediaPlayer.Release_MediaPlayer(libvlc_media_player_t);

            MediaPlayer.Release_Media_Instance(libvlc_instance_t);
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
        }
    }
}

 

 

 

 

 

暂停、停止、快进、音量等都还没做

win10x64 Unity 5.6.2f1 (64-bit)点击这里下载工程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于VLC的Unity视频播放器(一) 的相关文章

  • Retrofit统一异常处理

    一 杂谈 前一阵子博客备案因为名字问题被驳回了两次也是够了 现在在公司里一直写业务代码 这让本来就不会的算法的我算法水平更加烂 最近在跟着优酷上的一个小姐姐学魔方 智商跟不太上了啊哈哈哈哈哈 OK 步入正题 名字叫Retrofit异常处理

随机推荐

  • 向量点积与叉积等几何的定义及应用研究

    要计算两个向量的点积 需要将两个向量的对应分量相乘 然后再将乘积相加 下面这段代码可以计算出两个二维向量的点积 var dotProduct vectorOne x vectorTwo x vectorOne y vectorTwo y 计
  • 跟我学Java设计模式第4天:结构型模式大全

    5 结构型模式 5 6 组合模式 5 6 1 概述 对于这个图片肯定会非常熟悉 上图我们可以看做是一个文件系统 对于这样的结构我们称之为树形结构 在树形结构中可以通过调用某个方法来遍历整个树 当我们找到某个叶子节点后 就可以对叶子节点进行相
  • linux下进程绑定cpu情况查看

    linux下进程绑定cpu情况查看的几种方法 1 pidstat命令 查看进程使用cpu情况 如果绑定了多个cpu会都显示出来 pidstat p pidof 进程名 t 1 2 top命令 1 top 2 按f键可以选择下面配置选项 P
  • public void doGet(HttpServletRequest request, HttpServletResponse response)

  • 猿如意工具-【SwitchHosts】详情介绍

    一 什么是猿如意 在发表文章的契机下 看到了 猿如意 这个名词 处于好奇 点击进行了解 发现是我们熟悉的CSDN提供的一个面向开发者的辅助开发工具箱 猿如意的意思是 程序猿 员 的如意兵器 它提供效率工具 开发工具的下载 教程文档 代码片段
  • 【Vim】IdeaVim高级玩法之EasyMotion插件

    本文将介绍IDEA中的IdeaVim插件提供的EasyMotion拓展插件 什么是EasyMotion EasyMotion起源是Vim的一个插件 正如它的名字所表明的一样 EasyMotion可以让你在Vim中以更简单的方式移动 一旦熟练
  • gradle7.0.2如何发布jitpack开源项目

    前言 gradle 可以说发展十分迅速 一下子就飙升 7 0 2 了 当你想用 github jitpack 发布自己的开源项目的时候 网上找的教程都是 基于gradle 3 4 版本的 里面还说道要依赖 android maven gra
  • shell编程笔记3--shell并发

    shell编程笔记3 shell并发 shell编程笔记3 shell并发 介绍 并发方法 1 简单后台方式 2 普通控制并发量方式 3 通过管道控制并发量 参考文献 shell编程笔记3 shell并发 介绍 在shell中适当使用并发功
  • 《前端》样式冲突,怎么解决--2020年3月30日

    有时候我引用了bootstrap样式 自己也定义了 样式 但是我看后台应用的是bootstrap包装好的样式 很多时候 其实是我愚蠢的总把id选择器 用了 其实应该用 还有的时候 element style 的样式也阻挡了我自定义的样式 这
  • 阿里云免费证书“fileauth.txt内容配置错误”解决

    最近研究微信小程序开发 上阿里云申请了个证书 使用文件验证方式 感觉所有步骤都正确 就是审核的时候一直报 fileauth txt内容配置错误 我甚至按操作说明的方法 建了个FTP服务 严格按要求上传了文件 结果还是不行 后来在证书 进度查
  • yolo deepsort_目标跟踪初探(DeepSORT)

    最近由于工作原因 首次接触到了目标跟踪任务 这几天读了一些该领域的优秀论文 真心感觉目标跟踪任务的难度和复杂度要比分类和目标检测高不少 具有更大的挑战性 如果你跟我一样是正在学习目标跟踪的新手 希望本文能让你对目标跟踪任务和DeepSORT
  • JavaWeb图书管理系统

    目录 1 设计任务与目的 2 设计思路 3 概要设计 3 1系统结构图设计 3 2开发工具与运行环境 4 详细设计 4 1系统用户用例图 4 2用户登录用例图 4 3业务流程图 4 4数据流程图 4 5数据字典 4 6数据库介绍 4 7 E
  • 九轴传感器之数据处理篇

    关于九轴传感器数据的处理
  • 创意灵感网站都有哪些?推荐这8个

    设计师最痛苦的事情不是 改变草稿 加班吧 但创造力已经耗尽 没有灵感 对于创意设计师来说 浏览创意网站是寻找灵感创意的关键途径 但当你寻找灵感和创造力时 你会发现一些著名的创意网站只是展示了热门图片 公众很容易厌倦 8个设计师必备的创意网站
  • python是高级语言、并不支持传统的面向过程编程_安全检查中...

  • Linux命令·find参数详解

    find一些常用参数的一些常用实例和一些具体用法和注意事项 1 使用name选项 文件名选项是find命令最常用的选项 要么单独使用该选项 要么和其他选项一起使用 可以使用某种文件名模式来匹配文件 记住要用引号将文件名模式引起来 不管当前路
  • C++小游戏:五子棋(含代码)

    怎样用c 做出五子棋呢 其实很简单 不需要很多算法和函数 下面展示代码 注释都在下面了 include
  • 《java与模式》笔记(二) 开闭原则

    4 1 什么是开闭原则 开闭原则指的是一个软件实体应对对扩展开发 对修改关闭 Software entities should be open for extension but closed for modification 这个原则是说
  • 二、删去字符串中的元音(Biweekly4)

    题目描述 给你一个字符串 S 请你删去其中的所有元音字母 a e i o u 并返回这个新字符串 示例 1 输入 leetcodeisacommunityforcoders 输出 ltcdscmmntyfrcdrs 示例 2 输入 aeio
  • 基于VLC的Unity视频播放器(一)

    思路来自 http blog csdn net yechen2320374 article details 52226294 using System using System Text using System Runtime Inter