本次Demo演示工具介绍:Unity版本:2020.3.25,Visual Studio版本: 2020;
1:使用Unity新建一个工程,新建空场景并保存,然后在Project面板下新建几个文件夹:Res,Resources,Scence,Scripts,此三个文件夹放一个根目录VideoPlayerDemo,目录如下;这是我的习惯,大家随意;
2:Res文件夹下创建一个Render Texture,Hierarchy面板下创建一个画布,再创建RawImage,相机设置为纯色渲染,Projection设置为Orthographic模式,画布设置ScreenSpace_Camera模式,并将主相机赋值给画布的渲染相机,RawImage设置为随画布拉伸的方式,锚点的右下角那个点一下;
3:新建一个面板Controller,将再该面板中编写相关播放控制功能;Slider-进度条,Dropdown-播放速度,两个Text文本设置播放时间,还有个播放按钮。
4:新建类VideoController挂载到控制面板上;
/// <summary>
/// 绑定拖拽功能
/// </summary>
/// <param name="obj"></param>
/// <param name="eventID"></param>
/// <param name="action"></param>
public static void AddTriggersListener(GameObject obj, EventTriggerType eventID, UnityAction<BaseEventData> action)
{
EventTrigger trigger = obj.GetComponent<EventTrigger>();
if (trigger == null)
{
trigger = obj.AddComponent<EventTrigger>();
}
if (trigger.triggers.Count == 0)
{
trigger.triggers = new List<EventTrigger.Entry>();
}
UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(action);
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = eventID;
entry.callback.AddListener(callback);
trigger.triggers.Add(entry);
}
public class VideoController : MonoBehaviour
{
private Slider slider;
private Text totleTimer;
private Text culTimer;
private Dropdown speedValue;
private Button playbtn;
private Sprite PlaySP;
private Sprite PuaseSP;
bool isPause = false;
private VideoPlayer video;
private void Awake()
{
slider =Config<Slider>.GetComponent(transform, "ProsseSlider");
speedValue = Config<Dropdown>.GetComponent(transform, "SpeedDropdown");
totleTimer = Config<Text>.GetComponent(transform, "TotleTimer");
culTimer = Config<Text>.GetComponent(transform, "CulTimer");
playbtn = Config<Button>.GetComponent(transform, "PlayeBtn");
PlaySP= Resources.Load<Sprite>("UITexture/播放");
PuaseSP = Resources.Load<Sprite>("UITexture/暂停");
video = Config<VideoPlayer>.GetComponent(transform.parent, "VideoPlayer");
speedValue.onValueChanged.AddListener(DropdownOnClick);
}
private void DropdownOnClick(int arg0)
{
var value =float.Parse( speedValue.options[arg0].text.Replace("倍速 x ", ""));
video.playbackSpeed = value;
}
// Start is called before the first frame update
void Start()
{
playbtn.GetComponent<Image>().sprite = PuaseSP;
//视频播放结束事件
video.loopPointReached += EndWithVideoPlay;
//播放按钮监听
playbtn.onClick.AddListener(PlayBtnOnClick);
//添加Slider拖拽事件
Utils.AddTriggersListener(slider.gameObject, EventTriggerType.Drag, OnDrag);
}
private void OnDrag(BaseEventData arg0)
{
//踩坑记: 强制转换 long 的时候先将算法算出来之后得到float类型,然后再将结果强转,直接算法强转结果一直为0;
float tatol = slider.value * video.frameCount;
video.frame = (long)tatol;
}
/// <summary>
/// 清除上一帧渲染
/// </summary>
private void RemoveTargetframe()
{
video.targetTexture.Release();
video.targetTexture.MarkRestoreExpected();
}
/// <summary>
/// 显示当前视频的时间
/// </summary>
private void ShowVideoTime()
{
try
{
if (video != null && video.isPlaying)
{
//视频帧率 每秒多少帧;
float frameRate = video.frameRate;
int clipHour = (int)((float)video.frameCount / frameRate / (float)3600);
int clipMinute = (int)((float)video.frameCount / frameRate - (float)clipHour * (float)3600) / 60;
int clipSecond = (int)((float)video.frameCount / frameRate - (float)clipHour * (float)3600 - (float)clipMinute * (float)60);
// 当前的视频播放时间
int currentHour = (int)video.time / 3600;
int currentMinute = (int)(video.time - currentHour * 3600) / 60;
int currentSecond = (int)(video.time - currentHour * 3600 - currentMinute * 60);
string culTime = string.Format("{0:D2}:{1:D2}:{2:D2}", currentHour, currentMinute, currentSecond);
string totalTime = string.Format("{0:D2}:{1:D2}:{2:D2}", clipHour, clipMinute, clipSecond);
culTimer.text = culTime;
totleTimer.text = totalTime;
slider.value = (float)video.frame / (float)video.frameCount;
}
}
catch (Exception e)
{
print(e.Message);
}
}
private void PlayBtnOnClick()
{
isPause = isPause ? false : true;
playbtn.GetComponent<Image>().sprite = isPause ? PlaySP : PuaseSP;
if (isPause)
video.Pause();
else
video.Play();
}
private void EndWithVideoPlay(VideoPlayer source)
{
print("视频播放结束");
}
// Update is called once per frame
void Update()
{
ShowVideoTime();
}
}
虽然该有的功能都有,但还是建议大家使用AVPRO插件,个人觉得它比较友好,支持webgl,官方的api我使用在webgl的时候发现老是黑屏,播放不了的情况。AVPRO解决了我的问题。
最后看效果吧: