Unity3d 实现直播功能(无需sdk接入)

Unity3d 实现直播功能

需要插件 :VideoCapture 插件地址(免费的就行)
原理:客户端通过 VideoCapture 插件实现推流+nodejs视频流转服务进行转发,播放器实现rtmp拉流
废话不多说,直接上
场景对象挂上VideoCapture组件

CaptureSource我选择的是屏幕录制,也可以是其他源
CaptureType选择LIVE–直播形式
LiveStreamUrl选择自己本地服务地址 例如 rtmp://localhost:1935/live/unity//localhost也可以切换外网推流服务器地址

推流服务器

//  index.js 
const NodeMediaServer = require('node-media-server');
 
const config = {
  rtmp: {
    port: 1935,//rtmp服务端口号
    chunk_size: 60000,
    gop_cache: true,
    ping: 30,
    ping_timeout: 60
  },
  http: {
    port: 8000,//http服务端口号,拉流用的
    allow_origin: '*'
  }
};
 
var nms = new NodeMediaServer(config)
nms.run();

一个简单的nodejs服务,需提前安装依赖包

npm install node-media-server --save

安装完成后,命令行进入到 index.js所在目录执行

node index.js

命令,看到下图即为成功

服务运行成功
运行unity项目,点击 StartCapture

开启直播
打开拉流软件VLC(下载地址)
效果如下:
运行效果

视频效果如下

unity视频直播效果

unity直接起本地推流拉流服务代码(Editor使用,出包需要改地址和配合拷贝文件)


using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UnityEngine;
//Editor完美运行,出包需要另外设置地址杀死nodejs推流程序
public class StartNodeJsServer : MonoBehaviour
{
    private void Start()
    {
        StartServer();
    }
    public void StartServer()
    {
        // create the command-line process
        var cmdProcess = new Process
        {
            StartInfo =
            {
                FileName = "cmd.exe",
                UseShellExecute = false,
                CreateNoWindow = true, // this is probably optional
                ErrorDialog = false, // this is probably optional
                RedirectStandardOutput = true,
                RedirectStandardInput = true
            }
        };

        // register for the output (for reading the output)
        cmdProcess.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
        {
            string output = e.Data;
            // inspect the output text here ...
        };

        // start the cmd process
        cmdProcess.Start();
        cmdProcess.BeginOutputReadLine();

        // execute your command
        //cmdProcess.StandardInput.WriteLine("npm install node-media-server --save");//服务器文件放到Assets目录下面的server内,出包的时候此处需要修改
        cmdProcess.StandardInput.WriteLine("node " + Application.dataPath + "/server/index.js");
        UnityEngine.Debug.LogError("node " + Application.dataPath + "/server/index.js");
        GameManager.Instance.nodeServerStarted = true;
    }

    public dynamic RunCmd(string cmd, bool isReturnStreamReader = false)
    {
        Process pro = new Process();
        pro.StartInfo.FileName = "cmd.exe";

        pro.StartInfo.CreateNoWindow = true;         // 不创建新窗口    
        pro.StartInfo.UseShellExecute = false;       //不启用shell启动进程  
        pro.StartInfo.RedirectStandardInput = true;  // 重定向输入    
        pro.StartInfo.RedirectStandardOutput = true; // 重定向标准输出    
        pro.StartInfo.RedirectStandardError = true;
        pro.StartInfo.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
        pro.StartInfo.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
        // 重定向错误输出  
        // pro.StartInfo.WorkingDirectory = path;
        pro.Start();//开启cmd
        pro.StandardInput.WriteLine(cmd);
        pro.StandardInput.AutoFlush = true;
        pro.StandardInput.WriteLine("exit"); //若是运行时间短可加入此命令

        dynamic output;
        if (isReturnStreamReader)
        {
            output = pro.StandardOutput;
        }
        else
        {
            output = pro.StandardOutput.ReadToEnd();
        }

        pro.WaitForExit();//若运行时间长,使用这个,等待程序执行完退出进程
        pro.Close();
        return output;
    }

    public List<string> GetPidOfAddress(string address)
    {
        //用来保存所有对应地址的端口号数据
        List<string> valueList = new List<string>();
        //获取返回的StreamReader数据
        StreamReader sr = RunCmd($"netstat -aon|findstr {address}", true);
        //读取StreamReader的每一行数据
        while (!sr.EndOfStream)
        {
            string value = sr.ReadLine();
            //查看当前读取的行中内容是否包含TCP字符
            if (!string.IsNullOrEmpty(value) && value.Contains("TCP"))
            {
                //只获取状态为 LISTENING 的数据
                string[] ss = value.Split("LISTENING");
                //获取端口号数据信息
                if (ss.Length >= 2)
                {
                    string port = ss[ss.Length - 1].Trim();
                    //重复的端口号不加入结果列表中
                    if (valueList.FirstOrDefault(a => a == port) == null)
                        valueList.Add(port);
                }
            }
        }
        return valueList;
    }

    /// <summary>
    /// 根据PID杀死对应进程
    /// </summary>
    /// <param name="pid"></param>
    /// <returns></returns>
    public string KillTask(string pid)
    {
        return RunCmd($"taskkill /F /pid {pid}");
    }

    private void OnApplicationQuit()//退出程序杀死直播服务
    {
        List<string> address = GetPidOfAddress("1935");
        address.ForEach((s) =>
        {
            KillTask(s);
        });
    }
}

网页查看视频效果

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<script src="https://cdn.bootcss.com/flv.js/1.4.0/flv.min.js"></script>
		<video id="videoElement" style="width: 100%;" controls="controls"></video>
		<script>
		    if (flvjs.isSupported()) {
		        var videoElement = document.getElementById('videoElement');
		        var flvPlayer = flvjs.createPlayer({
		            type: 'flv',
					url:'http://localhost:8000/live/unity.flv' //这里走的http拉视频,所以用端口号8000
		        });
		        flvPlayer.attachMediaElement(videoElement);
		        flvPlayer.load();
		        flvPlayer.play();
		    }
		</script>
	</body>
</html>

参考链接(感谢大神铺路)
node.js简易版直播功能(局域网内)
Unity3d C#实现将场景中摄像头画面进行采集、录制并上传视频流(推流rtmp)直播的功能(含源码)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/303110.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA[Debug]简单说明

目录 &#x1f95e;1.打断点 &#x1f32d;2.第一组按钮 &#x1f9c2;3.第二组按钮 &#x1f953;4.参数查看 1.打断点 1.在需要断点处打上断点&#xff0c;然后点击debug运行 2.执行debug&#xff0c;直接执行到断点处 2.第一组按钮 共有8按钮&#xff0c;从左往右依…

【系统高级-环境变量】path配置一整行,而不是列表

这是列表编辑方便。但是不知道为什么变成一行&#xff0c;非常的令人抓狂&#xff0c;经过研究发现&#xff0c;第一个环境变量必须为C:\Windows\system32 开头才可以 文章如下 修改环境变量中的一行变成列表形式_环境变量编辑不是列表-CSDN博客

回归预测 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变…

苍穹外卖Day01——总结1

总结1 1. 软件开发整体介绍1.1 软件开发流程1.2 角色分工1.3 软件环境 2. 苍穹外卖项目介绍2.1 项目介绍2.2 技术选项 3. Swagger4. 补充内容&#xff08;待解决...&#xff09; 1. 软件开发整体介绍 1.1 软件开发流程 1.2 角色分工 从角色分工里面就可以查看自己以后从事哪一…

芯片命名大全:完整的器件型号包括主体型号、前缀、后缀等!

不少公司的采购会发现&#xff0c;拿到工程师提供的BOM中的器件去采购物料时&#xff0c;经常供应商还会问得更仔细&#xff0c;否则就不知道供给你哪种物料&#xff0c;严重时&#xff0c;采购回来的物料用不了。为什么会有这种情况呢&#xff1f;问题就在于&#xff0c;很多经…

数据结构—图(下)

文章目录 12.图(下)(4).生成树和最小生成树#1.什么是生成树和最小生成树&#xff1f;i.生成树ii.最小生成树 #2.Prim算法i.算法思想ii.看看例子iii.代码实现 #3.Kruskal算法i.算法思想ii.看看例子iii.代码实现 #4.次小生成树 (5).最短路径问题#1.加权有向图的最短路径问题#2.单…

盘点三款服务器运维工具

随着世界变得更加数字化&#xff0c;如何便捷高效地管理服务器变得越来越重要&#xff0c;能有一款简易实用且现代化服务器管理工具就显得尤为关键。今天就选取了三款服务器运维工具进行对比分析&#xff0c;评测每款产品的优缺点。 产品清单 宝塔面板 简介&#xff1a;国内老…

工作流自动化:它是什么,常见示例以及如何实现

由于您的组织旨在留住顶尖人才和高价值客户&#xff0c;因此您需要不断为这两个团队提供一流的体验。 就客户而言&#xff0c;它可以实时解决他们的问题和疑虑&#xff0c;并以深思熟虑、可操作的洞察力主动与他们联系&#xff1b;而且&#xff0c;对于员工来说&#xff0c;它可…

推荐一款强大的AI开源项目!有了它,将你的数据库秒变AI数据库!

前言 在当今数字化的世界中&#xff0c;数据库系统扮演着至关重要的角色。而原生系统的功能我们也大都知晓&#xff0c;无非是一些增删改查、数据优化的使用。但有一些开源工具项目可以帮助我们对数据库降本增效。 在本文中&#xff0c;小编将介绍一个名为SuperDuperDB的开源…

构建多种样式的弹窗(案例)

介绍 本篇Codelab将介绍如何使用弹窗功能&#xff0c;实现四种类型弹窗。分别是&#xff1a;警告弹窗、自定义弹窗、日期滑动选择器弹窗、文本滑动选择器弹窗。需要完成以下功能&#xff1a; 点击左上角返回按钮展示警告弹窗。点击出生日期展示日期滑动选择器弹窗。点击性别展示…

树莓派4B使用ncnn部署yolov5-Lite,推理耗时 247ms 包含前后处理

一. 引言 最近在玩树莓派&#xff0c;想在树莓派上不是一个目标检测算法&#xff0c;大致看了一下&#xff0c;目前开源的大家都在使用yolov5-Lite&#xff0c;使用ncnn去推理加速&#xff0c;于是自己也尝试部署&#xff0c;在此记录一下&#xff0c;个人踩的坑。 二. 版本选…

后端 API 接口文档 Swagger 使用

Swagger 是什么 swagger是一款可以根据 restful 风格生成的接口开发文档&#xff0c;并且支持做测试的一款中间软件。 例如当我们在开发前后端分离项目时&#xff0c;当后端开发完一个功能想要测试时&#xff0c;若此时还没有相应的前端页面发起请求&#xff0c;可以通过 swag…

java回溯算法、最短路径算法、最小生成树算法

回溯算法 回溯算法实际上一个类似枚举的搜索尝试过程&#xff0c;主要是在搜索尝试过程中寻找问题的解&#xff0c;当发现已不满足求解条件时&#xff0c;就“回溯”返回&#xff0c;尝试别的路径。 最短路径算法 从某顶点出发&#xff0c;沿图的边到达另一顶点所经过的路径中…

【QML COOK】- 002-添加一个图片

1. 编辑main.qml import QtQuickWindow {width: 800height: 800visible: truetitle: qsTr("Hello World")Image {anchors.fill: parentsource: "qrc:/Resources/Images/arrow.png"} }将Window的width和height都改成800&#xff0c;因为我们要添加的图片大…

Spring AOP概念

什么是 AOP &#xff1f; AOP 为 Aspect Oriented Programming 的缩写&#xff0c;意为&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续&#xff0c;是软件开发中的一个热点&#xff0c;也是 Spring …

Mac 环境多JDK安装与切换

一、下载jdk 去Oracle官网上下载想要安装的jdk版本&#xff0c;M芯片选择arm架构的.bmg格式的文件。 https://www.oracle.com/java/technologies/downloads/。 二、安装jdk 2.1 双击下载的文件&#xff0c;安装步骤一步步点继续就好。 2.2 安装完成后会在/Library/Java/JavaV…

常见测试技术都有哪些?

测试技术是用于评估系统或组件的方法&#xff0c;目的是发现它是否满足给定的要求。系统测试有助于识别缺口、错误&#xff0c;或与实际需求不同的任何类型的缺失需求。测试技术是测试团队根据给定的需求评估已开发软件所使用的最佳实践。这些技术可以确保产品或软件的整体质量…

2024年甘肃省职业院校技能大赛 高职学生组电子与信息大类信息安全管理与评估赛项样题卷①

2024年甘肃省职业院校技能大赛 高职学生组电子与信息大类信息安全管理与评估赛项样题 第一阶段&#xff1a;第二阶段&#xff1a;模块二 网络安全事件响应、数字取证调查、应用程序安全第二阶段 网络安全事件响应第一部分 网络安全事件响应第二部分 数字取证调查第三部分 应用程…

网络通信(12)-C#TCP客户端封装帮助类实例

本文使用Socket在C#语言环境下完成TCP客户端封装帮助类的实例。 实例完成的功能: 客户端与服务器连接,实现实时刷新状态。 客户端接收服务器的数据。 客户端发送给服务器的数据。 客户端实时判定状态,断开连接后自动重连。 客户端与服务器端发送心跳包。 在VS中创建C…

电商引流模式:广告电商

广告电商模式是一种将广告收入与电商业务相结合的商业模式。在这种模式下&#xff0c;电商企业通过向消费者提供免费或低价的商品或服务&#xff0c;吸引大量用户关注和参与。同时&#xff0c;电商企业通过与广告主合作&#xff0c;将广告投放到自己的平台上&#xff0c;通过广…