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

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 processvar cmdProcess = new Process{StartInfo ={FileName = "cmd.exe",UseShellExecute = false,CreateNoWindow = true, // this is probably optionalErrorDialog = false, // this is probably optionalRedirectStandardOutput = 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 processcmdProcess.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();//开启cmdpro.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>

遇到过的问题:
http://192.168.101.178:8000/live/unity/aaa.flv //地址太长HTTP请求播放的时候播放失败,rtmp没问题

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

相关文章:

  • GPT实战系列-简单聊聊LangChain
  • 【适用于Jetson Orin Nano的录屏软件】
  • 构建基于RHEL9系列(CentOS9,AlmaLinux9,RockyLinux9等)的MySQL8.0.32的RPM包
  • vue3+vite+ts+pinia新建项目(略详细版)
  • 使用MistNet在COCO128数据集上协作训练Yolo-v5
  • JS加密/解密之js加密小工具
  • win10在启动游戏时报错,提示“d3dx9_25.dll文件丢失”,怎么办?d3dx9_25.dll丢失如何自动修复
  • SCI一区级 | Matlab实现RIME-CNN-LSTM-Mutilhead-Attention多变量多步时序预测
  • 发起人自选-钉钉审批
  • Elasticsearch 地理空间搜索 - 远超 OpenSearch
  • 上海亚商投顾:创业板指放量涨近2% 全市场超4400只个股上涨
  • Vue入门五(Vue-CLI项目搭建|vue项目目录介绍|vue项目开发规范|es6导入导出语法)
  • RK3568驱动指南|第十一篇 pinctrl 子系统-第123章dt_node_to_map函数分析
  • Java课程设计个人博客
  • SQL-条件查询与聚合函数的使用
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 2019年如何成为全栈工程师?
  • CSS中外联样式表代表的含义
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • Intervention/image 图片处理扩展包的安装和使用
  • Java多线程(4):使用线程池执行定时任务
  • js正则,这点儿就够用了
  • Vim Clutch | 面向脚踏板编程……
  • 从setTimeout-setInterval看JS线程
  • 从零开始学习部署
  • 番外篇1:在Windows环境下安装JDK
  • 分布式熔断降级平台aegis
  • 技术发展面试
  • 前端面试之闭包
  • 跳前端坑前,先看看这个!!
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 在Mac OS X上安装 Ruby运行环境
  • 回归生活:清理微信公众号
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (3)llvm ir转换过程
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (多级缓存)多级缓存
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (算法)Game
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)SpringBoot3---尚硅谷总结
  • (一)u-boot-nand.bin的下载
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET导入Excel数据
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell