Set Video playback speed in Unity

狂风中的少年 提交于 2020-01-07 04:35:06

问题


My general problem is that I need to play and control the speed of a video (no sound) inside a Unity3D world and probably need to control the decoding myself and I have absolutely no idea how to do that efficiently. So any hints in the right direction are welcome.

I need to play a video projected on a Material in Unity and I need to control the speed of that video at runtime. As I target mobile devices I cannot use MovieTexture. There are alternatives like e.g. Easy Movie Texture but they do not allow me to control the speed of the video.

I found a problematic solution in this post. In short, the author breaks the video into its frames and then displays it frame by frame. This way I can control the video speed by simply changing the time until displaying the next frame. The video does not have any sound, so it's that easy. The problem is that this is a nightmare from a memory and performace point of view. The app would be GB big and inefficient.

So as far as I know a normal video player solves that by not saving and displaying every frame but just delta between them. If I could do that myself and control it frame by frame I'd solve my problem.

I imagine to decode it at runtime and then display the delta's. But I have no idea how to do that. So please point me in the right direction or maybe even give me a solution if you have.

The video format is not yet fixed, so whatever is easiest.


回答1:


You don't need Easy Movie Texture to do this and you don't even need to get the video frames to do this.

With the new Unity VideoPlayer API, you can check if you can set the playback speed on the platform with VideoPlayer.canSetPlaybackSpeed. If it returns true, you can then set the video playback speed by simply changing the videoPlayer.playbackSpeed property.

You can use the code in this answer to play video on RawImage then add the code below to set the playback speed.

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

It is as simple as that.


You mentioned that you want the image to be projected on a material. In this case, you should set the VideoPlayer.renderMode to VideoRenderMode.MaterialOverride;

The code below should project the video on any GameObject called "DisplayObject". You can also access the material from the video in the outputRenderer or outputRenderer.material variable.

It has audio for testing purposes and you can remove it if you don't want audio like you mentioned in your 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;
        }
    }
}


来源:https://stackoverflow.com/questions/42954566/set-video-playback-speed-in-unity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!