分类 Unity 下的文章

思路来自 http://blog.csdn.net/yechen2320374/article/details/52226294
系统是64位的,因为我用的VLC的类库是64位的,用64位的Unity导出exe时选择x86_64,导出后需要将工程中Plugins下的plugins文件夹拷贝到发布后的Plugins文件夹下
工程地址https://gitee.com/awnuxcvbn/UnityVLC.git

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,
            "rtmp://live.hkstv.hk.lxdns.com/live/hks");
        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)点击这里下载工程 http://pan.baidu.com/s/1geWfZEz

100444w9i9e959uvvn09xi.jpg

Android代码

package cn.net.xuefei.unityrec; 
import java.io.File;
import java.io.IOException;
import com.unity3d.player.UnityPlayerActivity;
import android.Manifest;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.DisplayMetrics;
import android.widget.Toast;
 
public class MainActivity extends UnityPlayerActivity {
        private static final int RECORD_REQUEST_CODE = 101;
        private static final int STORAGE_REQUEST_CODE = 102;
        private static final int AUDIO_REQUEST_CODE = 103;
        private static final int SHOW = 1;
        private static final int CANCEL = 2;
        private boolean isRecording;
        public static Context currentActivity;
        private MediaProjectionManager mediaProjectionManager;
        private Handler mHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        switch (msg.what) {
                        case SHOW:
                                if (isRecording) {
                                        Toast.makeText(MainActivity.this, "录制已开始", Toast.LENGTH_SHORT).show();
                                } else {
                                        startScreenCapture();
                                        isRecording = true;
                                }
                                break;
                        case CANCEL:
                                if (isRecording) {
                                        mediaRecorder.stop();
                                        mediaRecorder.reset();
                                        mediaProjection.stop();
                                        virtualDisplay.release();
                                        isRecording = false;
                                        insertVideoToMediaStore(getSaveDirectory() + videoName);
                                        Toast.makeText(MainActivity.this, "录制结束", Toast.LENGTH_SHORT).show();
                                } else {
                                        Toast.makeText(MainActivity.this, "没有开始录制", Toast.LENGTH_SHORT).show();
                                }
                                break;
                        }
                }
        };
        private MediaProjection mediaProjection;
        private MediaRecorder mediaRecorder;
        private VirtualDisplay virtualDisplay;
        /**
         * 屏幕的宽度
         */
        private int screenWidth;
        /**
         * 屏幕的高度
         */
        private int screenHeight;
        /**
         * 屏幕的像素
         */
        private int screenDpi;
        private DisplayMetrics metrics;
        /**
         * 保存在相册视频的名字
         */
        private String videoName;
 
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                mediaRecorder = new MediaRecorder();
                metrics = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(metrics);
                /**
                 * 动态注册权限
                 */
                if (ContextCompat.checkSelfPermission(MainActivity.this,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                        ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
                                        STORAGE_REQUEST_CODE);
                }
                if (ContextCompat.checkSelfPermission(MainActivity.this,
                                Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
                        ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.RECORD_AUDIO },
                                        AUDIO_REQUEST_CODE);
                }
                currentActivity = this;
                //mUnityPlayer.requestFocus();
        }
 
        /**
         * unity调用的方法,需要用一个handler进行处理实现功能,直接无法实现。
         */
        public void stopRecordin() {
                mHandler.sendEmptyMessage(CANCEL);
        }
 
        /**
         * unity调用的方法,需要用一个handler进行处理实现功能,直接无法实现。
         */
        public void startRecording() {
                mHandler.sendEmptyMessage(SHOW);
 
        }
 
        private void startScreenCapture() {
                mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
                Intent captureIntent = mediaProjectionManager.createScreenCaptureIntent();
                startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
        }
 
        public void setConfig(int screenWidth, int screenHeight, int screenDpi) {
                this.screenWidth = screenWidth;
                this.screenHeight = screenHeight;
                this.screenDpi = screenDpi;
        }
 
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
                        mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
                        setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
                        startRecord();
                        Toast.makeText(this, "开始录制", Toast.LENGTH_SHORT).show();
                }
        }
 
        public boolean startRecord() {
                initRecorder();
                createVirtualDisplay();
                mediaRecorder.start();
                return true;
        }
 
        private void createVirtualDisplay() {
                virtualDisplay = mediaProjection.createVirtualDisplay("MainScreen", screenWidth, screenHeight, screenDpi,
                                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);
        }
 
        private void initRecorder() {
                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
                mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                videoName = System.currentTimeMillis() + ".mp4";
                mediaRecorder.setOutputFile(getSaveDirectory() + videoName);
                mediaRecorder.setVideoSize(screenWidth, screenHeight);
                mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
                mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
                mediaRecorder.setVideoFrameRate(30);
                try {
                        mediaRecorder.prepare();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
 
        public String getSaveDirectory() {
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                        String screenRecordPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator
                                        + "DCIM" + File.separator + "Camera" + File.separator;
                        return screenRecordPath;
                } else {
                        return null;
                }
        }
 
        public void insertVideoToMediaStore(String filePath) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.MediaColumns.DATA, filePath);
                // video/*
                values.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
                getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
        }
 
        /**
         * 打开相册,
         *
         * @return
         */
        public void openAlbum() {
                Intent intent = new Intent(Intent.ACTION_PICK);
                startActivity(intent);
        }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.net.xuefei.unityrec"
    android:versionCode="1"
    android:versionName="1.0" >
 
  <uses-sdk
      android:minSdkVersion="22"
      android:targetSdkVersion="22" />
  
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <!--往sdcard中写入数据的权限 -->
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
  <!--在sdcard中创建/删除文件的权限 -->
  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
 
  <application
       >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
 
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>
 
</manifest>

Unity代码

using UnityEngine;
using System.Collections;
 
public class UnityRec : MonoBehaviour
{ 
    // Use this for initialization
    void Start()
    {
 
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
 
    void OnGUI()
    {
        if (GUI.Button(new Rect(0, 0, 300, 300), "开始录屏"))
        {
#if UNITY_ANDROID
            AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
            jo.Call("startRecording");
#elif UNITY_IPHONE
           
#endif
        }
 
        if (GUI.Button(new Rect(0, 300, 300, 300), "停止录屏"))
        {
# if UNITY_ANDROID
            AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
            jo.Call("stopRecordin");
#elif UNITY_IPHONE
 
#endif
        }
    }
}

1.jpg
2.jpg
3.jpg

using UnityEngine;
using System.Collections;
using OpenCvSharp;
 
public class VideoTest : MonoBehaviour
{
    public WebCamTexture cameraTexture;
    Texture2D rt;
    public string cameraName = "";
    private bool isPlay = false;
    static int mPreviewWidth = 320;
    static int mPreviewHeight = 240;
    bool state = false;
    CascadeClassifier haarCascade;
    WebCamDevice[] devices;
    // Use this for initialization
    void Start()
    {
        rt = new Texture2D(mPreviewWidth, mPreviewHeight, TextureFormat.RGB565, false);
        temp = new Texture2D(mPreviewWidth, mPreviewHeight, TextureFormat.RGB565, false);
        StartCoroutine(Test());
        haarCascade = new CascadeClassifier(Application.streamingAssetsPath + "/haarcascades/haarcascade_frontalface_alt2.xml");
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
 
    IEnumerator Test()
    {
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            devices = WebCamTexture.devices;
            cameraName = devices[0].name;
            cameraTexture = new WebCamTexture(cameraName, mPreviewWidth, mPreviewHeight, 15);
            cameraTexture.Play();
            isPlay = true;
        }
    }
    Mat haarResult;
    byte[] bs;
    void OnGUI()
    {
        if (isPlay)
        {
            GUI.DrawTexture(new UnityEngine.Rect(0, 0, mPreviewWidth, mPreviewHeight), cameraTexture, ScaleMode.ScaleToFit);
 
            if (GUI.Button(new UnityEngine.Rect(0, 240, 80, 80), "START"))
            {
                if (state)
                {
                    state = false;
                    return;
                }
                else
                {
                    state = true;
                }
            }
 
            if (state)
            {
                // Detect faces
                haarResult = DetectFace(haarCascade, GetTexture2D(cameraTexture));
                bs = haarResult.ToBytes(".png");
                rt.LoadImage(bs);
                rt.Apply();
                GUI.DrawTexture(new UnityEngine.Rect(mPreviewWidth, 0, mPreviewWidth, mPreviewHeight), rt, ScaleMode.StretchToFill);
            }
 
        }
 
    }
 
    Mat result;
    OpenCvSharp.Rect[] faces;
    Mat src;
    Mat gray = new Mat();
    Size axes = new Size();
    Point center = new Point();
    /// <summary>
    /// 
    /// </summary>
    /// <param name="cascade"></param>
    /// <returns></returns>
    private Mat DetectFace(CascadeClassifier cascade, Texture2D t)
    {
        src = Mat.FromImageData(t.EncodeToPNG(), ImreadModes.Color);
        result = src.Clone();
        Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
        src = null;
        // Detect faces
        faces = cascade.DetectMultiScale(gray, 1.08, 2, HaarDetectionType.ScaleImage, new Size(30, 30));
 
        // Render all detected faces
        for (int i = 0; i < faces.Length; i++)
        {
            center.X = (int)(faces[i].X + faces[i].Width * 0.5);
            center.Y = (int)(faces[i].Y + faces[i].Height * 0.5);
            axes.Width = (int)(faces[i].Width * 0.5);
            axes.Height = (int)(faces[i].Height * 0.5);
            Cv2.Ellipse(result, center, axes, 0, 0, 360, new Scalar(255, 0, 255), 4);
        }
        return result;
    }
    Texture2D temp;
    Texture2D GetTexture2D(WebCamTexture wct)
    {
        temp.SetPixels(wct.GetPixels());
        temp.Apply();
        return temp;
    }
}

OpenCvSharp github地址 https://github.com/shimat/opencvsharp

工程下载(.3.5f1&win10x64)http://pan.baidu.com/s/1pLy6W4N

OpenCV相关插件下载 https://pan.baidu.com/s/1c2agKHM

000033xpfpfgp4asaaf6ba.jpg

package com.xuefei.game;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import com.unity3d.player.UnityPlayerNativeActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
 
public class MainActivity extends UnityPlayerNativeActivity {
    public static Context context;
    public static MainActivity mainActivity;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        mainActivity = this;
    }
 
    // 保存到相册
    public static void savePng(final String fileName) {
 
        context = mainActivity.getApplicationContext();
 
        mainActivity.runOnUiThread(new Runnable() {
            public void run() {
 
                Bitmap bitmap = BitmapFactory.decodeFile(Environment
                        .getExternalStorageDirectory()
                        + "/Android/data/com.xuefei.game/files/"
                        + fileName
                        + ".png");
 
                File file = new File(Environment.getExternalStorageDirectory()
                        + "/DCIM/Camera", fileName + ".jpg");
 
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(file);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    Log.w("cat", e.toString());
                }
                bitmap.compress(CompressFormat.JPEG, 100, fos);
 
                try {
                    fos.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    Log.w("cat", e.toString());
                }
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    Log.w("cat", e.toString());
                }
                bitmap.recycle();//扫描保存的图片
                context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" +Environment.getExternalStorageDirectory()
                        + "/DCIM/Camera/"+fileName + ".jpg")));
                 
                Toast.makeText(context, "照片已保存到相册", Toast.LENGTH_SHORT).show();
  
            }
        });
    }
}

Unity中代码:

        if (GUI.Button(new Rect(0, 720, 400, 120), "SavePng"))
        {
            StartCoroutine(SavePngToSD(DateTime.Now.ToFileTime().ToString()));
        }
 
    /// <summary>
    /// 截图后先检测图片是否保存成功然后调用保存到相册
    /// </summary>
    /// <param name="name"></param>
    public void SavePng(string name)
    {
#if UNITY_ANDROID
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.CallStatic("SavePng", name);
#elif  UNITY_IPHONE
 
#endif
    }
 
/// <summary>
    /// 保存截图到相册
    /// </summary>
    /// <param name="pngName"></param>
    /// <returns></returns>
    IEnumerator SavePngToSD(string pngName)
    {
        yield return new WaitForEndOfFrame();
        Application.CaptureScreenshot(pngName + ".png");
        while (!IsFileExistByPath(Application.persistentDataPath + "/" + pngName + ".png"))
        {
            yield return new WaitForSeconds(0.05f);
        }
        SavePng(pngName);
        yield return new WaitForSeconds(0.3f);
        //测试请求文件
        WWW www = new WWW("file:///" + Application.persistentDataPath + "/" + pngName + ".png");
 
        yield return www;
    }
 
    /// <summary>
    /// 检测文件是否存在
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static bool IsFileExistByPath(string path)
    {
        FileInfo info = new FileInfo(path);
        bool b = false;
        if (info == null || info.Exists == false)
        {
            b = false;
        }
        else
        {
            b = true;
        }
        return b;
    }

注意文件路径是否存在,不存在就创建

流程:Unity截屏--调用安卓拷贝到相册--扫描保存的文件

解决的问题:截屏图片在相册不显示。

1.png
2.png

using UnityEngine;
using System.Collections;
using Id3Lib;
using NAudio.Wave;
using System.IO;
using System;
using System.Text;
using System.Runtime.InteropServices;
public class MusicPlayer : MonoBehaviour
{ 
 
    private IWavePlayer iwavePlayer;
    private WaveStream waveStream;
    private WaveChannel32 waveChannel32;
    Texture2D t;
    string path=""; 
    // Use this for initialization
    void Start()
    {
        
    }
 
    void LoadMusic(string path)
    { 
        byte[] imageData;
        using (FileStream fsRead = new FileStream(path, FileMode.Open))
        {
            int fsLen = (int)fsRead.Length;
            imageData = new byte[fsLen];
            fsRead.Read(imageData, 0, imageData.Length);
        }
        LoadAudioFromData(imageData);
        t = GetAlbumCover(path);
    }
 
    private bool LoadAudioFromData(byte[] data)
    {
        try
        {
            MemoryStream tmpStr = new MemoryStream(data);
            waveStream = new Mp3FileReader(tmpStr); 
            waveChannel32 = new WaveChannel32(waveStream);
 
            iwavePlayer = new WaveOut();
            iwavePlayer.Init(waveChannel32);
            return true;
        }
        catch (System.Exception ex)
        {
            Debug.LogWarning("Error! " + ex.Message);
        }
        return false;
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
 
 
    void OnGUI()
    {
        if (GUI.Button(new Rect(0, 0, 120, 30), "选择音乐"))
        {
            OpenFileName ofn = new OpenFileName();
 
            ofn.structSize = Marshal.SizeOf(ofn);
              
            ofn.filter = "mp3(*.mp3)\0*.mp3";
 
            ofn.file = new string(new char[256]);
 
            ofn.maxFile = ofn.file.Length;
 
            ofn.fileTitle = new string(new char[64]);
 
            ofn.maxFileTitle = ofn.fileTitle.Length;
 
            ofn.initialDir = UnityEngine.Application.dataPath;//默认路径  
 
            ofn.title = "选择音乐";
 
            ofn.defExt = "mp3";//显示文件的类型  
            //注意 一下项目不一定要全选 但是0x00000008项不要缺少  
            ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;//OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR  
 
            if (WindowDll.GetOpenFileName(ofn))
            {
                Debug.Log("Selected file with full path: {0}" + ofn.file);
                LoadMusic(ofn.file);
                path = ofn.file;
            }
            ofn = null;
            Resources.UnloadUnusedAssets();
        }
        if(GUI.Button(new Rect(0,30,120,30),"播放"))
        {
            iwavePlayer.Play();
        }
        if (GUI.Button(new Rect(0, 60, 120, 30), "暂停"))
        {
            iwavePlayer.Pause();
        }
        if (GUI.Button(new Rect(0, 90, 120, 30), "停止"))
        {
            iwavePlayer.Stop(); 
        }
        GUI.Label(new Rect(200, 170, 500, 30), path);
        if(t!=null)
        {
            GUI.DrawTexture(new Rect(200, 200, 200, 200), t);
        }
    }
 
    void OnApplicationQuit()
    {
        if (iwavePlayer!=null)
        {
            iwavePlayer.Dispose();
        }
    }
    /// <summary>
    /// 获取音乐封面
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public Texture2D GetAlbumCover(string path)
    {
        Texture2D image = null;
        FileStream fs = new FileStream(path, FileMode.Open);
        try
        {
            byte[] header = new byte[10]; //标签头
            int offset = 0;
            bool haveAPIC = false;
            fs.Read(header, 0, 10);
            offset += 10;
            string head = Encoding.Default.GetString(header, 0, 3);
 
            if (head.Equals("ID3"))
            {
                int sizeAll = header[6] * 0x200000 //获取该标签的尺寸,不包括标签头
                + header[7] * 0x4000
                + header[8] * 0x80
                + header[9];
                int size = 0;
                byte[] body = new byte[10]; //数据帧头,这里认为数据帧头不包括编码方式
                fs.Read(body, 0, 10);
                offset += 10;
                head = Encoding.Default.GetString(body, 0, 4);
                while (offset < sizeAll) //当数据帧不是图片的时候继续查找
                {
                    if (("APIC".Equals(head))) { haveAPIC = true; break; }
                    size = body[size + 4] * 0x1000000 //获取该数据帧的尺寸(不包括帧头)
                    + body[size + 5] * 0x10000
                    + body[size + 6] * 0x100
                    + body[size + 7];
                    body = new byte[size + 10];
                    fs.Read(body, 0, size + 10);
                    offset += size + 10;
                    head = Encoding.Default.GetString(body, size, 4);
                }
                if (haveAPIC)
                {
                    size = body[size + 4] * 0x1000000
                    + body[size + 5] * 0x10000
                    + body[size + 6] * 0x100
                    + body[size + 7];
                    byte[] temp = new byte[9];
                    byte[] temptype = new byte[10];
                    fs.Seek(1, SeekOrigin.Current);
                    fs.Read(temp, 0, 9);
                    int i = 0;
                    switch (Encoding.Default.GetString(temp))
                    {
                        case "image/jpe":
 
                            while (i < size) //jpeg开头0xFFD8
                            {
                                if (temptype[0] == 0 && temptype[1] == 255 && temptype[2] == 216)
                                {
                                    break;
                                }
                                fs.Seek(-2, SeekOrigin.Current);
                                fs.Read(temptype, 0, 3);
                                i++;
                            }
                            fs.Seek(-2, SeekOrigin.Current);
                            break;
                        case "image/jpg":
 
                            while (i < size) //jpg开头0xFFD8
                            {
                                if (temptype[0] == 0 && temptype[1] == 255 && temptype[2] == 216)
                                {
                                    break;
                                }
                                fs.Seek(-2, SeekOrigin.Current);
                                fs.Read(temptype, 0, 3);
                                i++;
                            }
                            fs.Seek(-2, SeekOrigin.Current);
                            break;
                        case "image/gif":
 
                            while (i < size) //gif开头474946
                            {
                                if (temptype[0] == 71 && temptype[1] == 73 && temptype[2] == 70)
                                {
                                    break;
                                }
                                fs.Seek(-2, SeekOrigin.Current);
                                fs.Read(temptype, 0, 3);
                                i++;
                            }
                            fs.Seek(-3, SeekOrigin.Current);
                            break;
                        case "image/bmp":
 
                            while (i < size) //bmp开头424d
                            {
                                if (temptype[0] == 66 && temptype[1] == 77)
                                {
                                    break;
                                }
                                fs.Seek(-1, SeekOrigin.Current);
                                fs.Read(temptype, 0, 2);
                                i++;
                            }
                            fs.Seek(-2, SeekOrigin.Current);
                            break;
                        case "image/png":
                            while (i < size) //png开头89 50 4e 47 0d 0a 1a 0a
                            {
                                if (temptype[0] == 137 && temptype[1] == 80 && temptype[2] == 78 && temptype[3] == 71 && temptype[4] == 13)
                                {
                                    break;
                                }
                                fs.Seek(-9, SeekOrigin.Current);
                                fs.Read(temptype, 0, 10);
                                i++;
                            }
                            fs.Seek(-10, SeekOrigin.Current);
                            break;
                        default://FFFB为音频的开头
                            break;
                    }
 
                    byte[] imageBytes = new byte[size];
                    fs.Read(imageBytes, 0, size);
                    image = new Texture2D(128, 128);
                    image.LoadImage(imageBytes);
                }
                else
                {
                    image = null;
                }
            }
            else
            {
                image = null;
            }
        }
        catch (Exception ex)
        {
            Debug.LogWarning(ex.Message);
        }
        finally
        {
            fs.Close();
        }
        return image;
    }
}

20160218152426016.png

点击这里下载项目文件