unity插件

Unity AVPro Video插件使用封装

2019-04-22  本文已影响0人  罗卡恩

链接:https://pan.baidu.com/s/1_dB2KxfSRtxJqeK1da-xqg
提取码:pwvj
先是NGUI
插件地址
把插件导入Unity Hierarchy框口右键

image.png
image.png
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;
        }
    }
}
image.png

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挂的是这个脚本


image.png

核心调用脚本

  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);
    }
}

GitHub
https://github.com/1004019267/AVPro-Video

上一篇 下一篇

猜你喜欢

热点阅读