Unity3d 实现直播功能
需要插件 :VideoCapture 插件地址(免费的就行)
原理:客户端通过 VideoCapture 插件实现推流+nodejs视频流转服务进行转发,播放器实现rtmp拉流
废话不多说,直接上
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)直播的功能(含源码)