Unity 2020.3.8f1, have set up an Empty with a VideoPlayer component that renders to a texture, texture is then shown in a RawImage on a Canvas.
Video is set to automatically start playing.
I need to keep the video synched with a datalog that I playback in realtime, so I check for a gap between datalog playback and video playback, and want to set the video playhead where it needs to be.
If I simply avoid interacting with the video by code (only reading from it), all is good and dandy.
If I try to set either VideoPlayer.frame or VideoPlayer.time, the video stops (both visual and audio).
VideoPlayer.Play() won’t do anything.
VideoPlayer.isPlaying will keep returning true, even if it’s a horrible lie.
Any thoughts on how to fix this?
Are you sure that the time / frame is available in the video?
You may also need to call Pause first then set the frame/time.
I would try disabling the automatically start playing, you call Play manually, maybe after you set the frame/time.
The video player definitely has a few strange quirks.
Thanks for the reply.
Yes I am setting either an existing frame or a time within the duration of the video.
I have tried using .Pause() then setting either frame or time, then calling .Play(). In this case the video will move to the requested point but will still not play.
I will try doing away with autoplay.
Is there a way to go around the arguably very buggy video player to… play a video?
There are some events you can hook into as well, like if the video ends and if it is preparing. You may want to check if the video is prepared first, then do your frame manipulations after its prepared:
private void Start(){
VideoPlayer vp = GetComponent<VideoPlayer>();
vp.loopPointReached += CheckOver;
vp.Prepare();
vp.prepareCompleted += CheckPrepared;
StartCoroutine(StartVideo(vp));
}
private IEnumerator StartVideo(VideoPlayer target){
while(!target.isPrepared){
// Debug.Log("loading / buffering");
}
yield return null;
}
target.Play();
}
private void CheckPrepared(VideoPlayer vp){
vp.prepareCompleted -= CheckPrepared;
//Debug.Log("<color=yellow>" + vp.clip.name + "</color>" + " is prepared!");
}
private void CheckOver(VideoPlayer vp){
vp.loopPointReached -= CheckOver;
//Debug.Log("video has ended");
}
Are your videos coming from a URL?
You may have to also set the VideoPlayer component bools to true for Wait For First Frame and Skip On Drop. That is ringing a bell for me too. I did a client job a few years ago that basically spins up video players on the fly and keeps them all synced up with audio and video, so it’s been a while since I dove into the inner workings, but I definitely remember having some major growing pains regarding the video player component.
Also you may have to type cast the time/frame values. I think time should be a double and frame should be a long