按下键时,使用Unity VideoPlayer缓慢暂停/恢复视频

时间:2018-01-13 13:43:31

标签: c# unity3d video-player

我正在编写一个脚本,其中有一个视频分为3个部分,分别有3个音频,在前一个完成后运行一个(视频和音频),但视频需要播放只有拿着一把钥匙(在我的情况下是"空间")我在按下空格时成功制作了视频和音频:

if (Input.GetButton ("Jump")) {
                vp.Play ();
                if (!ASource.isPlaying) {
                    ASource.Play ();
                }

暂停而不是:

else {
                vp.Pause ();
                ASource.Pause ();

            }

但它很难,我正在寻找一种让它顺利暂停/恢复的方法,我尝试制作一个功能:

public void videoPause() {
        for (i = 0; i < 10; i++) {
            vp.playbackSpeed = vp.playbackSpeed / i;
        }

    }

同样的简历,但有*而不是和i--但它没有工作,任何想法如何让它工作吗?

2 个答案:

答案 0 :(得分:0)

见:

for (i = 0; i < 10; i++) {
    vp.playbackSpeed = vp.playbackSpeed / i;
}

你正在一帧中完成所有这些,因此无法看到效果。将其移至协程函数,然后在每个for循环后生成,然后您将看到效果。

这样的事情:

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
}

您现在应该看到该代码的效果,但会顺利进行。

怎么做

lerp函数通常用于这样的事情。 Mathf.Lerp适用于此。

VideoPlayer.playbackSpeed的默认/正常值为12的值更快,0更慢。

  • 如果您要暂停VideoPlayer,请将10暂停到VideoPlayer 放慢速度然后暂停它。
  • 当您想要恢复0时,请慢慢恢复,然后从1翻译到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; } }

以下是两个协程函数,它们应该缓慢而平稳地处理暂停和恢复功能。

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));
}

在开始新的协程之前,您需要确保先前的协同程序功能未运行。停止旧的,然后在需要时开始新的。下面的两个函数应该处理它并能够安全地调用上面的函数:

Update

您的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); } } } 功能

Start

您的Update功能

基于this。它准备视频,但在上面的//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; } 函数中按下空格键之前不会播放它:

public VideoPlayer vp;

<强>用法

SmoothlyPauseOverTime(vp, 0.8f);

.....

将在0.8秒内缓慢暂停

SmoothlyResumeOverTime(vp, 0.8f);

将在0.8秒内缓慢恢复

sed -i '/y$/ {N; s/y\ny/ya\ny/; P; D}' a6s

答案 1 :(得分:0)

videoPause方法中的 for 循环会立即运行它,而不是按照您希望的方式运行。您可以尝试在一段时间内(例如5秒)更新更新方法中的播放速度。像这样的东西

// set when the pause is triggered
videoPauseTime = Time.realtimeSinceStartup;
// duration in seconds to smoothen the pause
duration = 5

public void Update() {
    float t = (Time.realtimeSinceStartup - videoPauseTime) / duration;
    if(t>1.0f)
        t = 1.0f;
    vp.playbackSpeed = Mathf.Lerp (vp.playbackSpeed,0.0f,t)
}

请注意,此代码仅供参考, t 将超出1.0,这是您不想要的;因此条件 t> 1.0F 即可。另外,我假设playbackSpeed为0使视频停止播放。