C# 摄像头录像问题

kmkjwjf 2009-10-27 09:52:59
怎么通过代码控制压缩比?目前我已经可以通过API调出那个调整压缩比的界面,也可以手动调整压缩比?但是这个功能能否直接用底层API实现?
我是通过avicap32.dll中的API实现的。

不压缩的话,实在太恐怖了,4分钟的视频,都达到500M了。要是录个1小时,还得了!
...全文
659 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
kmkjwjf 2009-10-29
  • 打赏
  • 举报
回复
1234567890-
liyoubaidu 2009-10-28
  • 打赏
  • 举报
回复
up
aotian798 2009-10-27
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.Windows.Forms;
namespace ServerDLL
{
public class ClassSave
{
private static ClassVedioCapture VC = new ClassVedioCapture();
public static void Save(System.Drawing.Image i)
{
ImageCodecInfo ici;
Encoder enc;
EncoderParameter ep;
EncoderParameters epa;

try
{
// Initialize the necessary objects
ici = ClassEncode.GetEncoderInfo("image/jpeg");
enc = Encoder.Quality;//设置保存质量
epa = new EncoderParameters(1);

// Set the compression level
ep = new EncoderParameter(enc, 15L);//质量等级为25%
epa.Param[0] = ep;
//i.Save(Application.StartupPath + "\\test.jpg", ici, epa);
i.Save(Application.StartupPath + "\\test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
i.Dispose();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

}

}
}
aotian798 2009-10-27
  • 打赏
  • 举报
回复
using System;
using System.Runtime.InteropServices;

namespace ServerDLL
{
///
/// avicap 的摘要说明。
///
public class ClassShowVideo
{
// ClassShowVideo calls
[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 );

// Constants
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;

// Structures
[StructLayout(LayoutKind.Sequential)] 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)] 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)] 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 methods
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);
}
}

//Web Camera Class
public class WebCamera
{
// Constructur
public WebCamera(IntPtr handle, int width,int height)
{
mControlPtr = handle;
mWidth = width;
mHeight = height;
}

// delegate for frame callback
public delegate void RecievedFrameEventHandler(byte[] data);
public event RecievedFrameEventHandler RecievedFrame;

private IntPtr lwndC; // Holds the unmanaged handle of the control
private IntPtr mControlPtr; // Holds the managed pointer of the control
private int mWidth;
private int mHeight;

private ClassShowVideo.FrameEventHandler mFrameEventHandler; // Delegate instance for the frame callback - must keep alive! gc should NOT collect it

// Close the web camera
public void CloseWebcam()
{
this.capDriverDisconnect(this.lwndC);
}

// start the web camera
public void StartWebCam()
{
byte[] lpszName = new byte[100];
byte[] lpszVer = new byte[100];

ClassShowVideo.capGetDriverDescriptionA(0, lpszName, 100,lpszVer, 100);
this.lwndC = ClassShowVideo.capCreateCaptureWindowA(lpszName, ClassShowVideo.WS_VISIBLE + ClassShowVideo.WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);

if (this.capDriverConnect(this.lwndC, 0))
{
this.capPreviewRate(this.lwndC, 66);
this.capPreview(this.lwndC, true);
ClassShowVideo.BITMAPINFO bitmapinfo = new ClassShowVideo.BITMAPINFO();
bitmapinfo.bmiHeader.biSize = ClassShowVideo.SizeOf(bitmapinfo.bmiHeader);
bitmapinfo.bmiHeader.biWidth = 352;
bitmapinfo.bmiHeader.biHeight = 288;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biBitCount = 24;
this.capSetVideoFormat(this.lwndC, ref bitmapinfo, ClassShowVideo.SizeOf(bitmapinfo));
this.mFrameEventHandler = new ClassShowVideo.FrameEventHandler(FrameCallBack);
this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);
ClassShowVideo.SetWindowPos(this.lwndC, 0, 0, 0, mWidth , mHeight , 6);
}
}

// private functions
private bool capDriverConnect(IntPtr lwnd, short i)
{
return ClassShowVideo.SendMessage(lwnd, ClassShowVideo.WM_CAP_DRIVER_CONNECT, i, 0);
}

private bool capDriverDisconnect(IntPtr lwnd)
{
return ClassShowVideo.SendMessage(lwnd, ClassShowVideo.WM_CAP_DRIVER_DISCONNECT, 0, 0);
}

private bool capPreview(IntPtr lwnd, bool f)
{
return ClassShowVideo.SendMessage(lwnd, ClassShowVideo.WM_CAP_SET_PREVIEW , f, 0);
}

private bool capPreviewRate(IntPtr lwnd, short wMS)
{
return ClassShowVideo.SendMessage(lwnd, ClassShowVideo.WM_CAP_SET_PREVIEWRATE, wMS, 0);
}

private bool capSetCallbackOnFrame(IntPtr lwnd, ClassShowVideo.FrameEventHandler lpProc)
{
return ClassShowVideo.SendMessage(lwnd, ClassShowVideo.WM_CAP_SET_CALLBACK_FRAME, 0, lpProc);
}

private bool capSetVideoFormat(IntPtr hCapWnd, ref ClassShowVideo.BITMAPINFO BmpFormat, int CapFormatSize)
{
return ClassShowVideo.SendMessage(hCapWnd, ClassShowVideo.WM_CAP_SET_VIDEOFORMAT, CapFormatSize, ref BmpFormat);
}

private void FrameCallBack(IntPtr lwnd, IntPtr lpVHdr)
{
ClassShowVideo.VIDEOHDR videoHeader = new ClassShowVideo.VIDEOHDR();
byte[] VideoData;
videoHeader = (ClassShowVideo.VIDEOHDR)ClassShowVideo.GetStructure(lpVHdr,videoHeader);
VideoData = new byte[videoHeader.dwBytesUsed];
ClassShowVideo.Copy(videoHeader.lpData ,VideoData);
if (this.RecievedFrame != null)
this.RecievedFrame (VideoData);
}
}

}

aotian798 2009-10-27
  • 打赏
  • 举报
回复
我有例子我找找看 你加我QQ651786338
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
高手来啊
thunderwolf 2009-10-27
  • 打赏
  • 举报
回复
帮顶
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 l171147904 的回复:]
有第三方开发的 图片 或 视频压缩 技术

控件
[/Quote]
的确,是调用的第三方视频压缩技术在进行压缩。问题是,这个调用的东西,必须是在开始录像之前设置好的。在录像过程中是无法设置的。所以,我的目的是想在开始录像的时候,就给一个默认的压缩技术它。

或者说是我想更改它默认的压缩技术。因为默认的压缩技术和压缩比,根本不压缩什么。一个4分钟的视频都有500M

目前打开这个压缩对话框后,显示的可用压缩技术有Cinepak Codec by Radius、Intel Indeo (R) Video R3.2、Intel IYUV Codec和Microsoft Video 1.而默认的压缩时采用Cinepak Codec by Radius,100%的压缩比。
NewUser2008 2009-10-27
  • 打赏
  • 举报
回复
WinRAR
limii 2009-10-27
  • 打赏
  • 举报
回复
up
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
ding
l171147904 2009-10-27
  • 打赏
  • 举报
回复
有第三方开发的 图片 或 视频压缩 技术

控件
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
不要沉啊,不要沉
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
不要沉了
llj821215 2009-10-27
  • 打赏
  • 举报
回复

suners 2009-10-27
  • 打赏
  • 举报
回复
雄姿也在做这个啊
bryht 2009-10-27
  • 打赏
  • 举报
回复
帮着顶下,没搞过这个
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
ding
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
公司不让上QQ,烦死了。

另外以上代码中ShowVideo和ClassShowVideo是同一个类。。。。。。。
kmkjwjf 2009-10-27
  • 打赏
  • 举报
回复
谢谢楼上的回复,但是你的代码看起来没有解决实际问题。我的代码其实和你的差不多,但是也有不同。
在ClassShowVideo这个类中,我还多了一个CapturePara的结构体,用于设定捕捉视频时的参数
[StructLayout(LayoutKind.Sequential)]
public struct CAPTUREPARAMS
{
public int dwRequestMicroSecPerFrame; // Requested capture rate
public bool fMakeUserHitOKToCapture; // Show "Hit OK to cap" dlg?
public uint wPercentDropForError; // Give error msg if > (10%)
public bool fYield; // Capture via background task?
public int dwIndexSize; // Max index size in frames (32K)
public uint wChunkGranularity; // Junk chunk granularity (2K)
public bool fUsingDOSMemory; // Use DOS buffers?
public uint wNumVideoRequested; // # video buffers, If 0, autocalc
public bool fCaptureAudio; // Capture audio?
public uint wNumAudioRequested; // # audio buffers, If 0, autocalc
public uint vKeyAbort; // Virtual key causing abort
public bool fAbortLeftMouse; // Abort on left mouse?
public bool fAbortRightMouse; // Abort on right mouse?
public bool fLimitEnabled; // Use wTimeLimit?
public uint wTimeLimit; // Seconds to capture
public bool fMCIControl; // Use MCI video source?
public bool fStepMCIDevice; // Step MCI device?
public int dwMCIStartTime; // Time to start in MS
public int dwMCIStopTime; // Time to stop in MS
public bool fStepCaptureAt2x; // Perform spatial averaging 2x
public uint wStepCaptureAverageFrames; // Temporal average n Frames
public int dwAudioBufferSize; // Size of audio bufs (0 = default)
public bool fDisableWriteCache; // Attempt to disable write cache
public uint AVStreamMaster; // Which stream controls length?
}


另外,在WebCamera类中的StartCamera中,会对这个结构体进行初始化。我觉得,这个地方应该是设置压缩比的地方,但是仔细看了下CapturePara这个结构,并没有属性时设置压缩的。
        public void StartWebCam()
{
byte[] lpszName = new byte[100];
byte[] lpszVer = new byte[100];

ClassShowVideo.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);
this.lwndC = ClassShowVideo.capCreateCaptureWindowA(lpszName, showVideo.WS_VISIBLE + showVideo.WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);
//showVideo.CAPTUREPARAMS CaptureParams = new showVideo.CAPTUREPARAMS();
//this.lwndC = showVideo.capCreateCaptureWindowA(lpszName, showVideo.WS_DISALBED + showVideo.WS_CHILD + showVideo.WS_MINIMIZE, 0, 0, mWidth, mHeight, mControlPtr, 0);
ClassShowVideo.CAPTUREPARAMS CaptureParams = new ClassShowVideo.CAPTUREPARAMS();

if (this.capDriverConnect(this.lwndC, 0))
{
this.cappreviewrate(this.lwndC, 100);
ClassShowVideo.SendMessage(this.lwndC, showVideo.WM_CAP_GET_SEQUENCE_SETUP, Marshal.SizeOf(CaptureParams), ref CaptureParams);
CaptureParams.fAbortLeftMouse = false;
CaptureParams.fAbortRightMouse = false;
CaptureParams.fCaptureAudio = false;
CaptureParams.fYield = true;
//CaptureParams.vKeyAbort = 0;
CaptureParams.dwRequestMicroSecPerFrame = 1000000 / 10;
ClassShowVideo.SendMessage(this.lwndC, ClassShowVideo.WM_CAP_SET_SEQUENCE_SETUP, Marshal.SizeOf(CaptureParams), ref CaptureParams);
this.capPreview(this.lwndC, true);
ClassShowVideo.bitmapinfo bitmapinfo = new ClassShowVideo.bitmapinfo();
bitmapinfo.bmiHeader.biSize = ClassShowVideo.SizeOf(bitmapinfo.bmiHeader);
bitmapinfo.bmiHeader.biWidth = mWidth;
bitmapinfo.bmiHeader.biHeight = mHeight;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biBitCount = 24;
this.capsetvideoformat(this.lwndC, ref bitmapinfo, ClassShowVideo.SizeOf(bitmapinfo));

//CompressDialog();

this.mFrameEventHandler = new ClassShowVideo.FrameEventHandler(framecallback);
this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);
ClassShowVideo.SetWindowPos(this.lwndC, 0, 0, 0, mWidth, mHeight, 6);
//showVideo.SetWindowPos(this.lwndC, 0, 0, 0, mWidth, mHeight, 0x80);
}
else
{
throw new Exception("No camera device is detected, please check the camera connection.");
}
}


而我录像和停止录像的代码如下,是在WebCamera类中的
 //录像
private void GetVideo(IntPtr lwnd, string path)
{
IntPtr hVideo = Marshal.StringToHGlobalAnsi(path);
showVideo.SendMessage(lwnd, showVideo.WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hVideo.ToInt32());
showVideo.SendMessage(lwnd, showVideo.WM_CAP_SEQUENCE, 0, 0);
}
//停止录像
private void StopGetVideo(IntPtr lwnd)
{
showVideo.SendMessage(lwnd, showVideo.WM_CAP_STOP, 0, 0);
}

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧