发代码之前补一下挖到的坑。
VideoPlayer 通过URL读取视频的时候,路径必须准确!如发现读取后Unity崩溃,基本就是读取的路径有问题。
补充1:
该代码不适合频繁切换和程序长时间运行,因为切换过程可能会存在内存泄露的问题(unity的锅),我后来找到处理方法,但是处理方法不太稳定,后续再补充填坑。
补充2:
这VideoPlayer组件真的有毒,解决内存溢出,然后发现切换视频有几率造成虚拟内存回收不了,并且Unity没有提供任何方法来处理,如果需要功能涉及自动切换视频以及需要长时间运行的。建议放弃研究。
【可能是我处理不当,毕竟我真查不到相关问题的信息,如果有大佬有处理方法,望不吝赐教】
【用的是2018,3.5 版本的unity , 2019仅测试过短时间内快速连续切换视频,长时间没测过】
补充3:
由于询问过很多人,他们没说没发生这种情况,所以如若你坚持使用没发现问题的话,可以忽略我以上的内容。
其实我觉得应该是大部分人没有进行长时间挂机验证。在任务管理器把提交大小显示出来,然后长时间运行VideoPlayer组件,并且进行切换视频,你会发现提交大小会随着时间变大,最终把虚拟内存撑爆(当然,不会马上出现撑爆,我自己挂了几个小视频进行切换也需要两天才把20G虚拟内存撑满)。
该代码之所以扔出来.. 看图
(稍作修改...修改后没再次运行测试)
代码就大概这样...找streamingAssets下的movies文件夹中的视频, 但只抓 具备命名规则的 如 A.mp4 B.mp4等
(可自行修改规则- 规则适宜ASCII码连续的字符 或直接拿数字)。
根据index标识直接抓取,每次只抓对应标号的视频名。
抓到后构成路径,通过URL在VideoPlayer中读取视频。
然后根据计时进行视频切换。
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Video;
public class VideoAutoPlayByName : MonoBehaviour
{
private VideoPlayer videoPlayer;
string folderName = "/Movie"; //文件夹名字
private string path = "";
public string[] likePaths;
private int beginIndexABC = (int)System.Text.ASCIIEncoding.ASCII.GetBytes("A")[0]; //ABC播放规则的索引值
public int endIndexABC = (int)System.Text.ASCIIEncoding.ASCII.GetBytes("Z")[0];
private int currentIndex = 0;
private float elapsedTime = 0; //消逝时间
public float durationTime = 30; //持续多少秒后更换视频
public bool isAuto = false; //是否开启自动更换视频
public bool defaultLooping = false; //是否默认循环播放
private void Start()
{
FindVideoPlayer();
InitPathString();
}
private void Update()
{
UpdateIndex();
}
private void InitPathString()
{
path = Application.streamingAssetsPath + folderName + "s/";
currentIndex = (int)System.Text.ASCIIEncoding.ASCII.GetBytes("A")[0];
likePaths = new string[endIndexABC - beginIndexABC + 1];
for (int i = 0; i < likePaths.Length; i++)
{
likePaths[i] = "* " + (char)(beginIndexABC + i) + ".mp4";
}
}
public void ReadMoviesByName()
{
//检索目录下的文件
DirectoryInfo directoryInfo = new DirectoryInfo(path);
FileInfo[] fileInfos = directoryInfo.GetFiles(likePaths[currentIndex - beginIndexABC]);
if (fileInfos.Length > 0)
SetVideoUrl(fileInfos[0].Name);
else
{
currentIndex++;
if (currentIndex > endIndexABC)
{
currentIndex = beginIndexABC;
}
ReadMoviesByName();
}
}
private void UpdateIndex()
{
if (isAuto && endIndexABC - beginIndexABC > 1)
{
elapsedTime += Time.deltaTime;
if (elapsedTime >= durationTime)
{
currentIndex++;
if (currentIndex > endIndexABC)
{
currentIndex = beginIndexABC;
}
ReadMoviesByName();
elapsedTime = 0;
}
}
}
//读取视频文件
private void SetVideoUrl(string videoName)
{
if (File.Exists(path + videoName))
{
videoPlayer.Stop();
videoPlayer.url = path + videoName;
videoPlayer.Play();
}
else
{
Debug.Log("文件不存在!!");
}
}
private void FindVideoPlayer()
{
videoPlayer = FindObjectOfType<VideoPlayer>();
if (videoPlayer == null)
{
Debug.LogError("缺少名为'Plane'背景板物体");
//自行创建 不创建就直接return了
return;
}
videoPlayer.isLooping = defaultLooping;
}
}