GB28181_WinForm + ZLMediakit(实现预览,PTZ,回放,语音广播,上级级联)
1. 配置ZLMediaKit并启动
2. 软件功能
2.1 获取设备目录:启动服务 -> 选中已注册设备-> 设备目录查询
2.2 视频直播:选中通道 -> 视频直播(得到视频地址)-> 在线直播(zlmediakit转流,vlc播放)
3. PTZ 控制
4. 录像回放
4.1 录像检索
4.2 录像点播
5. 语音广播
先更改配置信息,启动服务,设备注册后,选中设备,设备查询->选中通道 -> 语音广播通知 -> 播放广播
程序架构
调用代码
using GB28181.Sys.XML; using GB28181Server.SIPSorcery; using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Windows.Forms; namespace GB28181Server { public partial class MainForm : Form { SIPHelper sipHelper = new SIPHelper(); int recvCount = 0; int deviceIndex = 0; Dictionary<string, ListViewBinding> dicDevice2ViewBinding = new Dictionary<string, ListViewBinding>(); string currentDeviceId = string.Empty;// 当前选中设备编号 string currentDeviceIP = string.Empty;// 当前选中设备IP ListViewItem currentChannelItem; // 当前选中通道项 public MainForm() { InitializeComponent(); } // 窗体初始化 private void MainForm_Load(object sender, EventArgs e) { cmbQueryType.SelectedIndex = 2; // 加载配置 var config = sipHelper.Configs; txtListenPort.Text = config.ListenPort.ToString(); txtSerialId.Text = config.DeviceId; txtMediaIP.Text = config.MediaIP; txtMediaPort.Text = config.MediaPort.ToString(); txtMediaPlayPort.Text = config.MediaPlayPort.ToString(); // dtpBeginTime.Value = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd 00:00:00")); dtpEndTime.Value = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd 23:59:59")); } // vlc初始化 private void vlcControl1_VlcLibDirectoryNeeded(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e) { var currentAssembly = Assembly.GetEntryAssembly(); var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName; if (currentDirectory == null) return; if (AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86) e.VlcLibDirectory = new DirectoryInfo(Path.Combine(currentDirectory, @"libvlc\win-x86\")); else e.VlcLibDirectory = new DirectoryInfo(Path.Combine(currentDirectory, @"libvlc\win-x64\")); } // 更新消息 void UpdateMessage(string msg) { this.BeginInvoke((EventHandler)(delegate { lblMsg.Text = msg; })); } // 更新日志 public void UpdateLog(string msg) { this.BeginInvoke((EventHandler)(delegate { if (recvCount++ > 10) { // 清理数据 recvCount = 0; rtbMsg.Clear(); } rtbMsg.AppendText(DateTime.Now.ToString("MM-dd HH:mm:ss") + " " + msg + "\n"); })); } // 清除日志 public void ClearLog() { this.BeginInvoke((EventHandler)(delegate { recvCount = 0; rtbMsg.Clear(); })); } // 更新设备列表 public void UpdateDevice(SIPAccountBinding binding, string ip, string port = "", string deviceId = "", string hearTime = "", string offTime = "", string register = "", string channelCount = "") { this.BeginInvoke((EventHandler)(delegate { this.listViewDevice.BeginUpdate(); if (!dicDevice2ViewBinding.ContainsKey(ip)) { ListViewBinding createBinding = new ListViewBinding(); createBinding.ListViewIndex = deviceIndex++; createBinding.ListViewData = binding; dicDevice2ViewBinding.Add(ip, createBinding); // // 更新ui ListViewItem createViewItem = new ListViewItem(); createViewItem.SubItems.Add(""); createViewItem.SubItems.Add(""); createViewItem.SubItems.Add(""); createViewItem.SubItems.Add(""); createViewItem.SubItems.Add(""); createViewItem.SubItems.Add(""); createViewItem.SubItems.Add(""); createViewItem.SubItems.Add(""); listViewDevice.Items.Add(createViewItem); } var viewBinding = dicDevice2ViewBinding[ip]; if (null != binding) viewBinding.ListViewData = binding; // // 更新ui ListViewItem currentItem = listViewDevice.Items[viewBinding.ListViewIndex]; currentItem.SubItems[0].Text = viewBinding.ListViewIndex.ToString(); currentItem.SubItems[1].Text = ip; if (!string.IsNullOrEmpty(port)) { currentItem.SubItems[2].Text = port; } if (!string.IsNullOrEmpty(deviceId)) { currentItem.SubItems[3].Text = viewBinding.DeviceId = deviceId; } if (!string.IsNullOrEmpty(hearTime)) { currentItem.SubItems[4].Text = hearTime; } if (!string.IsNullOrEmpty(offTime)) { currentItem.SubItems[5].Text = offTime; } if (!string.IsNullOrEmpty(register)) { currentItem.SubItems[6].Text = register; } if (!string.IsNullOrEmpty(channelCount)) { currentItem.SubItems[7].Text = channelCount; } this.listViewDevice.EndUpdate(); })); } // 更新通道信息 public void AddChannel() { this.BeginInvoke((EventHandler)(delegate { this.listViewChannel.BeginUpdate(); this.listViewChannel.Items.Clear(); var dicChannel = sipHelper.DicDevice2Channel[currentDeviceId]; int index = 0; int channelCount = 0; if (null != dicChannel) { channelCount = dicChannel.Count; try { foreach (var item in dicChannel) { var channelId = item.Key; var channelItem = item.Value; var catalogItem = channelItem.CatalogItem; // ListViewItem createViewItem = new ListViewItem(); createViewItem.Text = (index++).ToString(); createViewItem.SubItems.Add(currentDeviceId); createViewItem.SubItems.Add(channelId); createViewItem.SubItems.Add(catalogItem.Name); createViewItem.SubItems.Add(catalogItem.Manufacturer); createViewItem.SubItems.Add(catalogItem.Address); createViewItem.SubItems.Add(catalogItem.Status.ToString()); createViewItem.SubItems.Add(""); listViewChannel.Items.Add(createViewItem); } } catch { } } this.listViewChannel.EndUpdate(); UpdateDevice(null, currentDeviceIP, "", "", "", "", "", channelCount.ToString()); })); } // 更新通道信息(直播地址) public void UpdateChannel() { currentChannelItem.SubItems[7].Text = sipHelper.SelectPlayLiveVideo; } // 更新录像 public void AddRecord(RecordInfo record) { this.BeginInvoke((EventHandler)(delegate { this.listViewRecord.BeginUpdate(); int index = 0; if (null != record.RecordItems) { foreach (var item in record.RecordItems.Items) { ListViewItem lvItem = new ListViewItem(new string[] { (index++).ToString(), record.Name, item.DeviceID, item.StartTime, item.EndTime }); listViewRecord.Items.Add(lvItem); } } this.listViewRecord.EndUpdate(); })); } // 保存加载配置 void SaveConfig() { sipHelper.Configs.ListenPort = Convert.ToInt32(txtListenPort.Text); sipHelper.Configs.DeviceId = txtSerialId.Text; sipHelper.Configs.MediaIP = txtMediaIP.Text; sipHelper.Configs.MediaPort = Convert.ToInt32(txtMediaPort.Text); sipHelper.Configs.MediaPlayPort = Convert.ToInt32(txtMediaPlayPort.Text); if (ConfigManager.SaveConfig(sipHelper.Configs)) { UpdateLog("保存配置成功"); } else { UpdateLog("保存配置失败"); } } // 开启服务 or 关闭服务 async void btnService_Click(object sender, EventArgs e) { SaveConfig(); string serviceStatus = btnService.Text; switch (serviceStatus) { case "启动服务": { if (sipHelper.StartService()) { UpdateMessage("服务已开启"); btnService.Text = "关闭服务"; } } break; case "关闭服务": { bool result = await sipHelper.StopService(); if (result) { UpdateMessage("服务已关闭"); btnService.Text = "启动服务"; } } break; } } // 选中已注册的设备 private void listViewDevice_Click(object sender, EventArgs e) { ListViewItem item = this.listViewDevice.SelectedItems[0];//当前选中行 if (item == null) { return; } string ip = item.SubItems[1].Text; currentDeviceIP = ip; var viewBinding = dicDevice2ViewBinding[ip]; sipHelper.SelectedAccountBinding = viewBinding.ListViewData; sipHelper.SelectDeviceId = currentDeviceId = viewBinding.DeviceId; } // 选中已注册的通道 private void listViewChannel_Click(object sender, EventArgs e) { currentChannelItem = this.listViewChannel.SelectedItems[0];//当前选中行 if (currentChannelItem == null) { return; } string deviceId = currentChannelItem.SubItems[1].Text; string channelId = currentChannelItem.SubItems[2].Text; string playVideo = currentChannelItem.SubItems[7].Text; var channelItem = sipHelper.DicDevice2Channel[deviceId]; if (null != channelItem && channelItem.ContainsKey(channelId)) { var catalogItem = channelItem[channelId]; sipHelper.SelectedAccountBinding = catalogItem.Binding; sipHelper.SelectPlayLiveVideo = playVideo; } } // 请求直播 private async void btnStartVideo_Click(object sender, EventArgs e) { await sipHelper.StartVideo(); } // 停止直播 private async void btnStopVideo_Click(object sender, EventArgs e) { await sipHelper.StopVideo(); } // 在线直播 private void btnPlayLive_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(sipHelper.SelectPlayLiveVideo)) { UpdateMessage("未选中直播地址"); return; } UpdateMessage("直播视频:" + sipHelper.SelectPlayLiveVideo); vlcControl1.Play(sipHelper.SelectPlayLiveVideo); } // 录像回放 private void btnPlayRecord_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(sipHelper.SelectPlayBackVideo)) { UpdateMessage("未选中回放地址"); return; } UpdateMessage("回放视频:" + sipHelper.SelectPlayBackVideo); vlcControl1.Play(sipHelper.SelectPlayBackVideo); } // 查询设备信息 private async void btnQuery_Click(object sender, EventArgs e) { ClearLog(); // sipHelper.SelectedType = (CommandType)cmbQueryType.SelectedIndex; await sipHelper.Query(); } // PTZ控制 private async void btnPTZControl_Click(object sender, EventArgs e) { ClearLog(); // var btn = (Button)sender; PTZCommand ptcCmd = (PTZCommand)Convert.ToInt32(btn.Tag); await sipHelper.PTZContorl(ptcCmd, 5); } private async void btnGetRecord_Click(object sender, EventArgs e) { // 录像检索 await sipHelper.RecordFileQuery(dtpBeginTime.Value, dtpEndTime.Value); } private async void btnStartRecord_Click(object sender, EventArgs e) { // 开始点播 await sipHelper.StartRecord(dtpBeginTime.Value, dtpEndTime.Value); } private async void btnStopRecord_Click(object sender, EventArgs e) { // 停止点播 await sipHelper.StopVideo(); } } }
附配置:
相机配置
NVR配置
qq:505645074
分类:
安防监控系统
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了