有没有人对Unity的视频播放器组件有任何解决方案?
基本上我有一个半交互式应用程序,可以在发生某些事情时背靠背播放一系列视频。问题是,一旦第一个视频结束,就会有一个很好的3-5秒间隙,因为第二个视频需要加载时间,但这在我的应用程序中看起来不太好。
我需要一种方法来预加载第二个视频(理想)或一种隐藏间隙的相当简单的方法(如顶部的静止帧)。我应该提到后一种想法,视频显示为球形。
using UnityEngine;
using UnityEngine.Video;
public class selectAndPlay_video : MonoBehaviour {
public VideoPlayer videoPlayer;
public VideoClip NewClip;
void OnEnable()
{
videoPlayer.loopPointReached += loopPointReached;
}
void OnDisable()
{
videoPlayer.loopPointReached -= loopPointReached;
}
void loopPointReached(VideoPlayer v)
{
videoPlayer.clip = NewClip;
videoPlayer.Play();
}
}
答案 0 :(得分:3)
解决此问题的关键是VideoPlayer.Prepare()
函数,VideoPlayer.time
和VideoPlayer.clip.length
属性。首先,我建议您忘记当前用于播放事件视频的方式。在this问题的示例中使用协同程序,因为下面的答案中的所有内容都假定您处于协程函数中。以下是如何在没有漫长等待的情况下播放不同的视频:
1 。有要播放的VideoClip
数组/列表。
2 。在#1 中的VideoPlayer
数组中创建VideoClip
的新列表。只需使用#1 中的VideoPlayer.clip
设置VideoClips
属性。
3 。拨打VideoPlayer.Prepare()
以准备列表中的第一个 VideoPlayer
,然后等待while
循环直到准备已完成或VideoPlayer.isPrepared
变为true
。
4 。拨打VideoPlayer.Play()
来播放您刚刚准备好的视频#3 。
无缝连续播放不同的视频
这是最重要的部分。
播放视频时,请检查正在播放的VideoPlayer
的当前时间是否为视频长度的一半。如果是一半,请在阵列中的下一个视频上拨打VideoPlayer.Prepare()
,然后在播放下一个视频之前等待#4 的视频完成播放。
通过执行此操作,下一个视频将在当前视频仍在播放时开始准备,并且准备过程应在当前视频播放完毕时完成。然后,您可以播放下一个视频,而无需等待它长时间加载。
5 。等待#4 的视频完成while
循环播放,直到VideoPlayer.isPlaying
变为false
。< / p>
6 。在#5 中的while
循环内等待,请检查视频是否已在if (videoPlayerList[videoIndex].time >= (videoPlayerList[videoIndex].clip.length / 2))
中途播放。如果是这样,请在列表中的下一个VideoPlayer.Prepare()
上致电VideoPlayer
以使其保持就绪状态。
7 。存在while
循环后,当前视频已完成播放。播放列表中的下一个VideoPlayer
,然后再次从#5 重复以准备列表中的下一个VideoPlayer
。
下面的脚本应该完成我上面描述的所有内容。只需创建一个RawImage
并将其插入图像插槽即可。您的所有视频也都是videoClipList
变量。它应该一个接一个地播放视频而不需要很长的加载时间。 Debug.Log
价格昂贵,因此一旦您确认其工作正常,请将其删除。
//Raw Image to Show Video Images [Assign from the Editor]
public RawImage image;
//Set from the Editor
public List<VideoClip> videoClipList;
private List<VideoPlayer> videoPlayerList;
private int videoIndex = 0;
void Start()
{
StartCoroutine(playVideo());
}
IEnumerator playVideo(bool firstRun = true)
{
if (videoClipList == null || videoClipList.Count <= 0)
{
Debug.LogError("Assign VideoClips from the Editor");
yield break;
}
//Init videoPlayerList first time this function is called
if (firstRun)
{
videoPlayerList = new List<VideoPlayer>();
for (int i = 0; i < videoClipList.Count; i++)
{
//Create new Object to hold the Video and the sound then make it a child of this object
GameObject vidHolder = new GameObject("VP" + i);
vidHolder.transform.SetParent(transform);
//Add VideoPlayer to the GameObject
VideoPlayer videoPlayer = vidHolder.AddComponent<VideoPlayer>();
videoPlayerList.Add(videoPlayer);
//Add AudioSource to the GameObject
AudioSource audioSource = vidHolder.AddComponent<AudioSource>();
//Disable Play on Awake for both Video and Audio
videoPlayer.playOnAwake = false;
audioSource.playOnAwake = false;
//We want to play from video clip not from url
videoPlayer.source = VideoSource.VideoClip;
//Set Audio Output to AudioSource
videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
//Assign the Audio from Video to AudioSource to be played
videoPlayer.EnableAudioTrack(0, true);
videoPlayer.SetTargetAudioSource(0, audioSource);
//Set video Clip To Play
videoPlayer.clip = videoClipList[i];
}
}
//Make sure that the NEXT VideoPlayer index is valid
if (videoIndex >= videoPlayerList.Count)
yield break;
//Prepare video
videoPlayerList[videoIndex].Prepare();
//Wait until this video is prepared
while (!videoPlayerList[videoIndex].isPrepared)
{
Debug.Log("Preparing Index: " + videoIndex);
yield return null;
}
Debug.LogWarning("Done Preparing current Video Index: " + videoIndex);
//Assign the Texture from Video to RawImage to be displayed
image.texture = videoPlayerList[videoIndex].texture;
//Play first video
videoPlayerList[videoIndex].Play();
//Wait while the current video is playing
bool reachedHalfWay = false;
int nextIndex = (videoIndex + 1);
while (videoPlayerList[videoIndex].isPlaying)
{
Debug.Log("Playing time: " + videoPlayerList[videoIndex].time + " INDEX: " + videoIndex);
//(Check if we have reached half way)
if (!reachedHalfWay && videoPlayerList[videoIndex].time >= (videoPlayerList[videoIndex].clip.length / 2))
{
reachedHalfWay = true; //Set to true so that we don't evaluate this again
//Make sure that the NEXT VideoPlayer index is valid. Othereise Exit since this is the end
if (nextIndex >= videoPlayerList.Count)
{
Debug.LogWarning("End of All Videos: " + videoIndex);
yield break;
}
//Prepare the NEXT video
Debug.LogWarning("Ready to Prepare NEXT Video Index: " + nextIndex);
videoPlayerList[nextIndex].Prepare();
}
yield return null;
}
Debug.Log("Done Playing current Video Index: " + videoIndex);
//Wait until NEXT video is prepared
while (!videoPlayerList[nextIndex].isPrepared)
{
Debug.Log("Preparing NEXT Video Index: " + nextIndex);
yield return null;
}
Debug.LogWarning("Done Preparing NEXT Video Index: " + videoIndex);
//Increment Video index
videoIndex++;
//Play next prepared video. Pass false to it so that some codes are not executed at-all
StartCoroutine(playVideo(false));
}