寫在前邊
在做公司項目時,需要播放一個視頻,但是由於發佈平臺爲Web,所以使用默認的VideoPlayer來實現的話,會導致播放失敗,下面來講解一下我的實現方法。免插件,直接導入項目即可使用。可快進,後退,暫停,支持大視頻播放,加載快速,播放快進無卡頓
關於webgl項目運行問題,請移步Unity發佈WebGL運行問題。
正文
創建UI界面
本人實現方法還是基於VideoPlayer組件,所以首先創建UI組件VideoPanel,搭建播放器UI。如下圖所示,請忽略博主沒有審美的UI。
VideoImage:播放視頻Image組件,由RawImage組件和VideoPlayer組件組成。並創建RenderTexture賦予VideoPlayer組件中TargetTexture屬性與RawImage組件中Texture屬性。並將VideoPlayer組件中Source屬性設置爲URL。
Slider:視頻進度條。
PlayerBtn/PauseBtn:播放/暫停按鈕。
視頻處理
對於發佈WebGL平臺,需要將視頻資源轉換爲ovg格式,使用ogv是由於WebGL平臺不支持mp4格式,並且ogv格式支持大視頻播放,博主使用該方法播放100多M的視頻,依然播放順暢。
分享一下視頻轉換工具,具體使用方法還請自己研究。
視頻轉換工具GitHub地址:https://github.com/WhoWhenLone/Mp4ToOgv
創建StreamingAssets文件夾,將視頻資源放在該文件夾下。
添加播放控制器腳本
將該腳本添加到VideoPanel下,並將組件拖拽賦值。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class VideoController : MonoBehaviour
{
//視頻名稱
public string videoName;
//videoImage組件
public GameObject VideoImage;
//進度條組件
public GameObject SliderController;
//播放按鈕
public GameObject PlayBtn;
//暫停按鈕
public GameObject PauseBtn;
//public GameObject CenterPlayBtn;
//視頻紋理
public RenderTexture renderTexture;
//視頻第一幀
public GameObject FirstFrameImage;
//視頻時長
public float Length;
//
private bool isDrag = false;
// Use this for initialization
private void Awake()
{
InitVideo(renderTexture);
}
void Start()
{
#region 註冊事件
PlayBtn.GetComponent<Button>().onClick.AddListener(PlayVideo);
//CenterPlayBtn.GetComponent<Button>().onClick.AddListener(PlayVideo);
PauseBtn.GetComponent<Button>().onClick.AddListener(PauseVideo);
AddTriggersListener(SliderController, EventTriggerType.BeginDrag, OnBeginDrag);
AddTriggersListener(SliderController, EventTriggerType.EndDrag, OnEndDrag);
#endregion
}
// Update is called once per frame
void Update()
{
ChangeSliderValue();
ChangeVideoPlayTime();
Debug.Log("Isdrag" + isDrag);
if (!gameObject.GetComponentInChildren<VideoPlayer>().isPlaying)
{
PauseVideo();
}
}
/// <summary>
/// 初始化視頻控制器
/// </summary>
public void InitVideoController()
{
PlayBtn.SetActive(true);
//CenterPlayBtn.SetActive(true);
PauseBtn.SetActive(false);
PauseVideo();
}
/// <summary>
/// 初始化videoplayer
/// </summary>
public void InitVideo(RenderTexture renderTexture)
{
DestroyImmediate(gameObject.transform.Find("VideoImage").gameObject.GetComponent<VideoPlayer>());
gameObject.transform.Find("VideoImage").gameObject.AddComponent<VideoPlayer>();
VideoPlayer videoPlayer = gameObject.GetComponentInChildren<VideoPlayer>();
videoPlayer.source = VideoSource.Url;
videoPlayer.renderMode = VideoRenderMode.RenderTexture;
videoPlayer.playOnAwake = false;
videoPlayer.targetTexture = renderTexture;
//適配平臺
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
videoPlayer.url = Application.dataPath + "/StreamingAssets/Video/" + videoName + ".ogv";
}
else if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor)
{
videoPlayer.url = Application.dataPath + "/StreamingAssets/Video/" + videoName + ".mp4";
}
videoPlayer.audioOutputMode = VideoAudioOutputMode.None;
videoPlayer.Prepare();
//設置slider 長度
SliderController.GetComponent<Slider>().maxValue = Length;
if (FirstFrameImage != null)
{
FirstFrameImage.SetActive(true);
}
PauseVideo();
}
/// <summary>
/// 播放
/// </summary>
private void PlayVideo()
{
gameObject.GetComponentInChildren<VideoPlayer>().Play();
PlayBtn.SetActive(false);
//CenterPlayBtn.SetActive(false);
PauseBtn.SetActive(true);
if (FirstFrameImage != null)
{
FirstFrameImage.SetActive(false);
}
}
/// <summary>
/// 暫停
/// </summary>
public void PauseVideo()
{
gameObject.GetComponentInChildren<VideoPlayer>().Pause();
PlayBtn.SetActive(true);
//CenterPlayBtn.SetActive(true);
PauseBtn.SetActive(false);
FirstFrameImage.SetActive(true);
}
/// <summary>
/// 修改視頻播放進度
/// </summary>
private void ChangeVideoPlayTime()
{
if (isDrag == true)
{
gameObject.transform.Find("VideoImage").gameObject.GetComponent<VideoPlayer>().time = SliderController.GetComponent<Slider>().value;
}
}
/// <summary>
/// 修改進度條
/// </summary>
private void ChangeSliderValue()
{
if (!isDrag)
{
SliderController.GetComponent<Slider>().value = (float)gameObject.transform.Find("VideoImage").gameObject.GetComponent<VideoPlayer>().time;
}
}
/// <summary>
/// 開始拖拽
/// </summary>
/// <param name="enenvt"></param>
private void OnBeginDrag(BaseEventData enenvt)
{
isDrag = true;
}
/// <summary>
/// 結束拖拽
/// </summary>
/// <param name="enenvt"></param>
private void OnEndDrag(BaseEventData enenvt)
{
isDrag = false;
gameObject.transform.Find("VideoImage").gameObject.GetComponent<VideoPlayer>().time = SliderController.GetComponent<Slider>().value;
}
/// <summary>
/// 爲obj添加Eventrigger監聽事件
/// </summary>
/// <param name="obj">添加監聽的對象</param>
/// <param name="eventID">添加的監聽類型</param>
/// <param name="action">觸發的函數</param>
private void AddTriggersListener(GameObject obj, EventTriggerType eventType, UnityAction<BaseEventData> action)
{
//首先判斷對象是否已經有EventTrigger組件,若沒有那麼需要添加
EventTrigger trigger = obj.GetComponent<EventTrigger>();
if (trigger == null)
{
trigger = obj.AddComponent<EventTrigger>();
}
//實例化delegates
if (trigger.triggers.Count == 0)
{
trigger.triggers = new List<EventTrigger.Entry>();//
}
//定義所要綁定的事件類型
EventTrigger.Entry entry = new EventTrigger.Entry();
//設置事件類型
entry.eventID = eventType;
//定義回調函數
UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(action);
//設置回調函數
entry.callback.AddListener(callback);
//添加事件觸發記錄到GameObject的事件觸發組件
trigger.triggers.Add(entry);
}
}
最後
案例GitHub地址:https://github.com/WhoWhenLone/UnityComponent/tree/master/VedioPlayerForWeb
至此,便實現了適配WebGL平臺下視頻播放器。建議在使用時,導爲Prefab,導出爲UnityPackage資源,方便在不同項目中直接使用。