U4S3L4——Video Player 视频播放器

本章代码关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
videoPlayer.playOnAwake            //是否自动播放
videoPlayer.renderMode //渲染模式
VideoRenderMode //渲染模式的枚举
VideoRenderMode.RenderTexture //要渲染的目标贴图
videoPlayer.targetCamera //要渲染到的目标摄像机
videoPlayer.texture //放置视频内容的内部纹理,可以每帧通过此属性获取视频显示内容,当renderMode属性为APIOnly时必须使用此属性获取视频内容
videoPlayer.targetCameraAlpha //视频透明度,渲染模式选择摄像机相关时
videoPlayer.source //视频源
VideoSource //视频源的枚举
videoPlayer.clip //要播放的视频切片
videoPlayer.url //要播放的视频的url路径
videoPlayer.length //视频的长度(秒)
videoPlayer.time //视频播放了多久(秒)
videoPlayer.frameCount //视频的总帧数
videoPlayer.frame //视频当前播放到那一帧
videoPlayer.playbackSpeed //视频播放速度
videoPlayer.Play(); //播放视频
videoPlayer.Stop(); //停止视频
videoPlayer.Pause(); //暂停视频
videoPlayer.Prepare(); //准备视频
videoPlayer.prepareCompleted //当准备完毕时执行的事件
videoPlayer.started //当视频开始播放时执行的事件
videoPlayer.loopPointReached //当视频播放到结尾时执行的事件

Video Player

Video Player 顾名思义是视频播放器的意思,它是 Unity 提供给我们用于播放视频的组件
该视频播放器组件,可以在游戏中播放导入的视频剪辑文件

VideoPlayer​是用于视频播放的组件,我们可以通过它来控制视频播放相关设置

其中比较重要的参数有

  1. 渲染模式
  2. 播放暂停相关 API

视频播放时,需要有短暂的准备时间才会开始播放,我们可以通过 Prepare()​ 函数来启动准备,准备完毕后再正式开始播放

添加 Video Player 组件

  • 方法一:在 Hierarchy 窗口点击加号,选择 Video > Video Player

    image

  • 方法二:选择场景上任何一个对象,为其添加 Video Player 组件

    image

  • 方法三:直接将视频文件拖入到 Hierarchy 窗口中

Video Player 参数相关

image

  • Source 视频源

    • Video Clip 视频剪辑

      注意!WebGL 平台不支持此方式播放视频

      可以直接将视频剪辑拖入此处或者选择视频剪辑进行关联

    • URL 视频路径

      选择视频的路径,可以是远程视频路径,播放在服务器上的视频
      也可以之后通过代码直接关联视频资源路径

  • Play On Awake 场景启动时就播放视频

    如果希望自己控制播放时机,请取消该选项

  • Wait For First Frame 等待第一帧准备完毕

    如果勾选该选项,Unity将等待视频第一帧准备好显示,
    如果取消勾选,可能会丢弃前几帧使视频时间与游戏保持同步

  • Loop 是否循环播放

  • Skip On Drop 是否允许视频播放器跳过帧以赶上当前时间

  • Playback Speed 表示播放速度的乘数

    0~10之间的值
    1表示正常速度,如果数值为2,则视频速度*2,表示两倍速播放

  • Render Mode 渲染方式

    • Camera Far Plane 在摄像机的远平面上渲染

      这意味着摄像机仍然会显示到拍摄到的物体

      image

      image

      • Camera 定义接受视频的摄像机
      • Alpha 视频的全局透明度
      • 3D Layout 3D层级
    • Camera Near Plane 在摄像机的近平面上渲染

      参数与上一个相同,但是这里视频将会遮挡拍摄到的物体

      image

      image​​

    • Render Texture 将视频渲染到渲染纹理中

      image

      • Target Texture 用于渲染图像的渲染纹理
        (建议将纹理的尺寸设置到与视频分辨率一致)
    • Material Override 通过游戏对象渲染器的材质将视频渲染到游戏对象的选定纹理属性中

      效果如下:

      image

      • Renderer 用于渲染图像的渲染器(Mesh Renderer)

        如果为 None,则使用 Video Player 依附对象的上的渲染器

    • API Only 不预先设置渲染到哪里,通过代码来设置视频渲染到哪里

      在此模式下,可以直接通过 Video Player 中的 texture​ 属性获取这一帧的视频显示内容的 Texture​ ,之后直接在场景上使用此 Texture​ 即可,此方法需要你每帧去通过 texture​ 属性获取视频画面。

  • Aspect Ratio 宽高比设置

    image

    • No Scaling 不使用缩放

    • Fit Vertically 垂直适应目标矩形

      必要时裁剪左侧和右侧或在每侧留下黑色区域
      以保留原视频的宽高比

    • Fit Horizontally 水平适应目标矩形

      必要时裁剪顶部和底部或在顶或底留下黑色区域
      以保留原视频的宽高比

    • Fit Inside 对原视频进行缩放而不必裁剪,但是可能会留黑边

    • Fit Outside 对原视频进行缩放,可能需要进行裁剪而不会留黑边

    • Stretch 在水平和垂直方向均进行缩放以适应目标矩形。不会保留源宽高比

  • Audio Output Mode 如何输出视频源的音频

    image

    • None 不播放音频

    • Audio Source 发送给指定的音频源对象,允许Unity的音频处理

      • Audio Source 用于播放音频轨道的音频源
    • Direct 直接绕过Unity音频处理,发送给音频输出硬件输出

      • Mute 静音
      • Volume 音量
    • API Only 通过代码将音频样本发送到关联AudioSampleProvider听诊器

  • Track Enabled 启用关联的音频轨道用于播放,必须在播放前设置

    image

    比如: Track 0[en, 2 ch]表示有一个音频轨道,语言是 en,
    并且音频轨道有2个声道(2 ch),表示它是双声道音频轨道

Video Player 代码相关

注意:使用 VideoPlayer​ 组件需要引用命名空间 UnityEngine.Video

  1. 将一个 VideoPlayer​​ 附加到主摄像机
    VideoPlayer​​ 添加到摄像机对象时,它会自动瞄准摄像机背板,无需更改videoPlayer.targetCamera​​

    1
    2
    GameObject camera = GameObject.Find("Main Camera");
    VideoPlayer videoPlayer = camera.AddComponent<VideoPlayer>();

    ​​image​​

  2. 参数相关设置

    • 是否自动播放

      1
      videoPlayer.playOnAwake = true;
    • 渲染模式

      这里是使用 VideoRenderMode​ 枚举来选择模式,参数和Inspector窗口上的渲染方式一致

      1
      videoPlayer.renderMode = VideoRenderMode.CameraNearPlane;
      • 当选择 VideoRenderMode.RenderTexture​ 时,就可以设置 targetTexture​ 属性

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        using UnityEngine.Video;

        public class Lesson2 : MonoBehaviour
        {
        public RenderTexture texture;
        public VideoClip clip;

        void Start()
        {
        GameObject camera = GameObject.Find("Main Camera");
        VideoPlayer videoPlayer = camera.AddComponent<VideoPlayer>();
        videoPlayer.renderMode = ​VideoRenderMode.RenderTexture​;
        videoPlayer.targetTexture = texture
        }
        }
      • 当选择 VideoRenderMode.CameraNearPlane​ 或者 VideoRenderMode.CameraFarPlane​ 时,就可以设置目标摄像机 targetCamera​ 参数

        1
        2
        videoPlayer.renderMode = VideoRenderMode.CameraNearPlane;
        videoPlayer.targetCamera = Camera.main;
      • 当选择 VideoRenderMode.APIOnly​ 时,需要每帧通过 texture​ 属性获取画面内容的 Texture​,接下来即可直接使用此 Texture​ 对象显示视频

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        using UnityEngine;
        using UnityEngine.Video;

        public class VideoTest : MonoBehaviour
        {
        VideoPlayer player;
        public VideoClip clip;

        void Start()
        {
        player = gameObject.AddComponent<VideoPlayer>();
        // 使用APIOnly渲染模式,不需要额外准备摄像机或者RenderTexture
        player.renderMode = VideoRenderMode.APIOnly;
        player.playOnAwake = true;
        player.clip = clip;
        player.Prepare();
        }

        private void OnGUI()
        {
        // 使用GUI相关直接将视频内容显示在屏幕上,你也可以使用UGUI的RawImage来显示画面
        Texture videoTexture = player.texture;
        GUILayout.Label(new GUIContent(videoTexture));
        }
        }

        显示效果:

        image

    • 透明度

      1
      videoPlayer.targetCameraAlpha = 0.5f;
    • 视频源

      这里是使用 VideoSource​ 枚举来选择模式,有 VideoSource.VideoClip​ 和 VideoSource.Url​ 两种

      1
      videoPlayer.source = VideoSource.VideoClip
      • 视频切片

        警告!WebGL 平台不支持视频切片,因此也不支持通过此方式加载要播放的播放视频

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        using UnityEngine.Video;

        public class Lesson2 : MonoBehaviour
        {
        public RenderTexture texture;
        public VideoClip clip;

        // Start is called before the first frame update
        void Start()
        {
        GameObject camera = GameObject.Find("Main Camera");
        VideoPlayer videoPlayer = camera.AddComponent<VideoPlayer>();
        videoPlayer.source = VideoSource.VideoClip;
        videoPlayer.clip = clip;
        }
        }
      • URL地址

        1
        2
        videoPlayer.source = VideoSource.Url;
        videoPlayer.url = Application.streamingAssetsPath + "/Video.mp4";
    • 视频总时长

      单位为秒

      1
      print(videoPlayer.length);    //单位为s
    • 当前时长,即播放了多久

      单位为秒

      1
      print(videoPlayer.time);    //单位为s
    • 总帧数

      1
      print(videoPlayer.frameCount);
    • 当前帧

      1
      print(videoPlayer.frame);
    • 播放速度

      playbackSpeed​ 属性可用于控制视频播放速度,正常速度是 1.0f

      • 如果 playbackSpeed​ 大于 1.0,则视频会以快于正常速度的速率播放;
      • 如果 playbackSpeed​ 在 0 到 1.0 之间,则视频会以慢于正常速度的速率播放;
      • 如果 playbackSpeed​ 等于 1.0,则视频以正常速度播放;
      • 如果 playbackSpeed​ 小于 0,此行为是未定义的,通常不支持反向播放通过此属性。
      1
      2
      3
      4
      5
      6
      public void SetPlaybackRate(float speed)
      {
      // 可以通过Mathf.Clamp等方式限制加快或者减慢的速度
      float rate = Mathf.Clamp(speed, 0.25f, 8f);
      videoPlayer.playbackSpeed = rate;
      }
  3. 方法相关

    • 视频播放

      1
      2
      3
      4
      if (Input.GetKeyDown(KeyCode.Space))
      {
      videoPlayer.Play();
      }
    • 视频停止

      1
      2
      3
      4
      if (Input.GetKeyDown(KeyCode.S))
      {
      videoPlayer.Stop();
      }
    • 视频暂停

      1
      2
      3
      4
      if (Input.GetKeyDown(KeyCode.P))
      {
      videoPlayer.Pause();
      }
    • 视频准备函数

      预先加载视频,之后播放视频反应可以更加迅速

      1
      videoPlayer.Prepare();
  4. 事件相关

    • 准备视频完成事件

      1
      2
      3
      4
      5
      videoPlayer.prepareCompleted += (v) =>
      {
      print("准备完成");
      isOver = true;
      };
    • 开始事件

      1
      2
      3
      4
      videoPlayer.started += (v) =>
      {
      print("当执行player播放方法后 会调用的事件");
      };
    • 当视频播放到结尾时调用事件

      1
      2
      3
      4
      videoPlayer.loopPointReached += (v) =>
      {
      print("视频播放到结尾处会调用的事件");
      };