GameTang
圣骑士
圣骑士
  • UID4314
  • 粉丝3
  • 关注2
  • 发帖数43
  • 社区居民
阅读:2741回复:4

Vuforia和视频播放器EasyMovieTexture的交互

楼主#
更多 发布于:2017-08-08 09:58
 大家好,我是游戏唐,新手一枚,最近刚入坑Vuforia,在学习AR视频播放方面的知识,就把自己最近整理的一些相关内容整理下,与大家分享下,主要的交互功能有左右划屏控制视频的进度快退/快进,单击暂停,双击切换下一个视频(主要是手势操作,功能简单,就没有做切换到上一个,其实原理与切换到下一个相同,至于用什么样的手势去控制,还请大家自由发挥哈)第一次发帖,其中错误之处还请大家多多指教。(Demo的Apk和工程我会在结尾易以网盘链接的形式贴在下面)。
    首先,Vuforia的SDK的下载导入我就不多说了,AR学院网站上归海一啸大神已经为各位同学做了详细教程:传送门。我这里EasyMovieTexture为3.59版本,应该是比较新的版本:EasyMovieTexture网盘链接:http://pan.baidu.com/s/1slfSXeH 密码:po27
    好了,资源方面就这么多,下面我们开始创建工程。Unity方面我用的Unity5.6.0,我们将Vuforia和EasyMovieTexture导入自己的工程,将Vuforia的AR Camera拖入到场景中,删除Main Camera,然后将Vuforia的ImageTarget同样拖入到场景中,在ImageTarget下创建一个Plan当做播放视频的载体命名为VideoPlan,同时创建一个Material命名为VideoPlan赋给VideoPlan大小根据自己喜欢进行调整,建议最好位置在识别图上方不远的距离,大小不要超过识别大小太多,看着方便(个人感觉,嘿嘿)然后再VideoPlan下在创建一个Slider,当做视频的进度条,创建完以后布局如下所示

图片:TextureOne.png





        然后,我们开始视频播放器的搭建,首先我们现将EasyMovieTexture的MediaPlayerCtrl添加到AR Camera上(位置随意);对MediaPlayerCtrl进行如下的处理,

图片:TextureTwo.png



接着我们创建一个C#脚本,我命名为:EasyMoveCtrl



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Vuforia;
using System;
  
  
public class EasyMoveCtrl : MonoBehaviour
{
  
    //定义EasyMovieTexture 引用
    public MediaPlayerCtrl myPyCtrl;
  
    //定义时间
    private float time;
    //定义触屏状态(用来防止单击移动两个阶段冲突设置的状态)
    private bool state;
    //视频组
    private List<string> moviePath = new List<string>();
    //视频进度条UI
    private Slider videoSlider;
    //定义是否正在播放
    private bool isMovePlaying = false;
    //定义是否允许操作
    private bool isOperation = false;
    //定义单击手势操作是否切换播放或者暂停按钮(我没有找到MediaPlayerCtrl定义的返回isPlaying的设置,此处为自己定义)
    private bool isPlayOrPause;
    //定义检测到识别图播放视频且播放逻辑只走一次,不影响后续操作
    private bool isPlayOne = false;
    //定义切换视频的顺序
    private int count = 0;
    //定义代表播放平板和Slider物体
    public GameObject videoPlan;
    public GameObject videosliderGameOBJ;
    //定义Slider的显隐状态
    private bool isEnable;
    //定义一个Touch 全局变量 方便使用(可以视自己情况可选)
    private Touch touch;
    // Use this for initialization
    void Start()
    {
        //添加视频组内容
        AddMovieName();
        //自动对焦
        Vuforia.CameraDevice.Instance.SetFocusMode(Vuforia.CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
        //屏幕常亮
        Screen.sleepTimeout = SleepTimeout.NeverSleep;
        //寻找监视面板中代表视频进度条的Slide UI
        videoSlider = GameObject.Find("Slider").GetComponent<slider>();
        //初始重置Slider值归零
        videoSlider.value = 0;
        //初始重置Slider UI状态为隐藏
        videosliderGameOBJ.SetActive(false);
    }
  
    // Update is called once per frame
    void Update()
    {
  
        //手机程序退出
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Application.Quit();
        }
        //if (Input.GetMouseButtonDown(0))
        //{
        //    mePyCtrl.m_strFileName = moviePath[0] + ".mp4";
        //    mePyCtrl.Play();
        //}
        //if (Input.GetMouseButtonDown(1))
        //{
        //    mePyCtrl.Load(NextMoviePlay());
        //}
        //检测到标示图开始播放视频
        if (DefaultTrackableEventHandler.instance.isAllow)
        {
            if (!isPlayOne)
            {
                //初始加载视频组第一个视频,当做默认播放设置,应该也可以用Load加载,临时想起来的大家可以试验下
                myPyCtrl.m_strFileName = moviePath[0] + ".mp4";
                //调用播放,不用的话就不会播放(此时是关闭MediaPlayerCtrl的初始自动播放设置的)
                myPyCtrl.Play();
                //默认正在播放,用来后面单击判断是暂停还是播放(true false 根据自己习惯)
                isMovePlaying = true;//
                //检测到标示图,允许进行后续操作
                isOperation = true;
                //代表此判断语句只执行一次
                isPlayOne = true;
            }
  
        }
  
        if (isOperation)
        {
            //    Ray ray = ARcamera.ScreenPointToRay(Input.GetTouch(0).position);
            //    RaycastHit hit;
  
            if (Input.touchCount >0)
            {
                touch = Input.GetTouch(0);
                //点击开始阶段
                if (touch.phase == TouchPhase.Began)
                {
                    time += Time.deltaTime;
                      
                }
                //点击移动阶段
                else if (touch.phase == TouchPhase.Moved)
                {
                    time += Time.deltaTime;
                    //定义变量 用来计算滑动的坐标增量
                    Vector2 offsetPos = Input.GetTouch(0).deltaPosition;
                    //接收储存X轴向移动的距离
                    float temp = offsetPos.x;
                    //赋值给视频进度Slider
                    videoSlider.value += temp / 5000;
                    //更改视频的进度值(传入的参数最好是Slider值,而不是一个定值)
                    myPyCtrl.SetSeekBarValue(videoSlider.value);
                    //移动阶段不执行点击事件
                    state = true;
                }
                //点击结束阶段
                else if (touch.phase == TouchPhase.Ended)
                {
                    if (!state)
                    {
                        //StartCoroutine(singleOrDouble());
                        //执行单击双击检测,tapCount就是GetTouch代表点击次数的方法
                        SingleOrDoubles(touch.tapCount);
                    }
                    //操作阶段结束,时间重置
                    time = 0;
                    //更改防冲突控制状态
                    state = false;
                }
                
            }
            else
            {
                //将视频的进度赋值给Slider
                videoSlider.value = myPyCtrl.GetSeekBarValue();
                
            }
            //记录储存VideoOlan的Renderer的状态,
            isEnable = videoPlan.GetComponent<renderer>().enabled;
            //Slider的显隐状态跟随播放平板的显隐状态
            videosliderGameOBJ.SetActive(isEnable);
        }
  
    }
    //选择下一个视频,返回一个字符串,将此字符串赋值给路径
    string NextMoviePlay()
    {
        string fileName;
        if (count >= moviePath.Count)
        {
            count = 0;
            return fileName = moviePath[count] + ".mp4";
        }
        else
        {
            count++;
            fileName = moviePath[count] + ".mp4";
            
            return fileName;
        }
        
    }
  
    //选择上一个视频
    void LastMoviePlay()
    {
          
    }
    //添加视频名字
    void AddMovieName()
    {
        moviePath.Add("SwordArtOnline2");
        moviePath.Add("SwordArtOnline3");
        moviePath.Add("SwordArtOnline4");
    }
    //单击
    void Single()
    {
        if (isMovePlaying)
        {
            myPyCtrl.Pause();
            isMovePlaying = false;
        }
        else
        {
            myPyCtrl.Play();
            isMovePlaying = true;
        }
    }
    // 检测单击和双击
    IEnumerator SingleOrDouble()
    {
        yield return new WaitForSeconds(0.3f);
        if (touch.tapCount == 1)
        {
            Single();
              
        }
  
        else if (touch.tapCount == 2)
        {
            //stop 否则会触发两次Double Touch
            StopCoroutine(SingleOrDouble());
            //使用MediaPlayerCtrl的加载视频的方法
            myPyCtrl.Load(NextMoviePlay());
           //加载到视频路径,执行视频播放
            myPyCtrl.Play();
        }
    }
    //单击双击检测
    void  SingleOrDoubles(int count)
    {
        switch (count)
        {
            case 1: Single();
                break;
            case 2: ChangeMovie();
                break;
            
        }
    }
    void ChangeMovie()
    {
        //使用MediaPlayerCtrl的加载视频的方法
        myPyCtrl.Load(NextMoviePlay());
        //加载到视频路径,执行视频播放
        myPyCtrl.Play();
    }
}

编辑完脚本后,将其挂在AR Camera 上,对齐进行如下处理

图片:TextureThre.png



     好了,现在看完脚本后我简单解析我我写的逻辑、学习时遇到的坑以及解决办法。
定义变量的部分我就不说了,每个我都有详细的注释,说明用来做什么的。首先我的逻辑都是在读取到识别图之后才能进行,

//检测到标示图开始播放视频
       if (DefaultTrackableEventHandler.instance.isAllow)
       {
           if (!isPlayOne)
           {
               //初始加载视频组第一个视频,当做默认播放设置,应该也可以用Load加载,临时想起来的大家可以试验下
               myPyCtrl.m_strFileName = moviePath[0] + ".mp4";
               //调用播放,不用的话就不会播放(此时是关闭MediaPlayerCtrl的初始自动播放设置的)
               myPyCtrl.Play();
               //默认正在播放,用来后面单击判断是暂停还是播放(true false 根据自己习惯)
               isMovePlaying = true;//
               //检测到标示图,允许进行后续操作
               isOperation = true;
               //代表此判断语句只执行一次
               isPlayOne = true;
           }
  
       }

此处就是我对其做的限制,只有首次读取到识别图后才能进行的操作,我对Vuforia ImageTarget预制体上的 DefaultTrackableEventHandler 做了些稍微的改动,相当于单例,方面在其他的函数调用,这样改造的脚本运行的前提是必须已经挂在场景中,否则会出错,无法运行

图片:TextureFour.png

图片:TextureFive.png





       我将视频都放在StreamingAssets文件夹中EasyMovieTexture插件的会自动去读取(修改路径的话以后有时间我在学习了解下,然后再给大家分享)。我在简单说下用到EasyMovieTexture的方法:
初始时EasyMovieTexture需要在面板上   MedioPlayCtrl脚本得 strFileName 进行赋值(初始的话可能用Load也可以),也可以获取这个脚本得    myPyCtrl.m_strFileName(myPyCtrl脚本开头我有说明),注意的是myPyCtrl.m_strFileName赋值完后要调用播放的方法,
暂停:   myPyCtrl.Pause();
播放:   myPyCtrl.Play();
获取视频的进度值:myPyCtrl.GetSeekBarValue();
设置视频的进度值:  myPyCtrl.SetSeekBarValue(videoSlider.value);  此处传入的Slider值
切换视频要用Load()方法,同样要调用播放的方法


//使用MediaPlayerCtrl的加载视频的方法
       myPyCtrl.Load(NextMoviePlay());
       //加载到视频路径,执行视频播放
       myPyCtrl.Play();

       之前我切换视频时用的还是 myPyCtrl.m_strFileName 赋值的方法,一直不成功,也不知问题在哪,然后就看了下EasyMovieTexture的Sample,发现他们用的是Load()方法,泪奔
       还是有就是单击/双击的判定,也是搞了好久一直不如意我先贴下归海大神的判断单击双击的教程:单击/双击/对焦  还有CSDN:Unity的各种双击
关于归海大神的我也用了,但是并没有禁止掉触发两次双击,(也就是我脚本中协程那个方法,其中Update的时间控制逻辑我已经去除了,详细的还请查看归海大神的帖子)我现在采用的方法我也忘了在哪里扒到的了,特此感谢匿名大神(不是故意的啊);
      
     最后一个,因为视频的进度条是自己用UGUI做的,Vuforia 扫描识别图控制模型隐藏操控就是模型的Render组件,但是,UI并没有Render组件,所以我就获取模型Render的显隐状态,然后记录,赋值给UI Slider  这样Slider就会和模型/播放载体一同显隐,初始设置隐藏,这样就不会有个单独的Slider尴尬的出现在屏幕上了


//记录储存VideoOlan的Renderer的状态,
         isEnable = videoPlan.GetComponent<renderer>().enabled;
         //Slider的显隐状态跟随播放平板的显隐状态
         videosliderGameOBJ.SetActive(isEnable);
    大家也可以仔细看下我GetTouch(手势操作部分的逻辑),完好的避免了视频快进时滑动屏幕会先触发点击操作,高人指点哦,我的每行代码都有详细的注释,不明白的同学可以在评论中讨论,好了一个功能简单AR视频播放器就完成了。

        做的不好,还望大家多多指教,新手上路请求护航!()

DemoApk:链接:http://pan.baidu.com/s/1cnPi5C 密码:obma(识别图我用的身份证背面,下载运行即可)
工程        :链接:http://pan.baidu.com/s/1qXZjxJQ 密码:gd74
[GameTang于2018-04-13 14:37编辑了帖子]

最新喜欢:

gear迷哥gear迷哥 归海一啸归海一啸

欢迎分享

GameTang
圣骑士
圣骑士
  • UID4314
  • 粉丝3
  • 关注2
  • 发帖数43
  • 社区居民
沙发#
发布于:2017-08-08 10:52
感谢归海大神的支持!!
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
板凳#
发布于:2017-08-08 10:56
GameTang:感谢归海大神的支持!!回到原帖
不错不错,继续坚持~
AR学院(www.arvrschool.com),从这里感触未来!
GameTang
圣骑士
圣骑士
  • UID4314
  • 粉丝3
  • 关注2
  • 发帖数43
  • 社区居民
地板#
发布于:2017-08-08 10:58
归海一啸:不错不错,继续坚持~回到原帖
好哒
gear迷哥
贫民
贫民
  • UID4710
  • 粉丝0
  • 关注0
  • 发帖数1
4楼#
发布于:2017-10-27 09:50
大神,我要发布一个支持gear vr的oculus版本的该怎么弄啊。我在vr support里选择oculus之后,就报错不兼容,然后下了个最新版本的2017.1.2unity,试用easymoviewtexture没有图像,只有声音
游客

返回顶部