屏幕录像功能技术探索及分享

  很佩服录像专家软件的功能,前两天一直在尝试实现自己的屏幕录像功能,进行了技术资料搜集和技术探索实现。该技术是基于开源项目CamStudio,将作为国信司南公司的未来技术产品功能的一部分。

  技术资料搜集阶段筛选出两种有用资源:

      1)ScrRecX是ActiveX插件,商业插件,有详细的二次开发代码实例,经测试,效果很好,录制的视频会有水印,但最终未能找到破解版。ActiveX Screen Video Recorder   :

  ScrRecX Screen Video Recorder is an ActiveX component. It allows you to incorporate the video recording capabilities into your own applications.

  Main Features

  • Allows you to select a screen area or window to record.
  • Supports multiple monitors.
  • Records video as AVI or WMV.
  • Records audio and synchronizes it with video.
  • Supports various video/audio codecs.
  • Video Setup (video compressor, frame rate, and more).
  • Audio Setup (audio device, audio input, audio compressor, sample rate, bits per sample, and more).
  • Scaling video on the fly.
  • Pause/Resume modes.
  • Optionally highlights the mouse pointer.
  • The recording area can follow the mouse pointer.
  • Can display the flashing border.
  • Allows you to use the unregistered ActiveX DLL  (Example)
  • The package contains our FM Screen Capture lossless video compressor for creating demonstrations/tutorials (See FM Screen Capture codec to learn more).
  • Supports almost any language Visual Basic, C#, C++, Delphi, and more.  (Examples)
  • ScrRecX is supplied with many working examples.

      ScrRecX功能很强大,实例代码很多,方便二次开发应用,但价格也不菲,初期建议公司购买,以便以后长期使用。

     2)开源的CamStudio,是C++开源项目,提供源代码,但为提供二次开发接口,不利于应用。

  CamStudio records activity from your screen and audio from a microphone into AVI video files and can also convert the AVIs into Streaming Flash videos (SWFs) using its built-in SWF Producer. Latest Stable Version: Camstudio-2.0-w32.zip

 

  我先前花费大量的时间寻找ScrRecX的破解注册码,自己甚至使用ExploreSuite工具想破解DLL,消除视频水印,但都无功而返。改造CamStudio对我个人来说,是有很大困难的,比较不太熟悉C++。正当我彷徨时,发现让我柳暗花明的消息,原来CamStudio有命令行版的CamStudio Command Line V0.1 Released,这样就可以被WINFORM程序调用啦。下载:http://camstudio.org/CamStudio_cl.01.zip

命令行截图如:

屏幕录像功能技术探索及分享

该工具需要三个参数:codec(视频编码,有下面0-14种编码方式)、outputfile(输出的AVI的完整路径)、 seconds(指定录制时间几秒,该项可缺省,缺省时需要输入ENTER键,才能停止输出)

测试命令行代码:C:\camstudio_cl.exe -codec 5 -outfile C:\12345.avi -seconds 10

                        C:\camstudio_cl.exe -codec 5 -outfile C:\12345.avi (需要手动输入enter结束视频录制)

          技术探索实现:winform 调用camstudio_cl.exe

 

该实验程序只是验证了可行性,将技术路线摸清了。在做实验程序中遇到最大的问题是:主程序如何与另一线程的camstudio_cl.exe进行通信?即如何向camstudio_cl.exe输入ENTER键结束屏幕录像。

          开始录像部分关键代码:

代码
          private   void  BeginScreenRecord() 
        {
            
string  RecordArguments  =   @"  -codec 5 -outfile  "   +  _VideoPath;
            
// 要调用外部程序的相对路径
            p.StartInfo.FileName  =  _RecorderPath;
            
// 参数
             p.StartInfo.Arguments  =  RecordArguments;
            
// 不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
           p.StartInfo.UseShellExecute  =   false ;
            
// 不创建进程窗口
             p.StartInfo.CreateNoWindow  =   true ;
            p.StartInfo.WindowStyle 
=  ProcessWindowStyle.Hidden;
            p.Start();
// 启动线程
        }

 

               关键是如何与另一进程程序进行交互,这里涉及到WIN32 API 编程(请参照:http://www.cnblogs.com/wuhenke/archive/2010/04/13/1711380.html),我花费了四个小时左右时间来实验探索,主要困扰在是使用SendMessage / PostMessage 还是PostThreadMessage。经测试,这里只能使用PostMessage发消息才能结束视频录制。

SendMessage Function
Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.

PostMessage Function
Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.To post a message in the message queue associated with a thread, use the PostThreadMessage function.

PostThreadMessage Function

Posts a message to the message queue of the specified thread. It returns without waiting for the thread to process the message.

 PostMessage和SendMessage的区别
1, PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数。而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息投放函数。而且,PostMessage的返回值表示PostMessage函数执行是否正确;而SendMessage的返回值表示其他程序处理消息后的返回值。这点大家应该都明白。 2, 如果在同一个线程内,PostMessage发送消息时,消息要先放入线程的消息队列,然后通过消息循环Dispatch到目标窗口。SendMessage发送消息时,系统直接调用目标窗口的消息处理程序,并将结果返回。SendMessage在同一线程中发送消息并不入线程消息队列。 如果在不同线程内。最好用PostThreadMessage代替PostMessage,他工作的很好。SendMessage发送消息到目标窗口所属的线程的消息队列,然后发送消息的线程等待(事实上,他应该还在做一些监测工作,比如监视QS_SENDMESSAGE标志),直到目标窗口处理完并且结果返回,发送消息的线程才继续运行。这是SendMessage的一般情况,事实上,处理过程要复杂的多。比如,当发送消息的线程监测到有别的窗口SendMessage一个消息到来时,他直接调用窗口处理过程(重入),并将处理结果返回(这个过程不需要消息循环中GetMessage等的支持)。 3, msdn: If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters can not include pointers. Otherwise, the operation will fail. 如果发送的消息码在WM_USER之下(非自定义消息)且消息参数中带有指针,那么PostMessage,SendNotifyMessage,SendMessageCallback这些异步消息发送函数将会调用失败。 最好不要用PostMessage发送带有指针参数的消息。 

摘自:http://blog.csdn.net/Aoouch/archive/2007/03/09/1525457.aspx


  结束视频录制的关键代码:

代码
       [DllImport( " user32.dll " , SetLastError  =   true )]
       
static   extern  IntPtr FindWindow( string  lpClassName,  string  lpWindowName);
       [DllImport(
" user32.dll " , SetLastError  =   true )]
       
static   extern  IntPtr PostMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
        [DllImport(
" user32.dll " )]
        [
return : MarshalAs(UnmanagedType.Bool)]
        
static   extern   bool  SetForegroundWindow(IntPtr hWnd);
        
const  UInt32 WM_KEYDOWN  = 0X100 ;
        
const  UInt32 WM_KEYUP  =   0x101 ;
        
const  UInt32 WM_CHAR  =   0X102 ;
        
const  Int32 VK_RETURN  =   0X0D // enter键代码
         ///   <summary>
        
///  结束屏幕录制
        
///   </summary>
         private   void  EndScreenRecorder()
        { 
            IntPtr hWnd 
=  FindWindow( null , _RecorderPath);
           
//   //  SetForegroundWindow(hWnd);
            PostMessage(hWnd, WM_KEYDOWN, VK_RETURN,  0 ); 
           
// 阻塞等待进程结束
            p.WaitForExit();
           
//  PostMessage(hWnd, WM_KEYUP, VK_RETURN, 0);
            p.Close(); // 关闭进程
             p.Dispose(); // 释放资源
        }

 

       希望上面的探索工作能帮网友们少走弯路!

 

      实例程序下载:下载

 

参考资料:

Enum Windows & SendMessage API  http://www.developerfusion.com/article/34/enum-windows-sendmessage-api/3/

http://msdn.microsoft.com/en-us/library/ms644944(v=VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms644946(v=VS.85).aspx

 Virtual-Key Codes   http://msdn.microsoft.com/en-us/library/ms927178.aspx

http://www.pinvoke.net/

http://sourceforge.net/projects/camstudio/

 

   补充:在实际应用中我修改了CamStudio_CL的源代码,除去codec参数设置,改为自动寻找最优视频编码;提高帧频和压缩率。修改后CamStudio_CL.exe只需要输出路径即可。——2010-6-23
 本博客声明:本人的技术探索过程中,得到了国信司南公司方面物质和精神支持。今后,本人博客里的所有技术探索成果将归“无痕客”、“国信司南”和“博客园”三方共同所有,原创作品如需转载,请注明本博客声明。 
 

 

你可能感兴趣的:(分享)