链接:https://pan.baidu.com/s/1_dB2KxfSRtxJqeK1da-xqg
提取码:pwvj
先是NGUI
插件地址
把插件导入Unity Hierarchy框口右键
using UnityEngine;
using System.Collections;
using RenderHeads.Media.AVProVideo;
using System;
using System.IO;
public class AVProControl : MonoBehaviour
{
MediaPlayer mediaPlayer;
Transform UIRoot;
GameObject btnPlay;
GameObject btnStop;
GameObject btnRePlay;
UISlider movieSlider;
/// <summary>
/// 显示实际进度
/// </summary>
UILabel movieSliderTime;
UISlider sourceSlider;
UIToggle muteToggle;
/// <summary>
/// 当前视屏总长度毫秒
/// </summary>
float duration;
//单位是秒 00:00
float mediaPlayerValue;
// Use this for initialization
void Start()
{
mediaPlayer = GetComponent<MediaPlayer>();
UIRoot = GameObject.Find("UI Root").transform;
btnPlay = UIRoot.Find("btnPlay").gameObject;
btnStop = UIRoot.Find("btnStop").gameObject;
btnRePlay = UIRoot.Find("btnRePlay").gameObject;
UIEventListener.Get(btnPlay).onClick += BtnPlayOnClick;
UIEventListener.Get(btnStop).onClick += BtnStopOnClick;
UIEventListener.Get(btnRePlay).onClick += BtnRePlayOnClick;
movieSlider = UIRoot.Find("SliderMovie").GetComponent<UISlider>();
UIEventListener.Get(movieSlider.gameObject).onPress += MovieSliderOnPress;
movieSliderTime = movieSlider.transform.Find("time").GetComponent<UILabel>();
sourceSlider = UIRoot.Find("SliderSource").GetComponent<UISlider>();
UIEventListener.Get(sourceSlider.gameObject).onDrag += SourceSliderOnDrag;
muteToggle = UIRoot.Find("MuteToggle").GetComponent<UIToggle>();
UIEventListener.Get(muteToggle.gameObject).onClick += BtnMuteToggleOnClick;
SetVideo("http://cn-sdqd-cu-v-02.acgvideo.com/upgcxcode/96/78/87367896/87367896-1-6.mp4?expires=1555985400&platform=html5&ssig=QTgvz85Ge3N6MFcaT3hMAA&oi=2008310406&trid=6d64c2c6756d4cfd866341415d9e383c&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1");
//SetVideo("chuanjianyinwei.mp4");
}
/// <summary>
/// 设置音量大小
/// </summary>
private void SourceSliderOnDrag(GameObject go, Vector2 delta)
{
if (mediaPlayer.Control.IsPlaying())
{
mediaPlayer.Control.SetVolume(sourceSlider.value);
}
}
/// <summary>
/// 静音按钮设置
/// </summary>
/// <param name="go"></param>
private void BtnMuteToggleOnClick(GameObject go)
{
mediaPlayer.Control.MuteAudio(muteToggle.value);
// Debug.Log(muteToggle.value);
}
/// <summary>
/// 拖动进度条设置视屏长度
/// </summary>
/// <param name="go"></param>
/// <param name="state"></param>
private void MovieSliderOnPress(GameObject go, bool state)
{
if (state == true)
{
mediaPlayer.Stop();
//Debug.Log("PressEnter");
}
else
{
mediaPlayer.Control.Seek(movieSlider.value * mediaPlayer.Info.GetDurationMs());
mediaPlayer.Play();
//Debug.Log("PressExit");
}
}
/// <summary>
/// 加载视频
/// </summary>
/// <param name="path"></param>
public void SetVideo(string path)
{
//网上或者本地加载
if (path.Contains("http://"))
{
mediaPlayer.m_VideoLocation = MediaPlayer.FileLocation.AbsolutePathOrURL;
}
else
{
mediaPlayer.m_VideoLocation = MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder;
//mediaPlayer.OpenVideoFromFile(mediaPlayer.m_VideoLocation, path);
//duration = mediaPlayer.Info.GetDurationMs();
//durationSecond =TimeSpan.FromSeconds(duration * 0.001f).ToString().Substring(3,5);
}
StartCoroutine(LoadVideoWithFading(path));
}
private IEnumerator LoadVideoWithFading(string path)
{
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
// Load the video
if (Application.isPlaying)
{
if (!mediaPlayer.OpenVideoFromFile(mediaPlayer.m_VideoLocation, path))
{
Debug.LogError("Failed to open video!");
}
else
{
// Wait for the first frame to come through (could also use events for this)
while (Application.isPlaying && (VideoIsReady(mediaPlayer) || AudioIsReady(mediaPlayer)))
{
yield return null;
}
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
}
}
duration = mediaPlayer.Info.GetDurationMs();
}
/// <summary>
/// 视频是否准备好了
/// </summary>
/// <param name="mp"></param>
/// <returns></returns>
private bool VideoIsReady(MediaPlayer mp)
{
return (mp != null && mp.TextureProducer != null && mp.TextureProducer.GetTextureFrameCount() <= 0);
}
/// <summary>
/// 声音是否准备好了
/// </summary>
/// <param name="mp"></param>
/// <returns></returns>
private bool AudioIsReady(MediaPlayer mp)
{
return (mp != null && mp.Control != null && mp.Control.CanPlay() && mp.Info.HasAudio() && !mp.Info.HasVideo());
}
/// <summary>
/// 播放
/// </summary>
/// <param name="go"></param>
private void BtnPlayOnClick(GameObject go)
{
mediaPlayer.Play();
}
/// <summary>
/// 暂停
/// </summary>
/// <param name="go"></param>
private void BtnStopOnClick(GameObject go)
{
mediaPlayer.Stop();
}
/// <summary>
/// 重播
/// </summary>
/// <param name="go"></param>
private void BtnRePlayOnClick(GameObject go)
{
mediaPlayer.Rewind(false);
mediaPlayer.Play();
}
// Update is called once per frame
void Update()
{
SetSliderValue();
}
/// <summary>
/// 进度条与视频进度百分比同步
/// </summary>
void SetSliderValue()
{
if (mediaPlayer.Control.IsPlaying())
{
//当前在几毫秒
float time = mediaPlayer.Control.GetCurrentTimeMs();
//Debug.Log(time+"_"+duration);
//最少取0.1
//print(Helper.GetTimeString(time * 0.001f));
//TimeSpan ts = TimeSpan.FromSeconds(time * 0.001f);
//插件自带 把时间转化为00:00
movieSliderTime.text = Helper.GetTimeString(time * 0.001f) + "/" + Helper.GetTimeString(duration * 0.001f);
mediaPlayerValue = Mathf.Clamp(time / duration, 0.0f, 1.0f);
movieSlider.value = mediaPlayerValue;
}
}
}
NGUI按照这样创建就可以了
不过加载网上资源的缓存条不知道在哪里调用
然后UGUI 我把AVpro封装了一下 这个类不负责UI逻辑 所以NGUI UGUI GUI都可以用
using UnityEngine;
using System.Collections;
using RenderHeads.Media.AVProVideo;
using System;
using System.IO;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Text;
using System.Security.Cryptography;
public class AVProControl
{
MediaPlayer mediaPlayer;
/// <summary>
/// 当前视屏总长度毫秒
/// </summary>
float duration;
public AVProControl(MediaPlayer mediaPlayer)
{
this.mediaPlayer = mediaPlayer;
}
public void Play()
{
mediaPlayer.Play();
}
public void Stop()
{
if (isPlaying())
{
mediaPlayer.Stop();
}
}
public void RePlay()
{
mediaPlayer.Rewind(false);
mediaPlayer.Play();
}
/// <summary>
/// 设置速率
/// </summary>
public void SetSpeedRate(float val)
{
mediaPlayer.Control.SetPlaybackRate(val);
}
/// <summary>
/// 获取总时间00:00格式
/// </summary>
/// <returns></returns>
public string GetTotalProgressTime()
{
return Helper.GetTimeString(duration * 0.001f);
}
/// <summary>
/// 获取当前时间00:00格式
/// </summary>
/// <returns></returns>
public string GetNowProgressTime()
{
//当前在几毫秒
float time = mediaPlayer.Control.GetCurrentTimeMs();
//最少取0.1
TimeSpan ts = TimeSpan.FromSeconds(time * 0.001f);
//插件自带 把时间转化为00:00
return Helper.GetTimeString(time * 0.001f);
}
/// <summary>
/// 获取进度条0-1
/// </summary>
/// <returns></returns>
public float GetProgress()
{
//当前在几毫秒
float time = mediaPlayer.Control.GetCurrentTimeMs();
return Mathf.Clamp(time / duration, 0.0f, 1.0f);
}
/// <summary>
/// 设置进度条
/// </summary>
/// <param name="value">0-1</param>
public void SetProgress(float value)
{
mediaPlayer.Control.Seek(value * mediaPlayer.Info.GetDurationMs());
}
/// <summary>
/// 设置音量大小
/// </summary>
/// <param name="value">0-1</param>
public void SetVolume(float value)
{
if (isPlaying())
{
mediaPlayer.Control.SetVolume(value);
}
}
/// <summary>
/// 静音按钮设置
/// </summary>
/// <param name="go"></param>
public void SetMute(bool isMute)
{
if (isPlaying())
{
mediaPlayer.Control.MuteAudio(isMute);
}
}
/// <summary>
/// 加载加密视频
/// </summary>
/// <param name="path"></param>
public IEnumerator LoadEncryptVideoWithFading(string path)
{
string newPath = Application.dataPath + "/StreamingAssets/videoNew";
path = newPath + "/" + path;
byte[] enBytes = DecryptVideo(newPath, FileTools.ReadFile(path));
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
// Load the video
if (Application.isPlaying)
{
if (!mediaPlayer.OpenVideoFromBuffer(enBytes))
{
Debug.LogError("Failed to open video!");
}
else
{
// Wait for the first frame to come through (could also use events for this)
while (Application.isPlaying && (VideoIsReady(mediaPlayer) || AudioIsReady(mediaPlayer)))
{
yield return null;
}
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
}
}
duration = mediaPlayer.Info.GetDurationMs();
}
/// <summary>
/// 加载普通视频
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public IEnumerator LoadVideoWithFading(string path)
{
//网上或者本地加载
if (path.Contains("http://"))
{
mediaPlayer.m_VideoLocation = MediaPlayer.FileLocation.AbsolutePathOrURL;
}
else
{
mediaPlayer.m_VideoLocation = MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder;
}
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
// Load the video
if (Application.isPlaying)
{
if (!mediaPlayer.OpenVideoFromFile(mediaPlayer.m_VideoLocation, path))
{
Debug.LogError("Failed to open video!");
}
else
{
// Wait for the first frame to come through (could also use events for this)
while (Application.isPlaying && (VideoIsReady(mediaPlayer) || AudioIsReady(mediaPlayer)))
{
yield return null;
}
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
}
}
duration = mediaPlayer.Info.GetDurationMs();
}
/// <summary>
/// 视频是否准备好了
/// </summary>
/// <param name="mp"></param>
/// <returns></returns>
private bool VideoIsReady(MediaPlayer mp)
{
return (mp != null && mp.TextureProducer != null && mp.TextureProducer.GetTextureFrameCount() <= 0);
}
/// <summary>
/// 声音是否准备好了
/// </summary>
/// <param name="mp"></param>
/// <returns></returns>
private bool AudioIsReady(MediaPlayer mp)
{
return (mp != null && mp.Control != null && mp.Control.CanPlay() && mp.Info.HasAudio() && !mp.Info.HasVideo());
}
/// <summary>
/// 是否在播放
/// </summary>
/// <returns></returns>
public bool isPlaying()
{
return mediaPlayer.Control.IsPlaying();
}
/// <summary>
/// 解密
/// </summary>
/// <param name="KeyPath"></param>
/// <param name="data"></param>
/// <returns></returns>
public byte[] DecryptVideo(string KeyPath, byte[] data)
{
Rijndael rij = new Rijndael();
RijndaelKey rijKey = rij.GetKeyAndIV(KeyPath);
return rij.Decrypt(data, rijKey.key, rijKey.IV);
}
}
UGUI挂的是这个脚本
核心调用脚本
private void Update()
{
if (AVpro.isPlaying())
{
movieSlider.value = AVpro.GetProgress();
}
}
public void InitAvPro()
{
AVpro = new AVProControl(transform.Find("Video/AVPro Video").GetComponent<DisplayUGUI>()._mediaPlayer);
Button btnPlay = transform.Find("Video/play").GetComponent<Button>();
var spStart = btnPlay.GetComponent<Image>().sprite;
btnPlay.onClick.AddListener(() =>
{
if (AVpro.isPlaying())
{
btnPlay.GetComponent<Image>().sprite = btnPlay.spriteState.disabledSprite;
AVpro.Stop();
}
else
{
btnPlay.GetComponent<Image>().sprite = spStart;
AVpro.Play();
}
});
transform.Find("Video/replay").GetComponent<Button>().onClick.AddListener(() =>
{
AVpro.RePlay();
});
//设置拖动进度条
movieSlider = transform.Find("Video/Slider").GetComponent<Slider>();
EventTriggerListener.Get(movieSlider.gameObject).onDown += ((go) =>
{
AVpro.Stop();
});
EventTriggerListener.Get(movieSlider.gameObject).onUp += ((go) =>
{
AVpro.SetProgress(movieSlider.value);
AVpro.Play();
});
}
这个是加密解密类 详细的可以看
https://www.jianshu.com/p/02cfd3b979cb
using UnityEngine;
using System.Collections;
using System;
using System.Security.Cryptography;
using System.Text;
public struct RijndaelKey
{
public byte[] key;
public byte[] IV;
public RijndaelKey(byte[] key, byte[] iV)
{
this.key = key;
IV = iV;
}
}
public class Rijndael
{
/// <summary>
/// Rijndael加密
/// </summary>
/// <param name="plainData">密文</param>
/// <param name="key">密钥</param>
/// <param name="IV">向量</param>
/// <returns></returns>
public byte[] Encrypt(byte[] plainData, byte[] key, byte[] IV)
{
if (plainData == null || plainData.Length <= 0)
throw new ArgumentNullException("video");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
//创建RijndaelManaged对象
//使用指定的键和IV。
//用完就会被释放
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = key;
rijAlg.IV = IV;
//设置对称算法的运算模式
rijAlg.Mode = CipherMode.ECB;
//设置填充模式
rijAlg.Padding = PaddingMode.ISO10126;
//创建加密程序以执行流转换。
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
encrypted = encryptor.TransformFinalBlock(plainData, 0, plainData.Length);
}
//从内存流返回加密的字节。
return encrypted;
}
/// <summary>
/// 解密
/// </summary>
/// <param name="cipherData"></param>
/// <param name="key"></param>
/// <param name="IV"></param>
/// <returns></returns>
public byte[] Decrypt(byte[] cipherData, byte[] key, byte[] IV)
{
if (cipherData == null || cipherData.Length <= 0)
throw new ArgumentNullException("video");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] decrypted;
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.ECB;
rijAlg.Padding = PaddingMode.ISO10126;
//创建解密程序以执行流转换。
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
decrypted = decryptor.TransformFinalBlock(cipherData, 0, cipherData.Length);
}
return decrypted;
}
/// <summary>
/// 创建Key 和IV在某个目录下
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public RijndaelKey CreateKeyAndIV(string path)
{
RijndaelManaged rijma = new RijndaelManaged();
rijma.GenerateKey();
rijma.GenerateIV();
FileTools.CreateFile(path + "/keyTxt.txt", rijma.Key);
FileTools.CreateFile(path + "/IVTxt.txt", rijma.IV);
return new RijndaelKey(rijma.Key, rijma.IV);
}
/// <summary>
/// 获取Key 和IV
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public RijndaelKey GetKeyAndIV(string path)
{
byte[] key = FileTools.ReadFile(path + "/keyTxt.txt");
byte[] IV = FileTools.ReadFile(path + "/IVTxt.txt");
return new RijndaelKey(key, IV);
}
}
using System.Collections;
using System.IO;
using System.Text;
/// <summary>
/// IO读写类
/// </summary>
public class FileTool
{
/// <summary>
/// 创建目录文件夹 有就不创建
/// </summary>
public static void CreateDirectory(string filePath)
{
if (!string.IsNullOrEmpty(filePath))
{
if (!File.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
}
}
/// <summary>
/// 创建文件
/// </summary>
/// <param name="filePath"></param>
/// <param name="bytes"></param>
public static void CreateFile(string filePath, byte[] bytes)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
fs.Write(bytes, 0, bytes.Length);
}
}
public static void CreateFile(string filePath, string str)
{
byte[] bytes = StrToBytes(str);
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
fs.Write(bytes, 0, bytes.Length);
}
}
/// <summary>
/// 读取文件
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public static byte[] ReadFile(string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] infbytes = new byte[fs.Length];
fs.Read(infbytes, 0, infbytes.Length);
return infbytes;
}
}
public static byte[] StrToBytes(string str)
{
return Encoding.Default.GetBytes(str);
}
public static string BytesToStr(byte[] bytes)
{
return Encoding.Default.GetString(bytes, 0, bytes.Length);
}
}