using System.Collections; using System.Collections.Generic; using System.IO; using Thousandto.Launcher.ExternalLibs; using UnityEngine; using UnityEngine.Video; using AppManager = UnityEngine.Gonbest.MagicCube.AppManager; #if FUNCELL_LAUNCHER using MyRuntimePlatform = Thousandto.Launcher.Logic.MyRuntimePlatform; using LauncherManager = Thousandto.Launcher.Logic.LauncherManager; #endif public class VideoRootScript : MonoBehaviour { #region//组件 private Camera _camera = null; private Transform _mask = null; private VideoPlayer _videoPlayer = null; private AudioSource _audioSource = null; #endregion #region//私有变量 private bool _isInit = false; private string _url = "http//xxxxxxxxxxxxxx"; private string _fileName = string.Empty; private string _ext = "mp4"; private OnPreparedCall _preparedCallBack = null; private OnFinishCall _finishCallBack = null; private List _fileNames = new List(); //texture缓存 private Dictionary _texCache = new Dictionary(); #endregion #region//const private const int TEXTURE_COUNT = 4; private const string TEX_MASK_0 = "tex_logininback_3"; private const string TEX_MASK_1 = "tex_logininback"; private const string TEX_MASK_2 = "tex_logininback_1"; private const string TEX_MASK_3 = "tex_logininback_2"; #endregion #region//delegate //视频准备完成回调 public delegate void OnPreparedCall(); //视频播放完毕回调 public delegate void OnFinishCall(); #endregion #region//私有函数 private void Initialize() { if (!_isInit) { if (_camera == null) _camera = transform.Find("Camera_Video").GetComponent(); _mask = transform.Find("Camera_Video/Mask"); _videoPlayer = RequireComponent(_camera.gameObject); _audioSource = RequireComponent(_camera.gameObject); _videoPlayer.playOnAwake = false; _videoPlayer.errorReceived += PlayErrorRecived; _videoPlayer.aspectRatio = VideoAspectRatio.Stretch; _audioSource.playOnAwake = false; _mask.gameObject.SetActive(false); Renderer rd = _mask.GetComponent(); if (rd != null) { rd.sharedMaterial = null; } _videoPlayer.source = VideoSource.Url; _isInit = true; } } private void UnInitialize() { _videoPlayer.errorReceived -= PlayErrorRecived; _videoPlayer = null; Destroy(_camera.GetComponent()); _isInit = false; } //判断文件是否在apk中 private bool IsFileInApk(string relationPath) { return AppManager.Instance.AssetInApp(relationPath); } private T RequireComponent(GameObject go) where T : Component { if (go == null) return default(T); T t = go.GetComponent(); if (t == null) { t = go.AddComponent(); } return t; } #endregion #region //静态函数 //准备视频 public static void PreVideo(string name, OnPreparedCall preparedCallBack = null, OnFinishCall finishCall = null, bool isShowMask = false, bool isLoop = false, VideoPlayExt extType = VideoPlayExt.Mp4) { var videoRoot = GameObject.Find("[VideoRoot]"); VideoRootScript videoScript = null; if (!videoRoot) { var asset = Resources.Load("Default/System/VideoRoot"); videoRoot = GameObject.Instantiate(asset) as GameObject; videoRoot.name = "[VideoRoot]"; if (videoRoot != null) { GameObject.DontDestroyOnLoad(videoRoot); } } videoScript = videoRoot.GetComponent(); if (videoScript == null) { videoRoot.AddComponent(); } videoScript.PrepareVideo("video_login", preparedCallBack, finishCall, isShowMask, isLoop, extType); } public static void PlayVideo(string name, OnPreparedCall preparedCallBack = null, OnFinishCall finishCall = null, bool isShowMask = false, bool isLoop = false, VideoPlayExt extType = VideoPlayExt.Mp4) { var videoRoot = GameObject.Find("[VideoRoot]"); VideoRootScript videoScript = null; if (!videoRoot) { var asset = Resources.Load("Default/System/VideoRoot"); videoRoot = GameObject.Instantiate(asset) as GameObject; videoRoot.name = "[VideoRoot]"; if (videoRoot != null) { GameObject.DontDestroyOnLoad(videoRoot); } } videoScript = videoRoot.GetComponent(); if (videoScript == null) { videoRoot.AddComponent(); } videoScript.Play("video_login", preparedCallBack, finishCall, isShowMask, isLoop, extType); } #endregion #region//公共函数 /// /// 准备视频 /// /// /// /// /// /// /// public void PrepareVideo(string name, OnPreparedCall preparedCallBack = null, OnFinishCall finishCall = null, bool isShowMask = false, bool isLoop = false, VideoPlayExt extType = VideoPlayExt.Mp4) { if (string.IsNullOrEmpty(name)) return; _fileName = name; _preparedCallBack = preparedCallBack; _finishCallBack = finishCall; Initialize(); if (isShowMask) { ShowMaskTexture(); } else { _mask.gameObject.SetActive(false); } _videoPlayer.isLooping = isLoop; SetExtName(extType); Prepare(name); } /// /// /// /// 视频名字 /// 播放类型 /// 视频格式 /// 视频准备成功回调 /// 视频播放完毕成功回调 /// 是否显示背景遮罩 public void Play(string name, OnPreparedCall preparedCallBack = null, OnFinishCall finishCall = null, bool isShowMask = false, bool isLoop = false, VideoPlayExt extType = VideoPlayExt.Mp4) { if (string.IsNullOrEmpty(name)) return; _fileName = name; _preparedCallBack = preparedCallBack; _finishCallBack = finishCall; Initialize(); if (isShowMask) { ShowMaskTexture(); } else { _mask.gameObject.SetActive(false); } _mask.gameObject.SetActive(false); _videoPlayer.isLooping = isLoop; SetExtName(extType); PlayLocal(name); } public void StopVideo() { if (_videoPlayer != null) { _videoPlayer.Stop(); //隐藏视频播放节点 _preparedCallBack = null; _finishCallBack = null; UnInitialize(); gameObject.SetActive(false); } } public bool IsPlaying() { if (_videoPlayer != null) { return _videoPlayer.isPlaying; } return false; } //点击跳过 public void Skip() { //停止视频播放 if (_videoPlayer != null) { _videoPlayer.Stop(); } //隐藏视频播放节点 _preparedCallBack = null; _finishCallBack = null; gameObject.SetActive(false); } #endregion #region//私有函数 //播放在线视频 private void PlayOline(string name) { string url = FixOnlineUrl(name); if (string.IsNullOrEmpty(url)) { return; } StartCoroutine(playVideo(url)); } //播放本地视频 private void PlayLocal(string name) { string path = IsExitVideoFile(name); if (string.IsNullOrEmpty(path)) { //本地视频不存在 播放online视频 PlayOline(name); } else { string url = FixLocalUrl(path); if (!gameObject.activeSelf) gameObject.SetActive(true); StartCoroutine(playVideo(url)); } } private void Prepare(string name) { string url = string.Empty; string path = IsExitVideoFile(name); if (string.IsNullOrEmpty(path)) { //本地视频不存在 url = FixOnlineUrl(name); if (string.IsNullOrEmpty(url)) { return; } } else { url = FixLocalUrl(path); if (!gameObject.activeSelf) gameObject.SetActive(true); } StartCoroutine(PrepareVideo(url)); } //判断视频文件是否存在 private string IsExitVideoFile(string name) { string ret = string.Empty; string streamingPath = string.Empty; #if FUNCELL_LAUNCHER //获取当前平台 MyRuntimePlatform runtimePlatform = LauncherManager.Instance.Data.RuntimePlatform; switch (runtimePlatform) { case MyRuntimePlatform.Standalone: case MyRuntimePlatform.AndroidEditor: case MyRuntimePlatform.IOSEditor: case MyRuntimePlatform.StandaloneEditor: streamingPath = Application.streamingAssetsPath; ret = string.Format("{0}/Assets/GameAssets/Resources/Video/{1}{2}", streamingPath, name, _ext); if (!System.IO.File.Exists(ret)) { ret = string.Empty; } return ret; case MyRuntimePlatform.IOS: case MyRuntimePlatform.Android: streamingPath = string.Format("{0}/StreamingAssets", Application.persistentDataPath); ret = string.Format("{0}/Assets/GameAssets/Resources/Video/{1}{2}", streamingPath, name, _ext); if (!System.IO.File.Exists(ret)) { ret = string.Empty; } if (string.IsNullOrEmpty(ret)) { //从apk中查找是否存在该文件 string relationPath = string.Format("Assets/GameAssets/Resources/Video/{0}{1}", name, _ext); if (IsFileInApk(relationPath)) { streamingPath = Application.streamingAssetsPath; ret = string.Format("{0}/Assets/GameAssets/Resources/Video/{1}{2}", streamingPath, name, _ext); } } break; default: break; } #else streamingPath = Application.dataPath; ret = string.Format("{0}/GameAssets/Resources/Video/{1}{2}", streamingPath, name, _ext); if (!System.IO.File.Exists(ret)) { ret = string.Empty; } #endif return ret; } private string FixOnlineUrl(string name) { string ret = string.Format("{0}/{1}", _url, name); return ret; } private string FixLocalUrl(string path) { ////判断视频本地文件是否存在 return path.Replace(@"\", "/"); } private string FixTexturePath(string name) { //string lan =UnityEngine.Gonbest.MagicCube.FLanguage.Default; string ret = string.Format("GameAssets/Resources/Texture/UI/CH/{0}", name); return ret; } //private void OnGUI() //{ // GUIStyle style = new GUIStyle // { // border = new RectOffset(10, 10, 10, 10), // fontSize = 25, // fontStyle = FontStyle.BoldAndItalic, // }; // // normal:Rendering settings for when the component is displayed normally. // style.normal.textColor = new Color(200 / 255f, 180 / 255f, 150 / 255f); // 需要除以255,因为范围是0-1 // //GUI.Label(new Rect(100, 100, 200, 80), , style); //} private void SetExtName(VideoPlayExt extType) { switch (extType) { case VideoPlayExt.Mov: _ext = ".mov"; break; case VideoPlayExt.Mpg: _ext = ".mpg"; break; case VideoPlayExt.Mpeg: _ext = ".mpeg"; break; case VideoPlayExt.Mp4: _ext = ".mp4"; break; case VideoPlayExt.Avi: _ext = ".avi"; break; case VideoPlayExt.Asf: _ext = ".asf"; break; } } //播放错误回调 private void PlayErrorRecived(VideoPlayer vp, string msg) { if (!string.IsNullOrEmpty(msg)) { UnityEngine.Debug.LogError("播放错误播放错误播放错误播放错误播放错误播放错误播放错误"); if (_preparedCallBack != null) { _preparedCallBack(); _preparedCallBack = null; } if (_finishCallBack != null) { _finishCallBack(); _finishCallBack = null; } } } //准备视频 private IEnumerator PrepareVideo(string url) { _videoPlayer.url = url; _videoPlayer.renderMode = VideoRenderMode.CameraFarPlane; _videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource; _videoPlayer.controlledAudioTrackCount = 1; _videoPlayer.SetTargetAudioSource(0, _audioSource); //这里一定要让以上工作完成后才能开始准备videoPlayer _videoPlayer.Prepare(); while (!_videoPlayer.isPrepared) { //Debug.Log("Preparing Video"); yield return null; } if (_preparedCallBack != null) { _preparedCallBack(); _preparedCallBack = null; gameObject.SetActive(false); } } private IEnumerator playVideo(string url) { if (string.Equals(_videoPlayer.url, url)) { //判断视频是否准备好了 if (_videoPlayer.isPrepared) { _videoPlayer.Play(); _audioSource.enabled = true; //视频播放成功了隐藏mask //_mask.gameObject.SetActive(false); yield return null; //等待一帧开始播放声音 //_audioSource.enabled = true; _audioSource.Play(); _mask.gameObject.SetActive(false); } } else { //走正常播放流程 _videoPlayer.url = url; _videoPlayer.renderMode = VideoRenderMode.CameraFarPlane; _videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource; //_videoPlayer.EnableAudioTrack(0, true); _videoPlayer.controlledAudioTrackCount = 1; _videoPlayer.SetTargetAudioSource(0, _audioSource); //这里一定要让以上工作完成后才能开始准备videoPlayer _videoPlayer.Prepare(); while (!_videoPlayer.isPrepared) { //Debug.Log("Preparing Video"); yield return null; } _videoPlayer.Play(); //_audioSource.enabled = false; //视频播放成功了隐藏mask //_mask.gameObject.SetActive(false); //yield return null; //等待一帧开始播放声音 _audioSource.enabled = true; _audioSource.Play(); if (_preparedCallBack != null) { _preparedCallBack(); _preparedCallBack = null; } _mask.gameObject.SetActive(false); } } //显示背景mask遮挡texture private void ShowMaskTexture() { string name = string.Empty; int random = Random.Range(0, TEXTURE_COUNT); switch (random) { case 0: name = TEX_MASK_0; break; case 1: name = TEX_MASK_1; break; case 2: name = TEX_MASK_2; break; case 3: name = TEX_MASK_3; break; } Texture tex = GetTextureFromCache(name); if (tex != null) { Renderer rd = _mask.GetComponent(); if (rd != null) { if (rd.sharedMaterial == null) { Shader sh = PrefabAssetRuntimeUtil.FindShader("Unlit/Transparent Colored"); rd.sharedMaterial = new Material(sh); } rd.sharedMaterial.mainTexture = tex; } _mask.gameObject.SetActive(true); } } //从缓存中获取背景texture private Texture GetTextureFromCache(string name) { Texture tex = null; if (_texCache.ContainsKey(name)) { tex = _texCache[name]; } else { //加载texture tex = LoadTexture(name); _texCache.Add(name, tex); } return tex; } //加载mask 图片 private Texture LoadTexture(string name) { Texture tex = null; //获取当前平台 string path = FixTexturePath(name); string streamingPath = string.Empty; string filePath = string.Empty; #if FUNCELL_LAUNCHER MyRuntimePlatform runtimePlatform = LauncherManager.Instance.Data.RuntimePlatform; switch (runtimePlatform) { case MyRuntimePlatform.Standalone: case MyRuntimePlatform.AndroidEditor: case MyRuntimePlatform.IOSEditor: case MyRuntimePlatform.StandaloneEditor: filePath = string.Format("{0}/{1}.jpg", Application.dataPath, path); //创建文件流 FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); fileStream.Seek(0, SeekOrigin.Begin); //创建文件长度的缓冲区 byte[] bytes = new byte[fileStream.Length]; //读取文件 fileStream.Read(bytes, 0, (int)fileStream.Length); //释放文件读取liu fileStream.Close(); fileStream.Dispose(); fileStream = null; //创建Texture int width = 1136; int height = 640; Texture2D texture2D = new Texture2D(width, height); texture2D.LoadImage(bytes); //texture2D.Resize(1136, 640); tex = texture2D; break; case MyRuntimePlatform.IOS: case MyRuntimePlatform.Android: //判断图片是否在转移目录里面 streamingPath = string.Format("{0}/StreamingAssets", Application.persistentDataPath); filePath = string.Format("{0}/Assets/{1}.unity3d", streamingPath, path); if (!File.Exists(filePath)) { //如果不在转移目录里面 那么从apk中读取 string relationPath = path; if (IsFileInApk(relationPath)) { streamingPath = Application.streamingAssetsPath; filePath = string.Format("{0}/Assets/{1}", streamingPath, path); } else { filePath = string.Empty; } } if (!string.IsNullOrEmpty(filePath)) { AssetBundle ab = AssetBundle.LoadFromFile(filePath); tex = (Texture)ab.LoadAsset(name); } break; default: break; } #else filePath = string.Format("{0}/{1}.jpg", Application.dataPath, path); //创建文件流 FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); fileStream.Seek(0, SeekOrigin.Begin); //创建文件长度的缓冲区 byte[] bytes = new byte[fileStream.Length]; //读取文件 fileStream.Read(bytes, 0, (int)fileStream.Length); //释放文件读取liu fileStream.Close(); fileStream.Dispose(); fileStream = null; //创建Texture int width = 1136; int height = 640; Texture2D texture2D = new Texture2D(width, height); texture2D.LoadImage(bytes); //texture2D.Resize(1136, 640); tex = texture2D; #endif return tex; } private void Update() { if (_videoPlayer != null && _videoPlayer.isPrepared) { if ((ulong)_videoPlayer.frame >= _videoPlayer.frameCount) { if (!_videoPlayer.isLooping) { //当前播放的视频已经播放完毕了 //隐藏视频播放节点 if (_finishCallBack != null) { _finishCallBack(); _finishCallBack = null; gameObject.SetActive(false); } } } } } //设置相机depth public void SetCamraDepth(float d) { if (_camera != null) { _camera.depth = d; } } #endregion }