Search Unity

Video Update RenderTexture when player has paused

Discussion in 'Audio & Video' started by Data1992, Mar 29, 2022.

  1. Data1992

    Data1992

    Joined:
    Dec 1, 2021
    Posts:
    1
    Hey folks,
    i'm trying to implement a scrubbing mechanic for the builtin VideoPlayer component. It works good enough when VideoPlayer plays the video content. However I wonder if there is any way to update the RenderTexture from a paused or stopped video as well? Do I have to play the video for one frame and then pause it again?

    Thanks in advance!
     
  2. The_Island

    The_Island

    Unity Technologies

    Joined:
    Jun 1, 2021
    Posts:
    502
    I am not sure I understand what you are asking. You can change the time value when paused to seek where you want. If you want to move one frame you can use StepForward() (only work if you have a frame ready). But if you do Play() and Pause() you will get the first frame draws in the RenderTexture (at least it does on my editor). Otherwise, if you want to improve the smoothness of your scrubbing mechanic, here is an example with some tips and tricks.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.Video;
    4.  
    5. public class ScrubbingController : MonoBehaviour
    6. {
    7.     public VideoPlayer player;
    8.  
    9.     private bool isSeeking;
    10.     private Slider slider;
    11.  
    12.     void Awake()
    13.     {
    14.         slider = GetComponent<Slider>();
    15.     }
    16.  
    17.     private void Player_seekCompleted(VideoPlayer source)
    18.     {
    19.         isSeeking = false;
    20.     }
    21.  
    22.     void Start()
    23.     {
    24.         slider.maxValue = (float)player.length;
    25.     }
    26.  
    27.     public void BeginScrub()
    28.     {
    29.         //It is recommended to pause the player when seeking as otherwise,
    30.         //you will continuously fight the VideoPlayer from playing and buffering frames.
    31.         player.Pause();
    32.  
    33.         //To know when the player has finished seeking    
    34.         player.seekCompleted += Player_seekCompleted;
    35.         isSeeking = false;
    36.     }
    37.  
    38.     public void UpdateScrub()
    39.     {
    40.         //If you are currently seeking there is no point to seek again.
    41.         if (isSeeking)
    42.             return;
    43.  
    44.         //Don't seek, if the time between the slider value and the current player time is too small.
    45.         //We will seek to the closest frame so if the delta is 0.00001f you will most likely seek the same frame.
    46.         //Change the value to fit your use case.
    47.         if(Mathf.Abs((float)player.time - slider.value) < 0.01f)
    48.             return;
    49.  
    50.         player.time = slider.value;
    51.         isSeeking = true;
    52.     }
    53.  
    54.     public void EndScrub()
    55.     {
    56.         //You don't want random event when you are not using this script
    57.         player.seekCompleted -= Player_seekCompleted;
    58.         player.Play();
    59.     }
    60. }
    61.