当前位置: 首页 > news >正文

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);
    }
}

相关文章:

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 …...

SCI一区级 | Matlab实现GWO-CNN-LSTM-selfAttention多变量多步时间序列预测

SCI一区级 | Matlab实现GWO-CNN-LSTM-selfAttention多变量多步时间序列预测 目录 SCI一区级 | Matlab实现GWO-CNN-LSTM-selfAttention多变量多步时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现GWO-CNN-LSTM-selfAttention灰狼算法优化卷积长短…...

线性分类器--图像表示

整个模型 图像表示 二进制图像 灰度图像 彩色图像 大多数分类算法都要求输入向量&#xff01; rbg的图像矩阵转列向量 大小为 32X32 的话&#xff0c;图像矩阵转列向量是多少维&#xff1f; 32x32x3 3072 维列向量...

车载通信架构 —— 传统车内通信网络FlexRay(较高速度高容错、较灵活拓扑结构)

车载通信架构 —— 传统车内通信网络FlexRay(较高速度高容错、较灵活拓扑结构) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,…...

如何在Ubuntu的Linux系统中安装MySQL5.7数据库

前往MySQL数据库官网链接地址下载5.7数据库。 MySQL :: Download MySQL Community Server (Archived Versions)使用ssh的可视化工具将下载的mysql-5.7.40-linux-glibc2.12-x86_64.tar.gz文件上传到Linux服务器&#xff0c;并解压文件 tar -zxvf mysql-5.7.40-linux-glibc2.12-x…...

基于Hadoop的区块链海量数据存储的设计与实现

点我完整下载&#xff1a;基于Hadoop的区块链海量数据存储的设计与实现.docx 基于Hadoop的区块链海量数据存储的设计与实现 Design and Implementation of Mass Data Storage for Blockchain based on Hadoop 目录 目录 2 摘要 3 关键词 4 第一章 引言 4 1.1 研究背景 4 1.2 研…...

运行时错误/缺陷到底是什么缺陷

运行时错误(Run-time Error)是一种跟程序运行状态相关的缺陷。这类缺陷不能通过直接禁用相关特性来屏蔽&#xff0c;而是需要通过分析变量的数值状态来发现可能的异常。简单来说&#xff0c;这些缺陷通常只有当程序执行起来以后&#xff0c;才能逐渐暴露出的缺陷&#xff0c;一…...

应用Web3.0的5种方法提升你的点击量

Web3.0早已成为互联网的全新方向标&#xff0c;为用户带来全新的手机上网感受。它也变成吸引住点击量疯涨的秘密武器。我们将要详细介绍Web3.0的五种使用方法&#xff0c;帮助你更好的了解并应用Web3.0技术性&#xff0c;以提升你的点击量。 1.可靠的身份认证Web3.0技术性提供了…...

计算机服务器中了mallox勒索病毒如何处理,mallox勒索病毒解密文件恢复

科技技术的发展推动了企业的生产运营&#xff0c;网络技术的不断应用&#xff0c;极大地方便了企业日常生产生活&#xff0c;但网络毕竟是一把双刃剑&#xff0c;网络安全威胁一直存在&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机…...

408—电子笔记分享

一、笔记下载 链接&#xff1a;https://pan.baidu.com/s/1bFz8IX6EkFMWTfY9ozvVpg?pwddeng 提取码&#xff1a;deng b站视频&#xff1a;408-计算机网络-笔记分享_哔哩哔哩_bilibili 包含了408四门科目&#xff08;数据结构、操作系统、计算机组成原理、计算机网络&#xff09…...

【每日一题】子数组的最小值之和

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;贡献法单调栈 写在最后 Tag 【贡献法】【单调栈】【数组】【2023-11-27】 题目来源 907. 子数组的最小值之和 题目解读 计算整数数组的连续子数组中最小值的和。 解题思路 本题朴素的解决思想是求出所有的连续子数组…...

【docker】docker总结

一、Docker简介 Docker是开源应用容器引擎&#xff0c;轻量级容器技术。基于Go语言&#xff0c;并遵循Apache2.0协议开源Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的Linux系统上&#xff0c;也可以实现虚拟化容…...

[英语学习][3][Word Power Made Easy]的精读与翻译优化

[序言] 这次翻译校验, 难度有点大, 原版中英翻译已出现了严重地偏差. 昨晚11点开始阅读如下段落, 花费了1个小时也没有理解原作者的核心表达, 索性睡觉了. 今早学习完朗文单词之后, 9点半开始继续揣摩. 竟然弄到了中午11点30, 终于明白原作者要表达的意思了. 废话不多说&#x…...

使用UIActivityViewController分享图片,没有preview

以前都是用第三方sdk来分享的&#xff0c;最近使用官方的UIActivityViewController来做分享&#xff0c;结果分享图片的时候preview不了分享的图片。 自定义一个继承UIActivityItemProvider的类。关于分享的内容自定义可以自己实现UIActivityItemSource这个协议。首先看看协议的…...

linux安装终端连接工具Tabby

参考&#xff1a;https://zhuanlan.zhihu.com/p/645787655...

Linux telnet命令详解:通过TCP/IP网络连接与管理远程机器(附实例教程和注意事项)

Linux telnet命令介绍 telnet命令&#xff0c;全称为teletype network&#xff0c;是一个使用telnet网络协议来连接并管理远程机器的命令。它通过TCP/IP网络使用端口23来建立连接&#xff0c;并提供了一种使用命令行界面&#xff08;CLI&#xff09;管理远程系统的方式。虽然t…...

linux 磁盘管理、分区管理常用命令

文章目录 基础命令挂载新硬盘/分区添加内存交换分区swaplvm分区管理模式 基础命令 查看目录文件大小 du -sh /backup du -sh /backup/* du -sh *查看磁盘挂载信息 df -lhT查看某个目录挂载在哪个分区&#xff0c;以及分区的磁盘使用情况 df [目录] #例如&#xff1a;df /ho…...

Milvus入门手册1.0

一、window环境搭建&#xff08;单机&#xff09; 1、docker安装 略 2、milvus安装 参考文档&#xff1a;https://milvus.io/docs/install_standalone-docker.md tips: &#xff08;1&#xff09;compose.yaml下载比较慢&#xff0c;可以在网络上找一份。 &#xff08;2&…...

PCL 计算两点云之间的最小距离

目录 一、 算法原理二、 代码实现三、 结果展示四、 相关链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、 算法原理 pcl::registration::CorrespondenceEstimation是确定目标和查询点集(或特征)之间对应关…...

基于YOLOv5的视频计数 — 汽车计数实现

在视频中计数对象可能看起来有挑战性&#xff0c;但借助Python和OpenCV的强大功能&#xff0c;变得令人意外地易于实现。在本文中&#xff0c;我们将探讨如何使用YOLO&#xff08;You Only Look Once&#xff09;目标检测模型在视频流或文件中计数对象。我们将该过程分解为简单…...

C# 如何实现对象序列化

在实现之前&#xff0c;先要做一些准备工作&#xff0c;序列化其实是对象和字符串&#xff08;文件&#xff09;之间的互相转换&#xff0c;所以首先我们准备好一个实体类&#xff0c;很简单的Person类&#xff1a;using System.Text.Json;public class Person {public string …...

我在选域名服务时,慢慢开始关注这3个点

在前面几篇里&#xff0c;我更多是在整理域名本身的问题。但最近在实际操作的时候&#xff0c;发现&#xff1a;&#x1f449; 选“在哪管理域名”&#xff0c;其实也挺重要的1. 一开始容易忽略的点最开始&#xff0c;我只是随便选了一个能用的方式。但后面才发现&#xff1a;&…...

MySQL锁机制:从全局锁到行级锁的深度解读颜

如果有多个供应商&#xff0c;你也可以使用 [[CC-Switch]] 来可视化管理这些API key&#xff0c;以及claude code 的skills。 # 多平台安装指令 curl -fsSL https://claude.ai/install.sh | bash ## Claude Code 配置 GLM Coding Plan curl -O "https://cdn.bigmodel.cn/i…...

JAVA找出哪个类import了不存在的类颜

一、中间件是啥&#xff1f;咱用“餐厅”打个比方 想象一下&#xff0c;你的FastAPI应用是个高级餐厅。 ?? 顾客&#xff08;客户端请求&#xff09;来到门口。- 迎宾&#xff08;CORS中间件&#xff09;&#xff1a;先看你是不是从允许的街区&#xff08;域名&#xff09;来…...

Llama-3.2-3B新手入门:用Ollama一键搭建你的本地AI助手

Llama-3.2-3B新手入门&#xff1a;用Ollama一键搭建你的本地AI助手 1. 为什么选择Llama-3.2-3B和Ollama组合 1.1 轻量级但实用的AI助手 Llama-3.2-3B是Meta最新推出的30亿参数语言模型&#xff0c;专为日常对话和多语言理解优化。相比其他同规模模型&#xff0c;它有三个突出…...

双膜气柜:生物质燃气存储的柔性恒压方案

在绿色发展与循环经济成为主流的当下&#xff0c;沼气等生物质燃气的高效、安全储存&#xff0c;是打通废弃物处理与清洁能源利用的关键纽带。双膜气柜作为柔性储气解决方案&#xff0c;凭借恒压稳定、防腐耐用、低维护等优势&#xff0c;已广泛应用于市政污水处理、农业沼气工…...

订阅号文章太干?AI 写作帮你提升可读性

几乎所有做内容的人&#xff0c;这两年都有同一个感受 文章越写越长&#xff0c;数据越加越多&#xff0c;阅读却越来越「干」。打开一篇订阅号文章&#xff0c;开头三段不是背景宏观&#xff0c;就是概念堆砌&#xff0c;核心观点要拉到中部才能看见。读者的耐心&#xff0c;早…...

Z-Image-Turbo-rinaiqiao-huiyewunv 开发环境配置:使用Visual Studio Code进行高效调试

Z-Image-Turbo-rinaiqiao-huiyewunv 开发环境配置&#xff1a;使用Visual Studio Code进行高效调试 如果你正在折腾Z-Image-Turbo-rinaiqiao-huiyewunv这个模型&#xff0c;想用它来生成图片&#xff0c;但发现代码跑起来总是不太顺手&#xff0c;或者想深入看看模型内部是怎么…...

XUnity.AutoTranslator技术深度解析:Unity游戏实时翻译引擎的架构设计与实现原理

XUnity.AutoTranslator技术深度解析&#xff1a;Unity游戏实时翻译引擎的架构设计与实现原理 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator是一款基于运行时hook技术的Unity游戏实…...

MySQL优化案例:忍者像素绘卷作品海量存储与查询实践

MySQL优化案例&#xff1a;忍者像素绘卷作品海量存储与查询实践 1. 场景与挑战 像素艺术分享平台"忍者像素绘卷"近期用户量突破百万&#xff0c;每天新增作品超过5万幅。平台需要存储每幅作品的元数据&#xff0c;包括提示词、生成参数、缩略图地址等信息。随着数据…...