在 Unity 中设置视频播放速度

Set Video playback speed in Unity

我的一般问题是我需要在 Unity3D 世界中播放和控制视频(无声音)的速度,并且可能需要自己控制解码,但我完全不知道如何有效地做到这一点。所以欢迎任何正确方向的提示。

我需要在 Unity 中播放投影在 Material 上的视频,我需要在运行时控制该视频的速度。由于我的目标是移动设备,因此我无法使用 MovieTexture。有其他选择,例如简单的电影纹理,但他们不允许我控制视频的速度。

我在这个 post 中找到了一个有问题的解决方案。简而言之,作者将视频分解成帧,然后逐帧显示。这样我就可以通过简单地更改显示下一帧的时间来控制视频速度。视频没有任何声音,就这么简单。 问题是,从内存和性能的角度来看,这是一场噩梦。该应用程序会很大且效率低下。

据我所知,普通的视频播放器通过不保存和显示每一帧而只保存和显示它们之间的增量来解决这个问题。如果我能自己做到这一点并逐帧控制它,我就会解决我的问题。

我想在运行时对其进行解码,然后显示增量。但我不知道该怎么做。所以请指出正确的方向,或者如果有的话甚至可以给我一个解决方案。

视频格式尚未确定,所以最简单的。

您不需要 Easy Movie Texture 来执行此操作,您甚至不需要获取视频帧来执行此操作。

有了新的Unity VideoPlayer API,您可以检查是否可以在VideoPlayer.canSetPlaybackSpeed. If it returns true, you can then set the video playback speed by simply changing the videoPlayer.playbackSpeed 属性.

平台上设置播放速度

您可以使用此 中的代码在 RawImage 上播放视频,然后添加下面的代码来设置播放速度。

if (videoPlayer.canSetPlaybackSpeed)
{
    videoPlayer.playbackSpeed = 1f;
}

就这么简单


您提到要将图像投影到 material 上。在这种情况下,您应该设置 VideoPlayer.renderMode to VideoRenderMode.MaterialOverride;

下面的代码应该将视频投影到任何名为“DisplayObject”的游戏对象上。您还可以从 outputRendereroutputRenderer.material 变量中的视频访问 material。

它有用于测试目的的音频,如果您不想要您在 post 中提到的音频,可以将其删除。

using UnityEngine;
using UnityEngine.Video;

public class VideoSpeedControl : MonoBehaviour
{
    //The material that Video will output to
    Renderer outputRenderer;

    private VideoPlayer videoPlayer;

    //Audio
    private AudioSource audioSource;

    void Start()
    {

        outputRenderer = gameObject.AddComponent<MeshRenderer>();

        //Add VideoPlayer to the GameObject
        videoPlayer = gameObject.AddComponent<VideoPlayer>();

        //Add AudioSource
        audioSource = gameObject.AddComponent<AudioSource>();

        //Disable Play on Awake for both Video and Audio
        videoPlayer.playOnAwake = false;
        audioSource.playOnAwake = false;

        // We want to play from url
        videoPlayer.source = VideoSource.Url;
        videoPlayer.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";

        //Set Audio Output to AudioSource
        videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;

        //Assign the Audio from Video to AudioSource to be played
        videoPlayer.EnableAudioTrack(0, true);
        videoPlayer.SetTargetAudioSource(0, audioSource);

        //Set the mode of output
        videoPlayer.renderMode = VideoRenderMode.MaterialOverride;

        //Set the renderer to store the images to
        //outputRenderer = videoPlayer.targetMaterialRenderer;
        videoPlayer.targetMaterialProperty = "_MainTex";

        //Prepare Video to prevent Buffering
        videoPlayer.Prepare();

        //Subscribe to prepareCompleted event
        videoPlayer.prepareCompleted += OnVideoPrepared;
    }

    void OnVideoPrepared(VideoPlayer source)
    {
        Debug.Log("Done Preparing Video");

        //Play Video
        videoPlayer.Play();

        //Play Sound
        audioSource.Play();

        //Change Play Speed
        if (videoPlayer.canSetPlaybackSpeed)
        {
            videoPlayer.playbackSpeed = 1f;
        }
    }

    bool firsrRun = true;
    void Update()
    {
        if (firsrRun)
        {
            GameObject.Find("DisplayObject").GetComponent<MeshRenderer>().material = outputRenderer.material;
            firsrRun = false;
        }
    }
}