参考上一篇:

针对监控摄像机(海康、大华等)进行手动录像的功能设计

录像后需要自定义一个播放器来播放录像文件。

简单设计界面如下:

打开文件,可暂停,可停止,可以拖动进度条。

static int width = 1920, height = 1080;int videoWidth = 639, videoHeight = 479;int YUVWidth = 640, YUVHeight = 480;bool bPause = false;bool bPlayStop = false;ILog log= LogManager.GetLogger("ErrorLog");int fps = 15, fpsMain = 15, fpsBase = 15;int msPerFrameCamera = 66, msPerFrameCameraBase = 66, msPerFrameCameraMain = 66; //相机每一帧的时间,25帧即40毫秒publicfrmPlay(){InitializeComponent();#region 解码器相关初始化,一般在窗口load中进行初始化decAttr= newH264Dec.hiH264_DEC_ATTR_S();decAttr.uPictureFormat= 0;decAttr.uStreamInType= 0;decAttr.uPicWidthInMB= (uint)width;decAttr.uPicHeightInMB= (uint)height;decAttr.uBufNum= 8;decAttr.uWorkMode= 16;//创建、初始化解码器句柄_decHandle = H264Dec.Hi264DecCreate(refdecAttr);#endregionInitVars();frmPlay_Resize(null, null);this.Resize += new System.EventHandler(this.frmPlay_Resize);}long offsetPlay = 0;int iFramePlay = 0;Image<Bgr, Byte> imageYUV = new Image<Bgr, Byte>(640, 480);Image<Bgr, Byte> imgNowShow = new Image<Bgr, Byte>(640, 480);int iFontSize16 = 12, iFontSize20 = 15, iFontSize24 = 18;string fontname = "仿宋_GB2312";private delegate void SetPicVideo(Image<Bgr, Byte> val);//跨线程修改图片框privateThread SetPicVideoThread;FileStream fs= null;private delegate void SetProgressLabel(stringval);Thread SetLabelThread;string labelValue = string.Empty;string sTotalTime = "";int iFrameCnt = 0;Thread showThread;void SetPic(Emgu.CV.Image<Bgr, Byte>val){if (bPause || bPlayStop ||bAbortPlayThread){Graphics g=imgBox.CreateGraphics();g.Clear(Color.Black);imageVideoOverLay.Visible= true;}elseif(imageVideoOverLay.Visible){imageVideoOverLay.Visible= false;}if (val != null && !bAbortPlayThread){this.imgBox.Image =val;imgBox.Refresh();}}private voidsetPicVideo(){if (bPause || bPlayStop || bAbortPlayThread) return;if(imgBox.InvokeRequired){SetPicVideo d= newSetPicVideo(SetPic);object[] arg = new object[] { imgNowShow };this.Invoke(d, arg);}else{SetPic(imgNowShow);}}List<BufferPlay> BufferPlayList = new List<BufferPlay>();private voidDrawnShow(){iFramePlay= 0;while (!bAbortPlayThread){if (BufferPlayList.Count > 0){DateTime dtStart=DateTime.Now;realstaticinfo= BufferPlayList[0].info;GCHandle handle= GCHandle.Alloc(BufferPlayList[0].yuvs, GCHandleType.Pinned);using (Image<Bgr, Byte> yuv420p = new Image<Bgr, byte>(YUVWidth, (YUVHeight >> 1) * 3, YUVWidth, handle.AddrOfPinnedObject())){CvInvoke.CvtColor(yuv420p, imageYUV, Emgu.CV.CvEnum.ColorConversion.Yuv420P2Bgr);}if(handle.IsAllocated)handle.Free();if (imageYUV == null) continue;Bitmap bmp=imageYUV.Bitmap;if (bmp == null) continue;lock(bmp){if(bShowLine){DrawInVideo(bmp);}imageYUV.Bitmap=bmp;imgNowShow=imageYUV;SetPicVideoThread= new Thread(newThreadStart(setPicVideo));SetPicVideoThread.IsBackground= true;SetPicVideoThread.Start();}if (BufferPlayList.Count > 0) BufferPlayList.RemoveAt(0);iFramePlay++;if (iFramePlay % fps == 0){int seconds = (int)((double)iFramePlay /fps);int h = (int)Math.Floor((double)seconds / 3600);int m = (int)Math.Floor((double)(seconds - h * 3600) / 60);int s = (int)Math.Floor((double)(seconds - h * 3600 - m * 60));string sNowPlayTime = h.ToString().PadLeft(2, '0') + ":" + m.ToString().PadLeft(2, '0') + ":" + s.ToString().PadLeft(2, '0');labelValue= sNowPlayTime + "/" +sTotalTime;SetLabelThread= new Thread(newThreadStart(setLableValue));SetLabelThread.IsBackground= true;SetLabelThread.Start();}DateTime timeStop2=DateTime.Now;TimeSpan ts2= newTimeSpan();ts2= timeStop2 -dtStart;if (ts2.TotalMilliseconds <msPerFrameCamera){Thread.Sleep((int)(msPerFrameCamera -ts2.TotalMilliseconds));}}}}private void Play(objectofs){FileStream fsTmp= ofs asFileStream;try{offsetPlay= 0;DateTime timeStart=DateTime.Now;DateTime timeStop=DateTime.Now;while (!bAbortPlayThread && fsTmp.Length > offsetPlay + 4 + 378 + 174){try{if(bPause){Thread.Sleep(msPerFrameCamera);continue;}timeStart=DateTime.Now;byte[] intdata = new byte[4];fsTmp.Read(intdata,0, 4);offsetPlay= offsetPlay + 4;fsTmp.Seek(offsetPlay, SeekOrigin.Begin);int frameLen = (int)FVD.Common.Common.bytes2uintNoRe(intdata, 0, 4);byte[] buffer = new byte[frameLen];fsTmp.Read(buffer,0, frameLen);offsetPlay= offsetPlay +frameLen;fsTmp.Seek(offsetPlay, SeekOrigin.Begin);GCHandle hObject2=GCHandle.Alloc(buffer, GCHandleType.Pinned);IntPtr pStreamData=hObject2.AddrOfPinnedObject();if (fsTmp.Length > offsetPlay + 500){byte[] datas= new byte[500];  //获取叠加数据fsTmp.Read(datas, 0, 500);Getdatas(datas);}if (H264Dec.Hi264DecAU(_decHandle, pStreamData, (uint)frameLen, 0, ref _decodeFrame, 0) == 0){int yLength = (int)(_decodeFrame.uHeight *_decodeFrame.uYStride);int uLength = (int)(_decodeFrame.uHeight * _decodeFrame.uUVStride / 2);IntPtr y=_decodeFrame.pY;IntPtr v=_decodeFrame.pV;IntPtr u=_decodeFrame.pU;byte[] ys = new byte[yLength];Marshal.Copy(y, ys,0, yLength);byte[] vs = new byte[uLength];Marshal.Copy(v, vs,0, uLength);byte[] us = new byte[uLength];Marshal.Copy(u, us,0, uLength);byte[] yuvs = new byte[ys.Length + vs.Length +us.Length];ys.CopyTo(yuvs,0);vs.CopyTo(yuvs, ys.Length);us.CopyTo(yuvs, ys.Length+vs.Length);BufferPlay bp;bp.info=realstaticinfoTmp;bp.yuvs=yuvs;BufferPlayList.Add(bp);}if(hObject2.IsAllocated)hObject2.Free();pStreamData=IntPtr.Zero;if (BufferPlayList.Count > 0){Thread.Sleep((int)((BufferPlayList.Count - 1) *msPerFrameCamera));}}catch(System.Exception ex){log.ErrorFormat("播放出错:" +ex.Message);continue;}}}catch(System.Exception ex){log.ErrorFormat("播放出错:" +ex.Message);MessageBox.Show("播放出错:" +ex.Message);}while (BufferPlayList.Count > 0){Thread.Sleep(msPerFrameCamera);}if(bLoopPlay) //循环播放,重新初始化{if (bAbortPlayThread) return;bPlayStop= true;bAbortPlayThread= true;Thread.Sleep(500);bPlayStop= false;bAbortPlayThread= false;labelValue= "00:00:00/" +sTotalTime;SetLabelThread= new Thread(newThreadStart(setLableValue));SetLabelThread.IsBackground= true;SetLabelThread.Start();fsTmp.Seek(0, SeekOrigin.Begin);playThread= new Thread(newParameterizedThreadStart(Play));playThread.IsBackground= true;playThread.Start(fsTmp);showThread= new Thread(newThreadStart(DrawnShow));showThread.IsBackground= true;showThread.Start();}else{fsTmp.Close();fsTmp.Dispose();bPlayStop= true;labelValue= "00:00:00/00:00:00";SetLabelThread= new Thread(newThreadStart(setLableValue));SetLabelThread.IsBackground= true;SetLabelThread.Start();}}private void trackBar1_ValueChanged(objectsender, EventArgs e){if (!string.IsNullOrEmpty(sTotalTime) && fs != null && btnStop.Enabled == true && fs.CanRead && iFrameCnt > 0){bPause= true;Thread.Sleep(msPerFrameCamera);int iNowFrame = (int)((double)trackBar1.Value / trackBar1.Maximum * (double)iFrameCnt);if (iNowFrame <= 0){iNowFrame= 1;}BufferPlayList.Clear();fs.Seek(0, SeekOrigin.Begin);long offsetTmp = 0;int iFrame = 0;byte[] intdata = new byte[4];while (fs.Length > offsetTmp + 504){fs.Read(intdata,0, 4);int frameLen = (int)(intdata[0] | intdata[1] << 8 | intdata[2] << 16 | intdata[3] << 24);offsetTmp= offsetTmp + frameLen + 504; //504 = 4 + 500
fs.Seek(offsetTmp, SeekOrigin.Begin);iFrame++;if (iFrame ==iNowFrame){offsetPlay=offsetTmp;iFramePlay=iNowFrame;break;}}bPause= false;}}void SetStatuslabel(stringval){if (bPlayStop) //自动播放完成,跨线程修改状态
{btnStop.Enabled= false;btnPause.Enabled= false;this.Text = "视频播放";trackBar1.ValueChanged-= newSystem.EventHandler(trackBar1_ValueChanged);trackBar1.Value= 0;trackBar1.ValueChanged+= newSystem.EventHandler(trackBar1_ValueChanged);trackBar1.Enabled= false;iFramePlay= 0;imageVideoOverLay.Visible= true;bPlayStop= false;}if (bPause || bPlayStop || bAbortPlayThread) return;this.labelProgress.Text =val;if (iFrameCnt > 0 && iFramePlay > 0 && iFramePlay <=iFrameCnt){trackBar1.ValueChanged-= newSystem.EventHandler(trackBar1_ValueChanged);trackBar1.Value= (int)((double)iFramePlay / (double)iFrameCnt *trackBar1.Maximum);trackBar1.ValueChanged+= newSystem.EventHandler(trackBar1_ValueChanged);}}private voidsetLableValue(){if (bPause || bAbortPlayThread) return;if(labelProgress.InvokeRequired){SetProgressLabel d= newSetProgressLabel(SetStatuslabel);object[] arg = new object[] { labelValue };//要传入的参数值this.Invoke(d, arg);}else{SetStatuslabel(labelValue);}}private void btnOpen_Click(objectsender, EventArgs e){if(rbMainVideo.Checked){YUVWidth=width;YUVHeight=height;msPerFrameCamera=msPerFrameCameraMain;fps=fpsMain;}else{YUVWidth= videoWidth + 1;YUVHeight= videoHeight + 1;msPerFrameCamera=msPerFrameCameraBase;fps=fpsBase;}transX= YUVWidth / (videoWidth + 1);transY= YUVHeight / (videoHeight + 1);frmPlay_Resize(null, null);openFileDialog1.Filter= "Zenith视频文件(*.dat)|*.dat";openFileDialog1.FileName= "";openFileDialog1.Multiselect= false;openFileDialog1.InitialDirectory=Application.StartupPath;if (openFileDialog1.ShowDialog() ==DialogResult.OK){this.labelProgress.Text = "00:00:00/00:00:00";bAbortPlayThread= true;Thread.Sleep(200);if (playThread != null &&playThread.IsAlive){playThread.Abort();}string filename =openFileDialog1.FileName;fs= newFileStream(filename, FileMode.OpenOrCreate, FileAccess.Read);if (fs.Length <= 512){MessageBox.Show("请确认文件是否有效!" +filename);return;}if (!fs.CanRead || !fs.CanSeek){MessageBox.Show("文件不可读,请确认!" +filename);return;}imageYUV= new Image<Bgr, Byte>(YUVWidth, YUVHeight);this.Cursor =Cursors.WaitCursor;try{this.Text = "视频播放" +filename;log.ErrorFormat("视频播放" +filename);if(bPause){bPause= false;btnPause.Text= "暂停";}bPlayStop= false;bAbortPlayThread= false;btnStop.Enabled= true;btnPause.Enabled= true;trackBar1.ValueChanged-= newSystem.EventHandler(trackBar1_ValueChanged);trackBar1.Value= 0;trackBar1.ValueChanged+= newSystem.EventHandler(trackBar1_ValueChanged);trackBar1.Enabled= true;fs.Seek(0, SeekOrigin.Begin);
//获取文件长度long offset = 0;iFrameCnt= 0;byte[] intdata = new byte[4];while (fs.Length > offset + 556){fs.Read(intdata,0, 4);int frameLen = (int)(intdata[0] | intdata[1] << 8 | intdata[2] << 16 | intdata[3] << 24);offset= offset + frameLen + 556; //556 = 4 + 378 + 174
fs.Seek(offset, SeekOrigin.Begin);iFrameCnt++;}int seconds = (int)((double)iFrameCnt /fps);int h = (int)Math.Floor((double)seconds / 3600);int m = (int)Math.Floor((double)(seconds - h * 3600) / 60);int s = (int)Math.Floor((double)(seconds - h * 3600 - m * 60));sTotalTime= h.ToString().PadLeft(2, '0') + ":" + m.ToString().PadLeft(2, '0') + ":" + s.ToString().PadLeft(2, '0');this.labelProgress.Text = "00:00:00/" +sTotalTime;fs.Seek(0, SeekOrigin.Begin);playThread= new Thread(newParameterizedThreadStart(Play));playThread.IsBackground= true;playThread.Start(fs);showThread= new Thread(newThreadStart(DrawnShow));showThread.IsBackground= true;showThread.Start();}catch(System.Exception ex){log.ErrorFormat("视频初始化错误!" +ex.Message);MessageBox.Show("视频初始化错误!");}finally{this.Cursor =Cursors.Default;}}}private void btnStop_Click(objectsender, EventArgs e){labelValue= "00:00:00/00:00:00";SetLabelThread= new Thread(newThreadStart(setLableValue));SetLabelThread.IsBackground= true;SetLabelThread.Start();this.Text = "视频播放";trackBar1.ValueChanged-= newSystem.EventHandler(trackBar1_ValueChanged);trackBar1.Value= 0;trackBar1.ValueChanged+= newSystem.EventHandler(trackBar1_ValueChanged);trackBar1.Enabled= false;if (fs != null){fs.Close();fs.Dispose();}bAbortPlayThread= true;btnStop.Enabled= false;btnPause.Enabled= false;if(bPause){bPause= false;btnPause.Text= "暂停";}}

转载于:https://www.cnblogs.com/jhlong/p/6513956.html

针对监控摄像机(海康、大华等)进行手动录像的录像文件播放器功能设计相关推荐

  1. LiveGBS流媒体平台国标GB/T28181作为上级平台对接海康大华华为宇视等下级平台硬件NVR监控摄像机

    LiveGBS流媒体平台国标GB/T28181作为上级平台对接海康.大华.华为.宇视等下级平台NVR硬件监控摄像机 1.背景说明 2.部署国标平台 2.1.安装使用说明 2.2.服务器网络环境 2.3 ...

  2. LiveGBS流媒体平台GB/T28181功能-作为上级平台对接海康大华华为宇视等下级平台监控摄像机NVR硬件执法仪等GB28181设备

    LiveGBS作为上级平台对接海康大华华为宇视等下级平台监控摄像机NVR硬件执法仪等GB28181设备 1.背景说明 2.部署国标平台 2.1.安装使用说明 2.2.服务器网络环境 2.3.信令服务配 ...

  3. LiveGBS流媒体平台国标GB/T28181作为下级支持国标级联海康大华宇视华为等第三方国标平台支持对接政务公安内网国标视频平台

    LiveGBS流媒体平台国标GB/T28181作为下级支持国标级联海康大华宇视华为等第三方国标平台支持对接政务公安内网国标视频平台 1.什么是GB/T28181级联 2.搭建GB28181国标流媒体平 ...

  4. RTSP安防网络摄像头/海康大华硬盘录像机网页无插件直播方案EasyNVR出现操作和画面显示不一致问题如何优化?

    诞生背景 众所周知,EasyNVR可以将局域网/广域网上的海康/大华等网络摄像头由rtsp转换为rtmp.rtsp.hls.flv协议转换,并提供推流服务,可以将拉到的网络摄像头直接转发到流媒体服务器 ...

  5. LiveGBS流媒体平台GB/T28181功能-摄像头报警告警预案触发图片截取视频录制海康大华华为宇视等摄像头报警触发截图录像

    LiveGBS摄像头报警告警预案触发图片截取视频录制海康大华华为宇视等摄像头报警触发截图录像 1.报警信息 1.1.报警查询 1.2.配置开启报警订阅 1.2.1.国标设备编辑 1.2.2.勾选订阅项 ...

  6. LiveGBS流媒体平台国标GB/T28181功能-作为下级级联到海康大华宇视华为等第三方国标平台同样支持对接政务公安内网国标视频平台

    LiveGBS流媒体平台国标GB/T28181功能-作为下级级联到海康大华宇视华为等第三方国标平台同样支持对接政务公安内网国标视频平台 1.什么是GB/T28181级联 2.搭建GB28181国标流媒 ...

  7. LiveGBS国标GB/T28181流媒体平台功能-作为下级国标平台级联到第三方海康大华宇视华为等国标平台及其它政务公安内网国标视频平台

    LiveGBS国标GB/T28181流媒体平台功能-作为下级国标平台级联到第三方海康大华宇视华为等国标平台及其它政务公安内网国标视频平台 1.GB/T28181级联是什么 2.搭建GB28181国标流 ...

  8. 摄像头拼接技术-远超海康大华

    先来看一下海康大华 海康大华的技术挺好,但是这方面产品实用性不强,这样看对眼睛并不利,产品价格贵,造价5000以上 我们用两个枪机拼接 造价500,是不是好多了 技术应用很简单,没有必要使用华而不实的 ...

  9. Qt编写安防视频监控系统(支持win/linux/mac/海康/大华/宇视/264/265等)

    一.前言 视频监控系统在整个安防领域,已经做到了烂大街的程序,全国起码几百家公司做过类似的系统,当然这一方面的需求量也是非常旺盛的,各种定制化的需求越来越多,尤其是这几年借着人脸识别的东风,发展更加迅 ...

  10. 将海康大华宇视等网络摄像机RTSP流采用websecket和H5进行RTSP网页无插件直播点播的技术方案

    一. 背景分析 随着移动互联网时代的到来,安防监控领域为了适应互联网的发展要求,首先由国内安防监控龙头企业(海康.大华.宇视)带头先后开发了萤石云.乐橙云等互联网视频云服务,为广大个人或者企业监控用户 ...

最新文章

  1. Go 学习笔记(33)— Go 自定义类型 type(自定义结构体、结构体初始化、结构体内嵌、自定义接口)
  2. HBase读写流程、flush、文件合并、region拆分
  3. Python 内置模块之 时间模块 datetime
  4. iOS之UI--CAGradientLayer
  5. 购买大米云主机并配置php环境搭建企业网站
  6. 从计算机网络系统组成看 计算机网络可分为,从计算机网络系统组成的角度看,计算机网络可以分为 子网和资源子网。...
  7. 谁说EMC、IBM不能替换,还你一个存储虚拟化的真相!
  8. unity中计算三角形的外接圆
  9. 通过机器学习预测电网平均总负荷
  10. html语言字体如何变大,怎么把网页的字变大_怎么让html字体变大?
  11. 学python要有多少英语词汇量_学习英语到底多少词汇量够用,1年能学习到1000的词汇量吗?...
  12. 震撼,java面试题整合(良心制作)11万多字拿去。持续更新【可以收藏】
  13. 张量分解学习(一 基础铺垫)
  14. USACO2013 island travels
  15. JVM2-性能监控故障处理工具
  16. XILINX 7系列FPGA_Slice_存储器_XADC篇
  17. 电脑用户须知 忘记分级审查密码怎么办(转)
  18. 闲人闲谈PS之二十四——着重聊聊网络和活动
  19. 参加计算机社团的英语作文,2016年12月英语六级考试作文范文:参加社团
  20. C++图书馆管理系统——基于jsoncpp与windows.h

热门文章

  1. 对cocos2dx引擎的改动
  2. 我在中国图书网不愉快的购书经历!!!!!!!
  3. 神经网络第五周tutorial解析
  4. NBA帧同步网络优化
  5. 宗宁:全面解析微博财报数据爆发下的平台机会
  6. implicit assignment of unexported field
  7. mongodb基础知识_3
  8. UIBezierPath 绘制正五边形
  9. iOS9 App Thinning(应用瘦身)功能介绍
  10. 第三部分:Android 应用程序接口指南---第二节:UI---第八章 Toast通知