利用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 -1;
}
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(8001);
//将套接字加入组播组
udpReceive.JoinMulticastGroup(IPAddress.Parse("224.100.0.10"), 50);
//接收从远程主机发送过来的信息
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
//ref表示引用类型的 IPPoint实例接收消息
try
{
bytes = udpReceive.Receive(ref iep);
}
catch
{
DialogResult result = MessageBox.Show("发送失败!");
}
string str = Encoding.UTF8.GetString(bytes, 0, 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, 8002);
//将发送内容转换为字节数组
byte[] bytes = System.Text.Encoding.UTF8.GetBytes();
//设置重传次数
int retry = 0;
while (true)
{
try
{
udpSend.Send(bytes, bytes.Length, remoteIPEndPoint);
break;
}
catch
{
if (retry < 3)
{
retry++; continue;
}
else
{
DialogResult result = MessageBox.Show("发送失败!");
break;
}
}
}
}
}
}
请各位大鸟指正,非常感谢! --------------------编程问答-------------------- using System;
using System.Runtime.InteropServices;
namespace 实时视频传输系统
{
/// <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[100];
byte[] lpszVer = new byte[100];
AviCapture.capGetDriverDescriptionA(0, lpszName, 100,lpszVer, 100);
this.lwndC = AviCapture.capCreateCaptureWindowA(lpszName, AviCapture.WS_VISIBLE + AviCapture.WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);
if (this.capDriverConnect(this.lwndC, 0))
{
this.capPreviewRate(this.lwndC, 66);
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 = 1;
bitmapinfo.bmiHeader.biBitCount = 24;
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, 0, 0, 0, mWidth , mHeight , 6);
}
}
// 以下为私有函数
private bool capDriverConnect(IntPtr lwnd, short i)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_DRIVER_CONNECT, i, 0);
}
private bool capDriverDisconnect(IntPtr lwnd)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_DRIVER_DISCONNECT, 0, 0);
}
private bool capPreview(IntPtr lwnd, bool f)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_PREVIEW, f, 0);
}
private bool capPreviewRate(IntPtr lwnd, short wMS)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_PREVIEWRATE, wMS, 0);
}
private bool capSetCallbackOnFrame(IntPtr lwnd, AviCapture.FrameEventHandler lpProc)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_CALLBACK_FRAME, 0, 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);
}
}
} --------------------编程问答-------------------- using System;
using System.Runtime.InteropServices;
namespace 实时视频传输系统
{
/// <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 + 10;
public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;
public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5;
public const int WM_CAP_SET_PREVIEW = WM_USER + 50;
public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;
public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;
// 结构
[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 = 4)]
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 = 40)]
public BITMAPINFOHEADER bmiHeader;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
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, 0, 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);
}
}
}
补充:.NET技术 , C#