ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Unity播放网络视频

2026/8/14 18:30:01 拓冰建站 浏览量
Unity播放网络视频

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mx.UI;
using Mx.Utils;
using UnityEngine.UI;
using UnityEngine.Video;

/// <summary> 视频UI面板 </summary>
public class VideoUIForm : BaseUIForm
{
    private ImageAdaptive imageAdaptive;
    private RawImage rawImage;
    private VideoPlayer videoPlayer;
    private bool isPlaying = false;
    private Slider slider;
    private Text playTimeText;
    private Text lengthText;
    private GameObject playButtonGo;
    private GameObject playIconGo;
    private GameObject pauseIconGo;
    private bool sliderIsDrag = false;

    private float playTime;
    private float length;

    public override void OnAwake()
    {
        base.OnAwake();

        init();

        rigisterButtonEvent();
    }

    private void init()
    {
        slider = UnityHelper.FindTheChildNode(gameObject, "Slider").GetComponent<Slider>();
        rawImage = UnityHelper.FindTheChildNode(gameObject, "Stage").GetComponent<RawImage>();
        rawImage.enabled = false;
        videoPlayer = rawImage.gameObject.GetComponent<VideoPlayer>();
        if (videoPlayer == null) videoPlayer = rawImage.gameObject.AddComponent<VideoPlayer>();
        playTimeText = UnityHelper.FindTheChildNode(gameObject, "PlayTime").GetComponent<Text>();
        lengthText = UnityHelper.FindTheChildNode(gameObject, "Length").GetComponent<Text>();
        playButtonGo = UnityHelper.FindTheChildNode(gameObject, "BtnPlay").gameObject;
        playIconGo = UnityHelper.FindTheChildNode(gameObject, "PlayIcon").gameObject;
        pauseIconGo = UnityHelper.FindTheChildNode(gameObject, "PauseIcon").gameObject;

        imageAdaptive = rawImage.GetComponent<ImageAdaptive>();
        if (imageAdaptive == null) imageAdaptive = rawImage.gameObject.AddComponent<ImageAdaptive>();

        videoPlayer.playOnAwake = false; // 设置不自动播放
        videoPlayer.waitForFirstFrame = true; // 等待第一帧加载完成再显示
        videoPlayer.source = VideoSource.Url;
        videoPlayer.aspectRatio = VideoAspectRatio.FitVertically;

        videoPlayer.prepareCompleted += onVideoPrepared; // 视频加载完成事件
        videoPlayer.loopPointReached += onVideoEnd; // 视频播放完成事件

        playIconGo.SetActive(true);
        pauseIconGo.SetActive(false);

        initFinish = true;
    }

    void Update()
    {
        if (!sliderIsDrag)
        {
            float progress = (float)videoPlayer.time / (float)videoPlayer.length;
            if (progress > 0) slider.value = progress;
            length = (float)videoPlayer.length;
            lengthText.text = formatTime(length);
        }

        playTime = (float)videoPlayer.time;
        playTimeText.text = formatTime(playTime);
        playButtonGo.SetActive(!isPlaying);
        playIconGo.SetActive(!isPlaying);
        pauseIconGo.SetActive(isPlaying);
    }

    /// <summary>关闭UI窗口事件</summary>
    public override void OnCloseUIEvent()
    {
        base.OnCloseUIEvent();

        clearData();
    }

    public override void OnUIMsgEvent(string key, object values)
    {
        base.OnUIMsgEvent(key, values);

        switch (key)
        {
            case MsgDefine.UPDATE_PANEL_DATA:
                if (values != null)
                {
                    if (initFinish)
                    {
                        rawImage.enabled = false;

                        string path = (string)values;
                        string encodedUrl = System.Uri.EscapeUriString(path);
                        videoPlayer.url = encodedUrl;
                        videoPlayer.Play();
                        isPlaying = true;

                    }
                }
                break;
        }

    }

    /// <summary>注册按钮事件</summary>
    private void rigisterButtonEvent()
    {
        RigisterButtonEvent("BtnClose", (clickObj) => { CloseCurrentUIForm(); });
        RigisterButtonEvent("BtnPlayAndPause", (clickObj) => { PlayPauseVideo(); });
        RigisterButtonEvent("BtnPlay", (clickObj) =>
        {
            videoPlayer.Play();
            isPlaying = true;
        });
    }

    /// <summary>进度条拖动发送改变</summary>
    public void OnSliderDragChange(bool isDrag)
    {
        sliderIsDrag = isDrag;
    }

    /// <summary>清理数据</summary>
    private void clearData()
    {
        if (!initFinish) return;

        isPlaying = false;
        slider.value = 0;
        playTimeText.text = "00:00";
        lengthText.text = "00:00";
        playButtonGo.SetActive(true);
        playIconGo.SetActive(true);
        pauseIconGo.SetActive(false);
        sliderIsDrag = false;
    }

    /// <summary>视频准备完成</summary>
    private void onVideoPrepared(VideoPlayer source)
    {
        rawImage.texture = source.texture;
        source.Play();
        rawImage.enabled = true;
        isPlaying = true;

        // 获取视频的宽度和高度
        uint width = source.width;
        uint height = source.height;

        RectTransform parentRect = transform.parent.GetComponent<RectTransform>();
        if (parentRect != null)
        {
            imageAdaptive.BoundarySize = new Vector2(parentRect.rect.width, parentRect.rect.height);
            imageAdaptive.ImageSize = new Vector2(width, height);
        }

    }

    /// <summary>视频播放结束</summary>
    private void onVideoEnd(VideoPlayer source)
    {
        source.Pause();
        isPlaying = false;
    }

    /// <summary>播放或者暂停视频</summary>
    public void PlayPauseVideo()
    {
        if (isPlaying)
        {
            videoPlayer.Pause();
            isPlaying = false;
        }
        else
        {
            videoPlayer.Play();
            isPlaying = true;
        }
    }

    /// <summary>设置视频播放进度</summary>
    public void setVideoProgress(float progress)
    {
        if (videoPlayer.canSetTime)
        {
            videoPlayer.time = videoPlayer.clip.length * progress;
        }
    }

    /// <summary>格式化时间</summary>
    private string formatTime(float time)
    {
        int minutes = Mathf.FloorToInt(time / 60f);
        int seconds = Mathf.FloorToInt(time % 60f);

        return string.Format("{0:00}:{1:00}", minutes, seconds);
    }
}