利用avicap32.dll实现的实时视频传输
直接上代码吧!
在窗体上调用的类:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms; using System.Net;
using System.Net.Sockets;
using System.Threading; namespace 实时视频传输系统
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
/// <summary>
/// 声明Camera类
/// </summary>
Camera ca = null;
//创建一个Thread实例
private Thread thread1;
//创建一个UdpClient实例
private UdpClient udpReceive;
private UdpClient udpSend;
private byte[] bytes;
//private DialogResult result;
private void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
btnStop.Enabled = true; ca = new Camera(pictureBox1.Handle, pictureBox1.Width, pictureBox1.Height);
try
{
ca.StartWebCam();
}
catch (Exception)
{
MessageBox.Show("未能初始化摄像头!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnPlay.Enabled = true;
btnStop.Enabled = false;
ca = null;
}
} private void btnStop_Click(object sender, EventArgs e)
{
try
{
ca.CloseWebcam(); btnPlay.Enabled = true;
btnStop.Enabled = false;
}
catch (Exception)
{
MessageBox.Show("摄像头关闭失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnPlay.Enabled = true;
btnStop.Enabled = false;
ca = null;
}
} private void btnClose_Click(object sender, EventArgs e)
{
try
{
ca.CloseWebcam(); btnPlay.Enabled = true;
btnStop.Enabled = false;
}
catch (Exception)
{
MessageBox.Show("摄像头关闭失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnPlay.Enabled = true;
btnStop.Enabled = false;
ca = null;
} //关闭程序
this.Close();
Application.Exit();
} private IPEndPoint ipLocalPoint;
private EndPoint RemotePoint;
private Socket mySocket;
private bool RunningFlag = false;
private void btnGetIP_Click(object sender, EventArgs e)
{
//string GetIP;
//IPAddress[] AddressList = Dns.GetHostEntry(Dns.GetHostEntry()).AddressList;
//if (AddressList.Length < 1)
//{
// return "";
//}
//return AddressList[0].ToString();
//this.tbGetIP.Text = Convert.ToInt32(AddressList);
}
//IP与端口号有效验证
private int getValidPort(string port)
{
int lport;
//测试端口号是否有效
try
{
//是否为空
if (port == "")
{
throw new ArgumentException("端口号无效,不能启动UDP");
}
lport = System.Convert.ToInt32(port);
}
catch(Exception e)
{
Console.WriteLine("无效的端口号"+ e.ToString());
this.tbGetPort.AppendText("无效的端口号"+ e.ToString()+"\n");
return -;
}
return lport;
}
private IPAddress getValidIP(string ip)
{
IPAddress lip = null;
//测试IP是否有效
try
{
//是否为空
if (!IPAddress.TryParse(ip, out lip))
{
throw new ArgumentException("IP无效,不能启动UDP");
}
}
catch(Exception e)
{
Console.WriteLine("无效的IP:"+ e.ToString());
this.tbGetIP.AppendText("无效的IP:"+ e.ToString() +"\n");
return null;
}
return lip;
} private void MainForm_Load(object sender, EventArgs e)
{
thread1 = new Thread(new ThreadStart());
thread1.Start();
} private void btnReceive_Click(object sender, EventArgs e)
{
//在本机指定的端口接收
udpReceive = new UdpClient();
//将套接字加入组播组
udpReceive.JoinMulticastGroup(IPAddress.Parse("224.100.0.10"), );
//接收从远程主机发送过来的信息
IPEndPoint iep = new IPEndPoint(IPAddress.Any, );
while (true)
{
//ref表示引用类型的 IPPoint实例接收消息
try
{
bytes = udpReceive.Receive(ref iep);
}
catch
{
DialogResult result = MessageBox.Show("发送失败!");
}
string str = Encoding.UTF8.GetString(bytes, , bytes.Length);
string message = "来自" + iep.ToString() + "的消息";
//显示消息 并以message为消息的标题
DialogResult res = MessageBox.Show(str, message);
}
} private void btnSend_Click_1(object sender, EventArgs e)
{
//初始化UdpClient
udpSend = new UdpClient();
//实际使用时应将127.0.0.1改为服务器的远程IP
IPAddress remoteIPAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteIPEndPoint = new IPEndPoint(remoteIPAddress, );
//将发送内容转换为字节数组
byte[] bytes = System.Text.Encoding.UTF8.GetBytes();
//设置重传次数
int retry = ;
while (true)
{
try
{
udpSend.Send(bytes, bytes.Length, remoteIPEndPoint);
break;
}
catch
{
if (retry < )
{
retry++; continue;
}
else
{
DialogResult result = MessageBox.Show("发送失败!");
break;
}
}
}
} }
}
视频封装类:
using System;
using System.Collections.Generic;
using System.Text; namespace Camera.avicap
{
/// <summary>
/// Camera 的摘要说明。
/// </summary>
public class Camera
{
private IntPtr lwndC;
private IntPtr mControlPtr;
private int mWidth;
private int mHeight; // 构造函数
public Camera(IntPtr handle, int width, int height)
{
mControlPtr = handle;
mWidth = width;
mHeight = height;
} // 帧回调的委托
public delegate void RecievedFrameEventHandler(byte[] data);
public event RecievedFrameEventHandler RecievedFrame;
private AviCapture.FrameEventHandler mFrameEventHandler; // 关闭摄像头
public void CloseWebcam()
{
this.capDriverDisconnect(this.lwndC);
} // 开启摄像头
public void StartWebCam()
{
byte[] lpszName = new byte[];
byte[] lpszVer = new byte[]; AviCapture.capGetDriverDescriptionA(, lpszName, , lpszVer, );
this.lwndC = AviCapture.capCreateCaptureWindowA(lpszName, AviCapture.WS_VISIBLE + AviCapture.WS_CHILD, , , mWidth, mHeight, mControlPtr, ); if (this.capDriverConnect(this.lwndC, ))
{
this.capPreviewRate(this.lwndC, );
this.capPreview(this.lwndC, true);
AviCapture.BITMAPINFO bitmapinfo = new AviCapture.BITMAPINFO();
bitmapinfo.bmiHeader.biSize = AviCapture.SizeOf(bitmapinfo.bmiHeader);
bitmapinfo.bmiHeader.biWidth = this.mWidth;
bitmapinfo.bmiHeader.biHeight = this.mHeight;
bitmapinfo.bmiHeader.biPlanes = ;
bitmapinfo.bmiHeader.biBitCount = ;
this.capSetVideoFormat(this.lwndC, ref bitmapinfo, AviCapture.SizeOf(bitmapinfo));
this.mFrameEventHandler = new AviCapture.FrameEventHandler(FrameCallBack);
this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);
AviCapture.SetWindowPos(this.lwndC, , , , mWidth, mHeight, );
}
}
// 以下为私有函数
private bool capDriverConnect(IntPtr lwnd, short i)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_DRIVER_CONNECT, i, );
} private bool capDriverDisconnect(IntPtr lwnd)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_DRIVER_DISCONNECT, , );
} private bool capPreview(IntPtr lwnd, bool f)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_PREVIEW, f, );
} private bool capPreviewRate(IntPtr lwnd, short wMS)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_PREVIEWRATE, wMS, );
} private bool capSetCallbackOnFrame(IntPtr lwnd, AviCapture.FrameEventHandler lpProc)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_CALLBACK_FRAME, , lpProc);
} private bool capSetVideoFormat(IntPtr hCapWnd, ref AviCapture.BITMAPINFO BmpFormat, int CapFormatSize)
{
return AviCapture.SendMessage(hCapWnd, AviCapture.WM_CAP_SET_VIDEOFORMAT, CapFormatSize, ref BmpFormat);
} private void FrameCallBack(IntPtr lwnd, IntPtr lpVHdr)
{
AviCapture.VIDEOHDR videoHeader = new AviCapture.VIDEOHDR();
byte[] VideoData;
videoHeader = (AviCapture.VIDEOHDR)AviCapture.GetStructure(lpVHdr, videoHeader);
VideoData = new byte[videoHeader.dwBytesUsed];
AviCapture.Copy(videoHeader.lpData, VideoData);
if (this.RecievedFrame != null)
this.RecievedFrame(VideoData);
}
}
}
win32的avicap32.dll封装类
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text; namespace Camera.avicap
{
/// <summary>
/// AviCapture 的摘要说明。
/// </summary>
public class AviCapture
{
//通过调用acicap32.dll进行读取摄像头数据
[DllImport("avicap32.dll")]
public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
[DllImport("avicap32.dll")]
public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, FrameEventHandler lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam);
[DllImport("User32.dll")]
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
[DllImport("avicap32.dll")]
public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize); //部分常量
public const int WM_USER = 0x400;
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;
public const int SWP_NOMOVE = 0x2;
public const int SWP_NOZORDER = 0x4;
public const int WM_CAP_DRIVER_CONNECT = WM_USER + ;
public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + ;
public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + ;
public const int WM_CAP_SET_PREVIEW = WM_USER + ;
public const int WM_CAP_SET_PREVIEWRATE = WM_USER + ;
public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + ; // 结构
[StructLayout(LayoutKind.Sequential)]
//VideoHdr
public struct VIDEOHDR
{
[MarshalAs(UnmanagedType.I4)]
public int lpData;
[MarshalAs(UnmanagedType.I4)]
public int dwBufferLength;
[MarshalAs(UnmanagedType.I4)]
public int dwBytesUsed;
[MarshalAs(UnmanagedType.I4)]
public int dwTimeCaptured;
[MarshalAs(UnmanagedType.I4)]
public int dwUser;
[MarshalAs(UnmanagedType.I4)]
public int dwFlags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public int[] dwReserved;
} [StructLayout(LayoutKind.Sequential)]
//BitmapInfoHeader
public struct BITMAPINFOHEADER
{
[MarshalAs(UnmanagedType.I4)]
public Int32 biSize;
[MarshalAs(UnmanagedType.I4)]
public Int32 biWidth;
[MarshalAs(UnmanagedType.I4)]
public Int32 biHeight;
[MarshalAs(UnmanagedType.I2)]
public short biPlanes;
[MarshalAs(UnmanagedType.I2)]
public short biBitCount;
[MarshalAs(UnmanagedType.I4)]
public Int32 biCompression;
[MarshalAs(UnmanagedType.I4)]
public Int32 biSizeImage;
[MarshalAs(UnmanagedType.I4)]
public Int32 biXPelsPerMeter;
[MarshalAs(UnmanagedType.I4)]
public Int32 biYPelsPerMeter;
[MarshalAs(UnmanagedType.I4)]
public Int32 biClrUsed;
[MarshalAs(UnmanagedType.I4)]
public Int32 biClrImportant;
} [StructLayout(LayoutKind.Sequential)]
//BitmapInfo
public struct BITMAPINFO
{
[MarshalAs(UnmanagedType.Struct, SizeConst = )]
public BITMAPINFOHEADER bmiHeader;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public Int32[] bmiColors;
} public delegate void FrameEventHandler(IntPtr lwnd, IntPtr lpVHdr); // 公共函数
public static object GetStructure(IntPtr ptr, ValueType structure)
{
return Marshal.PtrToStructure(ptr, structure.GetType());
} public static object GetStructure(int ptr, ValueType structure)
{
return GetStructure(new IntPtr(ptr), structure);
} public static void Copy(IntPtr ptr, byte[] data)
{
Marshal.Copy(ptr, data, , data.Length);
} public static void Copy(int ptr, byte[] data)
{
Copy(new IntPtr(ptr), data);
} public static int SizeOf(object structure)
{
return Marshal.SizeOf(structure);
}
}
}
出处:https://bbs.csdn.net/topics/390039653
参考:
https://blog.csdn.net/NCTU_to_prove_safety/article/details/53584905
https://www.cnblogs.com/JUSTSOSOBLOG/p/4612801.html
https://blog.csdn.net/laolei1986/article/details/5730245
https://blog.csdn.net/waeceo/article/details/50222781
======================================================================================================
我使用AVICAP32.DLL来捕获图像,捕完并保存到文件后,当我关闭它后.那个黑块的窗体一直在那里,如果让它消失呢?
哈哈哈,我自己搞定了,由于那个窗体是使用API调出来的,它只是位置和大小与PANEL一样而已,因此要想控制它还是要使用API消息机制.利用它的句柄来操作它.方法如下:
public const int WM_CLOSE = 0x10;//关闭窗口句柄
//关闭摄像头
if hWndC <> 0 then
begin
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
SendMessage(hWndC, WM_CLOSE, 0, 0);
hWndC := 0;
end;OK,完事了.
======================================================================================================
前面的代码有一个事件的处理是缺失的,就是Camera类的RecievedFrame事件;怎么把接收到的byte[] VideoData数组转成图片呢?
看看下面的文章,或许对你有所启发。
得到摄像头一帧数据的字节数组之后转成图片的处理
利用avicap32.dll实现的实时视频传输的更多相关文章
- FileUpload 上传文件,并实现c#使用Renci.SshNet.dll实现SFTP文件传输
fileupload上传文件和jquery的uplodify控件使用方法类似,对服务器控件不是很熟悉,记录一下. 主要是记录新接触的sftp文件上传.服务器环境下使用freesshd搭建好环境后,wi ...
- Git学习:利用Git和TortoiseGit把代码传输到网络服务器
版本控制这块,一直用SVN.感觉挺好用,比VSS要好用些.不过,近期在网上,又谈到时下很流行的Git.就想看看Git到底是何方神圣.趁着五一在家无事,就静下心来,简单研究一下. 当下,网络上提供的基于 ...
- C# 利用BarcodeLib.dll生成条形码(一维,zxing,QrCodeNet/dll二维码)
原文:http://blog.csdn.net/kongwei521/article/details/17588825 首先效果: 一.下载BarcodeLib.dll 下载地址 :http://do ...
- C# 利用BarcodeLib.dll生成条形码
首先效果: 1:首先下载BarcodeLib.dll 下载地址 http://pan.baidu.com/share/link?shareid=2590968386&uk=2148890391 ...
- C#.net 摄像头驱动程序,用avicap32.dll
装了摄像头后一般会有 avicap32.dll文件,没有一样可以用这些代码. 不需要在解决方案里面引用这个.dll文件. 下面有二种写法的例子: 例一: using System;using Syst ...
- winform利用itextsharp.dll实现图片文件转换PDF格式文件
1.利用itextsharp.dll实现单个图片文件转换为PDF格式文件, 可以使用以下类: void ConvertJPG2PDF(string jpgfile, string pdf) { var ...
- 视频运行库AVICAP32.DLL说明收藏
视频运行库AVICAP32.DLL说明收藏2008-09-28 09:04 // ----------------------------------------------------------- ...
- 利用破解dll来获取到一个软件的注册码
---恢复内容开始--- 首先做这个事是纯属于个人研究而已,请勿以侵犯他人劳动成果. 今天看到了一个关于IL语句的文章,于是就学学,然后实践实践下.废话不多说了. 1.安装好某一个需要注册才可以的使用 ...
- 利用URLRewriter.dll 实现ASP.NET实现伪静态
大家一定经常在网络上看到很多网站的地址后缀都是用XX.HTML或者XX.ASPX等类似静态文件的标示来操作的吧,那么大家有怀疑过他真的是一个一个的静态生成的文件么,静态文件的生成的优缺有好有坏,对于访 ...
随机推荐
- 【Spring Boot学习之二】WEB开发
环境 Java1.8 Spring Boot 1.3.2 一.静态资源访问 动静分离:动态服务和前台页面图片分开,静态资源可以使用CDN加速;Spring Boot默认提供静态资源目录位置需置于cla ...
- docker相关内容
原文地址:https://www.cnblogs.com/zhuochong/category/1310443.html
- dedecms原理及使用
dedecms原理 简单使用 现在老板要求你做一个文章管理系统,栏目(类别)包括(武侠.爱情.音乐...) ,每个栏目(类别)有对应的文章,文章已经给你准备好了,请你在30分钟搞定该网站,怎么样? 步 ...
- 解决 plsql 启动报错 Initialization error
由于文件 oci.dll 路径没添加 1.点击edit 2.点击PL/SQL 3.弹框中 填写oci.dll文件的完整路径!完整路径!完整路径!完整路径!完整路径!完整路径!完整路径!完整路径 ...
- 【笔试题】Java Data Types
Java 知识测试 Java Data Types Question 1 Predict the output of the following program. class Test { publi ...
- go ---变量数据结构调试利器 go-spew
我们在使用Golang(Go语言)开发的过程中,会通过经常通过调试的方式查找问题的原因,解决问题,尤其是当遇到一个很棘手的问题的时候,就需要知道一段代码在执行的过程中,其上下文的变量对应的数据,以便进 ...
- IDEA debug断点调试技巧
Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...
- Linux 服务器 关闭FTP匿名访问
service vsftpd status //查看FTP运行状态 vim /etc/vsftpd/vsftpd.conf //修改配置文件 找到vsftpd.conf中的 anonymous_ena ...
- ASP.NET Nlog上手练习小例子
添加NuGet程序包- Nlog Nlog.Web.AspNetCore 两个包. public void Configure(IApplication ...
- Angular复习笔记5-指令
Angular复习笔记5-指令 在Angular中,指令是一个重要的概念,它作用在特定的DOM元素上,可以扩展这个元素的功能,为元素增加新的行为.本质上,组件可以被理解为一种带有视图的指令.组件继承自 ...