Search Unity

Question the video player does not guarantee first frame

Discussion in 'Audio & Video' started by ExcellencyHong, Jun 8, 2022.

  1. ExcellencyHong

    ExcellencyHong

    Joined:
    Aug 9, 2016
    Posts:
    33
    version : unity 2022.1

    i'm doing make a seamless player.

    play method is frame by frame.

    progressing each frame by frame time in a coroutine.

    but, it seem to be the video player does not guarantee first frame.

    when the first frame of each video, sometimes show empty frame.

    it blinks even if previous video and next video is equals.

    sure, i have turn on the "Wait for First Frame" option.

    is there any solution? or am i missing something necessary for guarantee a first frame?
     
    unity_bYKuS7qdf61RCg likes this.
  2. The_Island

    The_Island

    Unity Technologies

    Joined:
    Jun 1, 2021
    Posts:
    502
    Depending on the platform you are working on, it is possible the first frame we receive is not actually the first video frame in your file. We are dependent on platform SDK, and they all have their issues. The best solution would be to add some padding at the start. Not sure what you are using to move frame by frame, but I recommend using VideoPlayer.StepForward for this as VideoPlayer.frame sometimes is not precise enough.
     
  3. ExcellencyHong

    ExcellencyHong

    Joined:
    Aug 9, 2016
    Posts:
    33
    i appreciate for your kindness. :)

    sometimes, the StepForward does not reached end frame... i had no way..
    in my opinion, it probably somethong to do with the existence of the first frame.

    the way that is to add a padding frame at start seems to be the simplest.

    thanks!
     
  4. CrowbarSka

    CrowbarSka

    Joined:
    Dec 15, 2009
    Posts:
    192
    Sorry to dive into this thread too but it sounds just like the issue I'm having.

    When I try to play a video (not even frame by frame, just using VideoPlayer.Play()) I get a brief flash of a grey box at the start of the video. It's only a frame or two, but full-screen in this case and pretty noticable.
    • Enabling "Wait For First Frame" has no effect (seems like it should address this exact problem, no?)
    • Toggling "Skip on Drop" has no effect either.
    • Also tried various setups of assigning the video clip on Awake or pre-loading it via Resources.Load. Nothing helps.
    This is running on a Windows 10 machine and it occurs in editor and standalone build on multiple machines we've tried. Not exactly an unusual setup, right?

    Would very much appreciate a solution as there is some urgency to this job.
     
  5. The_Island

    The_Island

    Unity Technologies

    Joined:
    Jun 1, 2021
    Posts:
    502
    I assume you are using a Rendertexture or Material Override? We never fill the texture with any colour. So if you see a brief flash of a grey, you probably show the renderer before the VideoPlayer has the time to update the texture.If you are using RenderTexture, you can fill the RenderTexture with transparency like this.
    Code (CSharp):
    1. void Start()
    2.     {    
    3.         rendTex = new CustomRenderTexture(rendTexWidth, rendTexHeight, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
    4.         rendTex.initializationMode = CustomRenderTextureUpdateMode.OnDemand;
    5.         rendTex.initializationSource = CustomRenderTextureInitializationSource.TextureAndColor;
    6.        
    7.         rendTex.initializationColor = new Color(1, 0, 0, 0);
    8.         rendTex.autoGenerateMips = false;
    9.         rendTex.useMipMap = false;
    10.         rendTex.Initialize();
    11.      
    12.         material.mainTexture = rendTex;
    13.  
    14.         _videoPlayer = gameObject.AddComponent<VideoPlayer>();
    15.         _videoPlayer.renderMode = VideoRenderMode.RenderTexture;
    16.         _videoPlayer.targetTexture = rendTex;
    17.  
    18.         _videoPlayer.clip = clip;
    19.         _videoPlayer.Play();
    20.     }
    If you are using Material Override, you need to find a shader that is invisible with no texture in it, like the Standard/Fade shader. Otherwise, you can hide/show the renderer using VideoPlayer.frameReady or wait for VideoPlayer.IsPlaying to be true. If you go with frameReady you need to enable it with VideoPlayer.frameReadyEventsEnabled
     
  6. CrowbarSka

    CrowbarSka

    Joined:
    Dec 15, 2009
    Posts:
    192
    Actually no, just using 'Camera Near/Far Plane' (both had the same result).

    I will try this RenderTexture method instead. Thanks for the detailed help!
     
  7. CrowbarSka

    CrowbarSka

    Joined:
    Dec 15, 2009
    Posts:
    192
    Thanks, this did help! Although I still had a brief frame or two dropped at the start of the video. I had to pre-initialise the RenderTexture on Awake before I could then play it later. Luckily in this case that was possible.

    Please help me understand though: should "Wait For First Frame" not avoid this very problem? I assumed it would freeze the application entirely and not advance any frames or updates until the video is loaded and ready to play the first frame. Is there no way to play a video at any time and guarantee the first frame would be displayed?
     
  8. The_Island

    The_Island

    Unity Technologies

    Joined:
    Jun 1, 2021
    Posts:
    502
    Weird. We are not doing anything other than blit the image in the RenderTexture. To be clear, even with the RenderTexture, you still need a material that allows the alpha channel. Like the Fade Rendering mode.
    upload_2022-6-27_15-32-33.png
    If you use the VideoPlayer.frameReady beware, we don't have the control over when the Texture will be blit because all this is done asynchronously. So if you press play, you could wait for one frame to make sure at least one frame was applied, and it should remove the brief flash.

    Or do you mean now that some frames are missing at the start?

    When you call Play, WaitForFirstFrame will wait for the first frame to start the playback. Otherwise, the playback will catch up to where it should be. So if you call Play at t=0 and get the first frame at t=1, the VideoPlayer will jump to t=1. If WaitForFirstFrame is enabled, with the same scenario, the player will start at t=1, but VideoPlayer would still be at t=0. In both case, the VideoPlayer player start at t=1 but WaitForFirstFrame allows to say you don't want to skip frames.
     
    Last edited: Jun 27, 2022