当前位置: 首页 > 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;目标检测模型在视频流或文件中计数对象。我们将该过程分解为简单…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...

当下AI智能硬件方案浅谈

背景&#xff1a; 现在大模型出来以后&#xff0c;打破了常规的机械式的对话&#xff0c;人机对话变得更聪明一点。 对话用到的技术主要是实时音视频&#xff0c;简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术&#xff0c;开发自己的大模型。商用方案多见为字节、百…...

ffmpeg(三):处理原始数据命令

FFmpeg 可以直接处理原始音频和视频数据&#xff08;Raw PCM、YUV 等&#xff09;&#xff0c;常见场景包括&#xff1a; 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装&#xff08;如封装为 MP4、TS&#xff09; 处理原始 YUV 视频…...

【向量库】Weaviate概述与架构解析

文章目录 一、什么是weaviate二、High-Level Architecture1. Core Components2. Storage Layer3. 组件交互流程 三、核心组件1. API Layer2. Schema Management3. Vector Indexing3.1. 查询原理3.2. 左侧&#xff1a;Search Process&#xff08;搜索流程&#xff09;3.3. 右侧&…...