这是通过Tcp以最简单的方式发送图像作为视频流的方法。该方法可以发送和接收视频流。此方法基于Windows表单。
发送流(服务器):
private void Start_Sending_Video_Conference(string remote_IP, int port_number)
{
try
{
ms = new MemoryStream();
IDataObject data;
Image bmap;
SendMessage(hHwnd, WM_CAP_EDIT_COPY, 0, 0);
data = Clipboard.GetDataObject();
if (data.GetDataPresent(typeof(System.Drawing.Bitmap)))
{
bmap = ((Image)(data.GetData(typeof(System.Drawing.Bitmap))));
bmap.Save(ms, ImageFormat.Bmp);
}
picCapture.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] arrImage = ms.GetBuffer();
myclient = new TcpClient(remote_IP, 5000);
myns = myclient.GetStream();
mysw = new BinaryWriter(myns);
mysw.Write(arrImage);
ms.Flush();
mysw.Flush();
myns.Flush();
ms.Close();
mysw.Close();
myns.Close();
myclient.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Video Conference Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
接收流(客户端):
private void Start_Receiving_Video_Conference()
{
try
{
mytcpl = new TcpListener(5000);
mytcpl.Start();
mysocket = mytcpl.AcceptSocket();
ns = new NetworkStream(mysocket);
picture_comming.Image = Image.FromStream(ns);
mytcpl.Stop();
if (mysocket.Connected == true)
{
while (true)
{
Start_Receiving_Video_Conference();
}
}
myns.Flush();
}
catch (Exception) { button1.Enabled = true; myth.Abort(); }
}
非托管引用:
[System.Runtime.InteropServices.DllImport("user32", EntryPoint="SendMessageA")]
static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)]
object lParam);
[System.Runtime.InteropServices.DllImport("user32", EntryPoint="SetWindowPos")]
static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
[System.Runtime.InteropServices.DllImport("user32")]
static extern bool DestroyWindow(int hndw);
[System.Runtime.InteropServices.DllImport("avicap32.dll")]
static extern int capCreateCaptureWindowA(string lpszWindowName, int dwStyle, int x, int y, int nWidth, short nHeight, int hWndParent, int nID);
[System.Runtime.InteropServices.DllImport("avicap32.dll")]
static extern bool capGetDriverDescriptionA(short wDriver, string lpszName, int cbName, string lpszVer, int cbVer);
在服务器上预览网络摄像头图像的方法
这个方法应该首先启动,以初始化网络摄像头的预览(在服务器端)。
private void OpenPreviewWindow()
{
int iHeight = 259;
int iWidth = 369;
hHwnd = capCreateCaptureWindowA(iDevice.ToString (), (WS_VISIBLE | WS_CHILD), 0, 0, 640, 480, picCapture.Handle.ToInt32(), 0);
if (SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, iDevice, 0) == 1)
{
SendMessage(hHwnd, WM_CAP_SET_SCALE, 1, 0);
SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(hHwnd, WM_CAP_SET_PREVIEW, 1, 0);
SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, iWidth,iHeight, (SWP_NOMOVE | SWP_NOZORDER));
}
else
{
DestroyWindow(hHwnd);
}
}
结束预览:
private void ClosePreviewWindow()
{
SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, iDevice, 0);
DestroyWindow(hHwnd);
}
网络摄像头 API
const short WM_CAP = 1024;
const int WM_CAP_DRIVER_CONNECT = WM_CAP + 10;
const int WM_CAP_DRIVER_DISCONNECT = WM_CAP + 11;
const int WM_CAP_EDIT_COPY = WM_CAP + 30;
const int WM_CAP_SET_PREVIEW = WM_CAP + 50;
const int WM_CAP_SET_PREVIEWRATE = WM_CAP + 52;
const int WM_CAP_SET_SCALE = WM_CAP + 53;
const int WS_CHILD = 1073741824;
const int WS_VISIBLE = 268435456;
const short SWP_NOMOVE = 2;
const short SWP_NOSIZE = 1;
const short SWP_NOZORDER = 4;
const short HWND_BOTTOM = 1;
如有任何疑问,请随时提出。