So whenever i try showing the video, I get a single frame of the last frame popping up before playing the video.
How would I go about fixing this?
Thanks in advance!
So whenever i try showing the video, I get a single frame of the last frame popping up before playing the video.
How would I go about fixing this?
Thanks in advance!
This might be late, but for future reference:
The videoPlayer retains the last frame instead of resetting to the first frame when the end / the loop point is reached. You can manually reset the frame to the first one by subscribing to the method which is invoked as soon as the videoPlayer reaches the loop point:
// Subscribe to loopPointReached event
videoPlayer.loopPointReached += EndReached;
and then
void EndReached(UnityEngine.Video.VideoPlayer vp)
{
// Reset video to first frame
videoPlayer.frame = 0;
}
Next time you play the video it should start from frame 0 instead of from the last frame.
Hope this helps!
Hi,
I have the same issue and the code you suggested doesn’t seem to do the trick… I still see the last frame of the video everytime I start it again…
Can you post some code of the script which loads/starts the video? Also, what settings do you have for looping, playOnAwake etc.?
this is the code. PlayVid() gets called when tapping on a collider.
Looping is off since I want to disable the gameObject after it played once.
Play on Awake is on and wait for first frame as well.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
public class WorldSpaceVideo : MonoBehaviour
{
public GameObject VP;
public VideoPlayer videoPlayer;
private int videoClipIndex;
// Use this for initialization
void Start ()
{
videoPlayer.loopPointReached += EndReached;
}
public void PlayVid()
{
if (!VP.activeSelf)
{
VP.SetActive (true);
}
}
void EndReached (VideoPlayer videoPlayer)
{
VP.SetActive (false);
}
So did you already try setting videoPlayer.frame = 0 in EndReached?
Yes I added it right here in the but it had no effect. I don’t know if I have to change anything else or if this way of implementing it is completely wrong
void EndReached (VideoPlayer videoPlayer)
{
VP.SetActive (false);
videoPlayer.frame = 0;
}
I’m having the same issue. The video player hold on to the last frame that it played
I have a problem when I execute VideoPlayer.Stop. It keeps the last frame that played. That is by design according to the scripting documentation. I tried videoPlayer.frame = 0; but it’s not working.
Hey all! I saved the first frame of the video as an Texture2D and used ‘Graphics.Blit(firstFrameTexture, videoRenderTexture)’ to basically reset the render texture before I call VideoPlayer.Play.
When you call ‘VideoPlayer.Stop’ it doesn’t clear the render texture, which means once you start it again, it shows the last frame.
edit:
Using RenderTexture.DiscardContents did not seem to do the trick, neither does VideoPlayer.frame.
Can anyone from Unity comment on why this doesn’t work? It’s very annoying. Seems like a bug.
I currently use this when hiding my video ready for the next time
renderTexture.DiscardContents();
Graphics.Blit(firstFrameTexture, renderTexture);
but it relies on having a bitmap of the first frame (which I guess you could get from the video at startup etc)
you could maybe use this technique
I got this to go away by using GL.Clear on the Video Player’s awake.
RenderTexture.active = videoplayer.targetTexture;
GL.Clear(true, true, Color.black);
RenderTexture.active = null;
Changing the frame in the same method as we stop the player won’t allow it to render the next (zero) frame before stopping.
It would be enough to set videoPlayer.frame = 0; then yield return new WaitForEndOfFrame(); and then videoPlayer.stop();
well, so actually videoPlayer.frame = framenumber does not work at all?
Nope. Try my solution above, it worked for me.
Hi everyone
Thanks for all the useful help. I’ve been trying all the proposed solutions, but in my case it’s been a pain in the neck.
I’m not trying to obtain the 0 frame. My code needs to get an specific frame that it’s not the current frame played by the videoplayer. For example, I could have a video from 0 to 500 frames, the current frame being 455 and I would need to obtain the renderTexture from frame 200. This last frame can change depending on player’s decisions.
For this I’m following the next approach:
But, I’m still dealing with the issue that the renderTarget it is still not getting updated on this frame.
The only solution that I’ve found this far is to add a yield return new WaitForFrames(numberOfFrames) after the videoplayer2.started has began.
private void VideoPlayer_started(VideoPlayer source)
{
StartCoroutine(WaitForFramesAndCopyRenderTexture(20, source));
}
private IEnumerator WaitForFramesAndCopyRenderTexture(int frames, VideoPlayer source)
{
// Videoplayer has a delay until it renders the targetTexture, we need to wait until it's done
yield return new WaitForFrames(frames);
source.Pause();
var renderTexture = source.targetTexture;
var copy = new RenderTexture(renderTexture);
Graphics.CopyTexture(renderTexture, copy);
}
But this is awful. Depending on the hardware, this could take more frames to render the texture. Is there actually no other solution for this?
Thanks, help is appreciated.
videoPlayer.targetTexture.Release();
This code might work.
Nothing here has worked for me, as some videos were still locking up the render texture after VideoPlayer
stops playing them. But surprisingly, calling Stop()
right after it stops the video playback did the trick.
Nonsense or not, I noticed calling Stop()
anytime before the end always worked fine, so I thought the method internally may do its cleaning magic.
Oh, I’m (still) using Unity 2019.1.3 around here.
videoPlayer.targetTexture.Release(); worked fine for me.
videoPlayer.Stop() didn’t worked. My unity version is 2018.4.8f1