zoukankan      html  css  js  c++  java
  • 屏幕录像功能技术探索及分享

      很佩服录像专家软件的功能,前两天一直在尝试实现自己的屏幕录像功能,进行了技术资料搜集和技术探索实现。该技术是基于开源项目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
     本博客声明:本人的技术探索过程中,得到了国信司南公司方面物质和精神支持。今后,本人博客里的所有技术探索成果将归“无痕客”、“国信司南”和“博客园”三方共同所有,原创作品如需转载,请注明本博客声明。 
     
  • 相关阅读:
    lucene学习-创建索引
    ExtJs学习-搭建开发环境
    Struts2上传文件(1)
    使用USBWriter做U盘启动盘后U盘在盘中不显示的解决办法(轉載)
    家里旧电脑装了centos7實踐思路
    win7/win10下装centos7双系统(转载)
    美区google play礼品卡,如何正确充值到美区google play余额,并能购买游戏道具
    excel 2016 打开UTF-8编码CSV文件乱码的问题UTF-8编码CSV文件乱码的问题
    python3 writerow CSV文件多一个空行
    python3 UnicodeEncodeError: 'gbk' codec can't encode character 'xa0' in position 4400: illegal multibyte sequence
  • 原文地址:https://www.cnblogs.com/wuhenke/p/1760980.html
Copyright © 2011-2022 走看看