See this:
for (i = 0; i < 10; i++) {
vp.playbackSpeed = vp.playbackSpeed / i;
}
You are doing all those in one frame therefore won't be able to see the effect. Move that to a coroutine function then yield after each for loop then you will see the effect.
Something like this:
for (i = 0; i < 10; i++) {
vp.playbackSpeed = vp.playbackSpeed / i;
yield return null; //Wait for a frame
//OR
yield return new WaitForSeconds(0.1f); //Wait for 0.1 sec
}
You should now see the effect of that code but it will not be smooth.
What to do:
The lerp functions are usually used for something like this. Mathf.Lerp
is appropriate for this one.
The default/normal value of VideoPlayer.playbackSpeed
is 1
. The value of 2
is faster and 0
is slower.
- When you want to pause the
VideoPlayer
, lerp from 1
to 0
to
slow it down then pause it.
- When you want to resume the
VideoPlayer
, resume it slowly then lerp from 0
to 1
.
Here are the two coroutines functions that should handle the pause and resume functionality slowly and smoothly.
IEnumerator SmoothlyPauseOverTimeCOR(VideoPlayer targetVp, float duration)
{
float counter = 0;
//Get the current playbackSpeed of the VideoPlayer
float startSpeed = targetVp.playbackSpeed;
//We want to go to 0 but within duration
float endSpeed = 0;
//Normal speed to slow speed
while (counter < duration)
{
counter += Time.deltaTime;
targetVp.playbackSpeed = Mathf.Lerp(startSpeed, endSpeed, counter / duration);
yield return null;
}
//Now, do the actual pause
targetVp.Pause();
executingPause = false;
}
IEnumerator SmoothlyResumeOverTimeCOR(VideoPlayer targetVp, float duration)
{
float counter = 0;
//Get the current playbackSpeed of the VideoPlayer
//float startSpeed = targetVp.playbackSpeed;
float startSpeed = 0f;
//We want to go to 1 but within duration
float endSpeed = 1;
//Do the actual resume
targetVp.Play();
//Slow speed to normal Speed
while (counter < duration)
{
counter += Time.deltaTime;
targetVp.playbackSpeed = Mathf.Lerp(startSpeed, endSpeed, counter / duration);
yield return null;
}
}
You need to make sure that the previous coroutine function is not running before starting a new one. Stop the old one then start a new one when needed. The two functions below should handle that and be able to safely call the functions above:
Coroutine pauseCoroutine;
Coroutine resumeCoroutine;
bool executingPause = false;
void SmoothlyPauseOverTime(VideoPlayer targetVp, float duration)
{
//Stop old coroutines before starting a new one
if (pauseCoroutine != null)
StopCoroutine(pauseCoroutine);
if (resumeCoroutine != null)
StopCoroutine(resumeCoroutine);
executingPause = true;
pauseCoroutine = StartCoroutine(SmoothlyPauseOverTimeCOR(targetVp, duration));
}
void SmoothlyResumeOverTime(VideoPlayer targetVp, float duration)
{
if (pauseCoroutine != null)
StopCoroutine(pauseCoroutine);
//Stop old coroutines before starting a new one
if (resumeCoroutine != null)
StopCoroutine(resumeCoroutine);
resumeCoroutine = StartCoroutine(SmoothlyResumeOverTimeCOR(targetVp, duration));
}
Your Update
function:
void Update()
{
if (Input.GetButton("Jump"))
{
if (!vp.isPlaying)
{
Debug.Log("Resumed Playing");
SmoothlyResumeOverTime(vp, 0.8f);
}
}
else
{
if (!executingPause && vp.isPlaying)
{
Debug.Log("Paused Playing");
SmoothlyPauseOverTime(vp, 0.8f);
}
}
}
Your Start
function:
Based on this. It prepares the video but does not play it until Space key is pressed in the Update
function above:
//Raw Image to Show Video Images [Assign from the Editor]
public RawImage image;
//Video To Play [Assign from the Editor]
public VideoClip videoToPlay;
private VideoPlayer vp;
private VideoSource videoSource;
//Audio
private AudioSource aS;
// Use this for initialization
void Start()
{
Application.runInBackground = true;
StartCoroutine(playVideo());
}
IEnumerator playVideo()
{
//Add VideoPlayer to the GameObject
vp = gameObject.AddComponent<VideoPlayer>();
//Add AudioSource
aS = gameObject.AddComponent<AudioSource>();
//Disable Play on Awake for both Video and Audio
vp.playOnAwake = false;
aS.playOnAwake = false;
//We want to play from video clip not from url
vp.source = VideoSource.VideoClip;
//Set Audio Output to AudioSource
vp.audioOutputMode = VideoAudioOutputMode.AudioSource;
//Assign the Audio from Video to AudioSource to be played
vp.EnableAudioTrack(0, true);
vp.SetTargetAudioSource(0, aS);
//Set video To Play then prepare Audio to prevent Buffering
vp.clip = videoToPlay;
vp.Prepare();
//Wait until video is prepared
while (!vp.isPrepared)
{
Debug.Log("Preparing Video");
yield return null;
}
Debug.Log("Done Preparing Video");
//Assign the Texture from Video to RawImage to be displayed
image.texture = vp.texture;
}
Usage:
public VideoPlayer vp;
.....
Will pause slowly within 0.8 second
SmoothlyPauseOverTime(vp, 0.8f);
Will resume slowly within 0.8 second
SmoothlyResumeOverTime(vp, 0.8f);