这段时间一直在搞大华的执法记录仪设备的视频播放,总所周知,unity平台对视频播放不是很友好,而大华的SDK只有c#版本的并没有专门为unity做出来SDK,最开始尝试过使用SDK里面的方式获取YUV格式的视频流,再讲YUV格式的视频流转换为unity可以播放的格式,但是这个格式转换经常出现问题,而且很卡顿,所以呢我就用了ump插件进行rtsp视频流播放,还算是比较流畅的。
ump插件下载链接:https://pan.baidu.com/s/1AW50i41MgGHR9npdgJOf6Q 提取码:ahez (仅供学习,请勿商用)
大华的设备rtsp流构成分析:
rtsp://[username]:[password]@[address]:[port]/cam/realmonitor?channel=[id]&subtype=[type]
rtsp:// => 协议格式头
username => 用户名,例如:admin
password => 密码,例如:123456
address => IPC设备的网络地址,例如:192.168.1.65
port => IPC设备的RTSP输出端口,默认为554,若为默认可不填写
id => 通道号,起始为1。例如通道2,则为channel=2。
type => 码流类型,主码流为0(即subtype=0),辅码流为1(即subtype=1)。
原文链接:https://blog.csdn.net/haoyitech/article/details/79563281 (原文介绍了大华和海康的rtsp视频流构成,我这里只用了大华的,如果有需要海康的,请自行查找)
插件非常好用,只需要将UniversalMediaPlayer预制体拖放至场景中,将脚本上的rtsp流修改之后就可以查看视频了。
但是!由于我们需要的功能执法记录仪上没有,我们就定制了我们需要的功能,然后将执法记录仪设备系统升级了,结果升级之后,之前的获取rtsp视频流的功能,居然无法使用了,我在和大华的技术部联系过之后,得到的结论是升值后确实不能使用rtsp来播放视频流了,如果有需要可以定制。emm... ... 这就很尴尬了,定制是不可能的,但是问题还是要解决的,在热心同时的提示和帮助之下,我们采取了使用开启一个winform程序专门用来播放视频,虽然界面丑了点,但是还是完成了需要的功能。
winform代码:
调用大华SDK
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NetSDKCS;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System;
using System.Collections.Generic;
namespace MeshDaHuaTool
{
public class DaHuaManager
{
#region Field 字段,属性
private const int m_WaitTime = 5000;
private const int SyncFileSize = 5 * 1024 * 1204;
private static fDisConnectCallBack m_DisConnectCallBack;
private static fHaveReConnectCallBack m_ReConnectCallBack;
private static fRealDataCallBackEx2 m_RealDataCallBackEx2;
private static fSnapRevCallBack m_SnapRevCallBack;
private static fAudioDataCallBack m_AudioDataCallBack;
private IntPtr m_LoginID = IntPtr.Zero;
private IntPtr m_TalkID = IntPtr.Zero;
private NET_DEVICEINFO_Ex m_DeviceInfo;
private IntPtr m_RealPlayID = IntPtr.Zero;
private uint m_SnapSerialNum = 1;
private bool m_IsInSave = false;
private bool m_Islogin = false;
//对讲参数
private const int SampleRate = 8000;
private const int AudioBit = 16;
private const int PacketPeriod = 25;
private const int SendAudio = 0;
private const int ReviceAudio = 1;
//回放参数
private IntPtr m_PlayBackID = IntPtr.Zero;
//下载录像参数
IntPtr m_DownloadID = IntPtr.Zero;
fTimeDownLoadPosCallBack m_DownloadPosCallBack;
/// <summary>
/// 步长速度
/// </summary>
private int SpeedValue = 4;
/// <summary>
/// 最大步长速度
/// </summary>
private const int MaxSpeed = 8;
/// <summary>
/// 最小步长速度
/// </summary>
private const int MinSpeed = 1;
/// <summary>
/// 抓图保存根目录
/// </summary>
private string m_CaptureImageDirectory;
/// <summary>
/// 获取SDK错误
/// </summary>
private string LastError
{
get
{
return NETClient.GetLastError();
}
}
/// <summary>
/// 是否正在保存视频
/// </summary>
public bool IsinSave
{
get
{
return m_IsInSave;
}
}
#endregion
#region 回调
public Action<ErrorType> OnSucess;
public Action<ErrorArgs> OnError;
public Action<string> OnCaptureSucced;
#endregion
/// <summary>
/// 初始化
/// </summary>
public void Init()
{
m_DisConnectCallBack = new fDisConnectCallBack(DisConnectCallBack);
m_ReConnectCallBack = new fHaveReConnectCallBack(ReConnectCallBack);
m_RealDataCallBackEx2 = new fRealDataCallBackEx2(RealDataCallBackEx);
m_SnapRevCallBack = new fSnapRevCallBack(SnapRevCallBack);
m_AudioDataCallBack = new fAudioDataCallBack(AudioDataCallBack);
m_DownloadPosCallBack = new fTimeDownLoadPosCallBack(TimeDownLoadPosCallBack);
try
{
//注册回调函数
NETClient.Init(m_DisConnectCallBack, IntPtr.Zero, null);
NETClient.SetAutoReconnect(m_ReConnectCallBack, IntPtr.Zero);
NETClient.SetSnapRevCallBack(m_SnapRevCallBack, IntPtr.Zero);
//抓图路径赋值
m_CaptureImageDirectory = @"C:\img";
if (!Directory.Exists(m_CaptureImageDirectory))
{
Directory.CreateDirectory(m_CaptureImageDirectory);
}
}
catch (Exception ex)
{
OnError?.Invoke(new ErrorArgs(ErrorType.None, ex.Message));
Process.GetCurrentProcess().Kill();
}
}
/// <summary>
/// 登录大华平台
/// </summary>
/// <param name="ip">IP地址</param>
/// <param name="port">端口</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
public void Login(string ip, ushort port, string username, string password)
{
if (IntPtr.Zero == m_LoginID)
{
m_DeviceInfo = new NET_DEVICEINFO_Ex();
m_LoginID = NETClient.Login(ip,