【小沐学Unity3d】Unity播放视频(VideoPlayer组件)

文章目录

  • 1、简介
  • 2、脚本播放示例
  • 3、界面播放示例
    • 3.1 2d界面全屏播放
    • 3.2 2d界面部分区域播放
    • 3.3 3d模型表面播放
  • 结语

1、简介

使用视频播放器组件可将视频文件附加到游戏对象,然后在运行时在游戏对象的纹理上播放。

  • 视频播放器 (Video Player) 组件:

【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第1张图片

属性 功能
Source 选择视频源类型。Video Clip:将视频剪辑分配给视频编辑器。使用此字段来定义分配给视频播放器组件的视频剪辑。将视频文件拖放到此字段中,或单击该字段右侧的圆圈,然后从资源列表中选择文件(如果该文件位于 Project 文件夹中)。
Play On Awake 勾选 Play On Awake 复选框可在场景启动时播放视频。如果希望在运行时的另一个点触发视频播放,请取消勾选此复选框。此情况下可使用 Play() 命令通过脚本触发视频播放。
Render Mode 使用下拉选单来定义视频的渲染方式。Camera Far Plane:在摄像机的远平面上渲染视频。Camera Near Plane:在摄像机的近平面上渲染视频。Render Texture:将视频渲染到渲染纹理中。Material Override:通过游戏对象渲染器的材质将视频渲染到游戏对象的选定纹理属性中。API Only:将视频渲染到 VideoPlayer.texture 脚本 API 属性中。必须使用脚本将纹理分配给其预期目标。

2、脚本播放示例

以下脚本演示了 VideoPlayer 组件的一些功能。

  • (1)在层级树上新建一个空对象

【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第2张图片

  • (2)在项目面板通过鼠标右键菜单,新建一个脚本对象,内容如下:
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第3张图片
// VideoPlayer 函数示例

using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        // 将一个 VideoPlayer 附加到主摄像机。
        GameObject camera = GameObject.Find("Main Camera");

        // 将 VideoPlayer 添加到摄像机对象时,
        // 它会自动瞄准摄像机背板,无需更改 videoPlayer.targetCamera。
        var videoPlayer = camera.AddComponent<UnityEngine.Video.VideoPlayer>();

        // Play on Awake 默认为 true。将它设置为 false 以避免下面设置的 URL
        // 自动开始播放,因为我们处于 Start() 状态。
        videoPlayer.playOnAwake = false;

        // 默认情况下,添加到摄像机的 VideoPlayer 将使用远平面。
        // 让我们改为瞄准近平面。
        videoPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane;

        // 这将使场景通过正在播放的视频可见。
        videoPlayer.targetCameraAlpha = 0.5F;

        // 设置要播放的视频。URL 支持本地绝对或相对路径。
        // 此处使用绝对路径。
        videoPlayer.url = "file:///D:/basketball.mp4";

        // 跳过前 100 帧。
        videoPlayer.frame = 100;

        // 完成后从头重新开始。
        videoPlayer.isLooping = true;

        // 每次到达结尾时,我们都会将播放速度减慢 10 倍。
        videoPlayer.loopPointReached += EndReached;

        // 开始播放。这意味着 VideoPlayer 可能需要做好准备工作(预留
        // 资源、预加载几帧等)。为了更好地控制此项准备工作
        // 带来的延迟,您可以使用 videoPlayer.Prepare() 及其
        // prepareCompleted 事件。
        videoPlayer.Play();
    }

    void EndReached(UnityEngine.Video.VideoPlayer vp)
    {
        vp.playbackSpeed = vp.playbackSpeed / 10.0F;
        Debug.Log("Video: End reached!");
    }
}
  • (3)将上面的脚本对象Example.script挂在上面新建的空对象上。
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第4张图片
  • (4)点击上面的播放按钮,
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第5张图片
  • (5)运行如下:
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第6张图片

注意:URL 源选项会绕过资源管理,这意味着您必须手动确保 Unity 可以找到源视频。例如,一个 Web URL 需要由 Web 服务器托管源视频,而普通文件必须位于 Unity 可以找到该文件的位置(用脚本表示)。但是,如果内容不在 Unity 的直接控制之下,或者您希望避免在本地存储大型视频文件,则此功能非常有用。如果将视频播放器组件源设置为 URL,也可通过 http:// 和 https:// 从 Web 源读取视频。在这些情况下,Unity 会执行必要的预缓冲和错误管理。置于 Unity 的 StreamingAssets 文件夹中的文件可通过视频播放器组件的 URL 选项(见上文)进行使用,也可借助特定于平台的路径 (Application.streamingAssetsPath) 进行使用。

提示:Unity3d 拖拽脚本报错Can’t add the script component “” because the script class cannot be found
报错原因:文件名与文件内容中的类名不相符。c#文件创建以后再改名,会报错找不到对应类。类名和文件名要一致才行。(这个是Unity要求,c#本身不要求一致)

这里提供两段网上的示例脚本如下:

  • VideoScript1.cs:
using UnityEngine;
using UnityEngine.Video;
 
public class VideoScript1 : MonoBehaviour
{
    void Start () {
        var vPlayer = gameObject.AddComponent<VideoPlayer>();
        vPlayer.URL = "https://images.nvidia.cn/cn/youtube-replicates/p7RniXWvYhY.mp4";
        vPlayer.target = UnityEngine.Video.VideoTarget.CameraFrontPlane;
        vPlayer.alpha = 0.8f;
        vPlayer.prepareCompleted += Prepared;
        vPlayer.Prepare();
        Debug.Log("Video: Start!");
    }
 
    void Prepared(VideoPlayer vPlayer)
    {
        Debug.Log("Video: End reached!");
        vPlayer.Play();
    }
}
  • VideoScript2.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.UI;
using System;
 
public class VideoScript2: MonoBehaviour {
    //图像
    public RawImage image;
    //播放器
    public VideoPlayer vPlayer;
    public string urlNetWork = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";//网络视频路径
    //播放
    public Button btn_Play;
    //暂停
    public Button btn_Pause;
    //前进
    public Button btn_Fornt;
    //后退
    public Button btn_Back;
    //下一个
    public Button btn_Next;
    //视频控制器
    public Slider sliderVideo;
    //音量控制器
    public Slider sliderSource;
    //音量大小
    public Text text;
    //当前视频时间
    public Text text_Time;
    //视频总时长
    public Text text_Count;
    //音频组件
    public AudioSource source;
    //需要添加播放器的物体
    public GameObject obj;
    //是否拿到视频总时长
    public bool isShow;
    //前进后退的大小
    public float numBer = 20f;
    //时 分的转换
    private int hour, mint;
    private float time;
    private float time_Count;
    private float time_Current;
    //视频是否播放完成
    private bool isVideo;
 
    // Use this for initialization
    void Start () {
        image = obj.GetComponent<RawImage>();
        //一定要动态添加这两个组件,要不然会没声音
        vPlayer = obj.AddComponent<VideoPlayer>();
        source = obj.AddComponent<AudioSource>();
 
        //这3个参数不设置也会没声音 唤醒时就播放关闭
        vPlayer.playOnAwake = false;
        source.playOnAwake = false;
        source.Pause();
 
        //初始化
        Init(urlNetWork);
 
        btn_Play.onClick.AddListener(delegate { OnClick(0); });
        btn_Pause.onClick.AddListener(delegate { OnClick(1); });
        btn_Fornt.onClick.AddListener(delegate { OnClick(2); });
        btn_Back.onClick.AddListener(delegate { OnClick(3); });
        btn_Next.onClick.AddListener(delegate { OnClick(4); });
 
        sliderSource.value = source.volume;
        text.text = string.Format("{0:0}%", source.volume * 100);
        sliderSource.onValueChanged.AddListener(delegate { ChangeSource(sliderSource.value); });
    }
 
    /// 
    ///     初始化VideoPlayer
    /// 
    /// 
    private void Init(string url) {
        isVideo = true;
        isShow = true;
        time_Count = 0;
        time_Current = 0;
        sliderVideo.value = 0;
        //设置为URL模式
        vPlayer.source = VideoSource.Url;
        //设置播放路径
        vPlayer.url = url;
        //在视频中嵌入的音频类型
        vPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
 
        //把声音组件赋值给VideoPlayer
        vPlayer.SetTargetAudioSource(0, source);
 
        //当VideoPlayer全部设置好的时候调用
        vPlayer.prepareCompleted += Prepared;
        //启动播放器
        vPlayer.Prepare();
    }
 
    /// 
    ///     改变音量大小
    /// 
    /// 
    public void ChangeSource(float value) {
        source.volume = value;
        text.text = string.Format("{0:0}%", value * 100);
    }
 
    /// 
    ///     改变视频进度
    /// 
    /// 
    public void ChangeVideo(float value) {
        if (vPlayer.isPrepared)
        {
            vPlayer.time = (long)value;
            Debug.Log("VideoPlayer Time:"+vPlayer.time);
            time = (float)vPlayer.time;
            hour = (int)time / 60;
            mint = (int)time % 60;
            text_Time.text = string.Format("{0:D2}:{1:D2}", hour.ToString(), mint.ToString());
        }
    }
 
    private void OnClick(int num) {
        switch (num)
        {
            case 0:
                vPlayer.Play();
                Time.timeScale = 1;
                break;
            case 1:
                vPlayer.Pause();
                Time.timeScale = 0;
                break;
            case 2:
                sliderVideo.value = sliderVideo.value + numBer;
                break;
            case 3:
                sliderVideo.value = sliderVideo.value - numBer;
                break;
            case 4:
                vPlayer.Stop();
                Init(Application.streamingAssetsPath + "/EasyMovieTexture.mp4");
                break;
            default:
                break;
        }
    }
     
    // Update is called once per frame
    void Update ()
    {
        if (vPlayer.isPlaying && isShow)
        {
            //把图像赋给RawImage
            image.texture = vPlayer.texture;
            //帧数/帧速率=总时长    如果是本地直接赋值的视频,我们可以通过VideoClip.length获取总时长
            sliderVideo.maxValue = vPlayer.frameCount/vPlayer.frameRate;
 
            time = sliderVideo.maxValue;
            hour = (int)time / 60;
            mint = (int)time % 60;
            text_Count.text = string.Format("/  {0:D2}:{1:D2}", hour.ToString(), mint.ToString());
 
            sliderVideo.onValueChanged.AddListener(delegate { ChangeVideo(sliderVideo.value); });
            isShow = !isShow;
        }
 
        if (Mathf.Abs((int)vPlayer.time - (int)sliderVideo.maxValue) == 0)
        {
            vPlayer.frame = (long)vPlayer.frameCount;
            vPlayer.Stop();
            Debug.Log("播放完成!");
            isVideo = false;
            return;
        }
        else if (isVideo && vPlayer.isPlaying)
        {
            time_Count += Time.deltaTime;
            if ((time_Count - time_Current) >= 1)
            {
                sliderVideo.value += 1;
                Debug.Log("value:" + sliderVideo.value);
                time_Current = time_Count;
            }
        }
    }
 
    private void FixedUpdate()
    {
 
    }
 
    void Prepared(VideoPlayer player) {
        player.Play();
    }
}

Unity5.6提供了多种生成Video Player控件的方式:

1、新建一个空白的Video Player:选择菜单栏的GameObject->Video->Video Player或者在Hierarchy面板上选择Create->Video->Video Player或者右击Hierarchy面板空白处选择Video->Video Player。
2、直接将导入的VideoClip拖入场景或者Hierarchy面板,生成的VideoPlayer控件的VideoClip将会自动被赋值,如果场景中存在MainCamera,Camera也会被自动赋值为MainCamera。
3、将导入的VideoClip拖动到场景中的Camera物体上,生成的VideoPlayer控件的VideoClip和MainCamera将会自动被赋值,模式默认选择Camera Far Plane。
4、将导入的VideoClip拖动到场景中的2D或者3D物体上,生成的VideoPlayer控件的VideoClip和Renderer将会自动被赋值,模式默认选择Material Override。
5、将导入的VideoClip拖动到场景中的UI物体上,生成的VideoPlayer控件的VideoClip将会自动被赋值,模式默认选择Render Texture。

VideoPlayer的脚本控制与AudioSource相似,有常规的Play,Pause,Stop方法,也有用于进度控制的time,isPlaying,isLooping,frame,frameCount等属性。
VideoPlayer可以使用一系列事件来监听播放的各个动作:

errorReceived: 错误监听到时被执行。
frameDropped :有丢帧发生时被执行。
frameReady :新的一帧准备好时被执行。
loopPointReached :播放结束或播放到循环的点时被执行。
prepareCompleted :视频准备完成时被执行。
seekCompleted :查询帧操作完成时被执行。
started:在Play方法调用之后立刻调用。

3、界面播放示例

3.1 2d界面全屏播放

  • (1)在层级树上鼠标右键新建一个视频播放对象如下:

【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第7张图片

  • (2)设置视频对象的参数
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第8张图片
    Source:设置视频源,Video Clip或URL。这里使用Video Clip,它的视频资源在项目面板的Assets里面需要提前配置好相关视频资源。
    Render Mode:这里设置为在主相机上播放视频。

  • (3)新建一个脚本对象,绑定在视频播放对象上(当然也可以绑定在其他对象上),用来监控视频播放过程的事件。
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第9张图片

Example2.cs:

using UnityEngine;
using UnityEngine.Video;

public class Example2 : MonoBehaviour
{
    public VideoPlayer vPlayer;

    void Awake()
    {
        vPlayer = GetComponent<VideoPlayer>();
        Debug.Log("Video: Awake";
    }

    void Start()
    {
        vPlayer.loopPointReached += VideoEnd;

        vPlayer.Play();//播放视频
        //vPlayer.Pause();//暂停视频
        //vPlayer.Stop();//停止视频
        //vPlayer.playbackSpeed = 1;//播放速度
        Debug.Log("Video: Start";
    }

    void Update()
    {
        Debug.Log("Video: Frame " + vPlayer.frame);
    }

    /// 
    /// 监听视频是否播放结束,结束时调用
    /// 
    /// 
    void VideoEnd(VideoPlayer vp)
    {
        Debug.Log("爱看书的小沐:视频播放结束");
        Vp.Play();//重新播放视频
    }
}

点击系统的播放按钮运行如下:
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第10张图片

3.2 2d界面部分区域播放

在2D界面播放视频和在3D游戏体上播放,原理及代码是一样的,区别是要把Mesh组件换成RawImage,然后VideoPlayer的RenderMode选项选择RenderTexture或者其他选项。

这里需要把RenderMode 渲染模式改为 Rendertexture ,Canvas画布下创建 RawImage , 在Project 视图下创建 RenderTexture,将RenderTexture 拖入RawImage 的Texture中。

(1)新建一个视频播放对象,并改名为“小沐视频播放”。
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第11张图片

(2)在层级树上,新建一个raw image对象
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第12张图片
新建之后在Canvas下面出现一个RawImage节点。
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第13张图片
修改RawImage在屏幕上的位置;
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第14张图片

(3)Project 视图下创建 RenderTexture。它的属性可以保持默认,不修改。
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第15张图片
(4)修改上面的RawImage对象的属性。将Texture属性关联上面新建的RenderTexture对象。
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第16张图片
(4)修改上面的视频播放对象的属性。将Target Texture属性关联上面新建的RenderTexture对象。
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第17张图片
(5)点击系统的播放按钮运行如下:
【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第18张图片

3.3 3d模型表面播放

  • (1)新建一个视频播放对象,如上。

  • (2)新建一个立方体对象,如下
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第19张图片

  • (3)修改视频对象的属性:
    设置视频源:Source
    设置渲染目标:Render Mode修改为Material Override,同时将Renderer修改为Cude(上面新建的立方体对象)。
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第20张图片

  • (4)预览如下:
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第21张图片
    如果想在立方体的某一个面上播放的话,方法如下:

  • (5)在Cude对象下面新建一个网格对象Quad.
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第22张图片

  • (6)并在三维空间中调整网格对象的位置,相对立方体。
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第23张图片

  • (7)修改视频对象的属性:
    将Renderer的值修改为网格对象Quad.
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第24张图片

  • (8)预览如下:
    【小沐学Unity3d】Unity播放视频(VideoPlayer组件)_第25张图片

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

你可能感兴趣的:(Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#)