C#实现屏幕录像 网上看到的看起来不错

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WMEncoderLib;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Threading;
using System.IO;
using System.Drawing.Drawing2D;

        有关系统托盘#region 有关系统托盘
        /** <summary>
        /// 托盘图标类实例
        /// </summary>
        private NotifyIcon notifyIcon;
        /** <summary>
        /// 托盘菜单
        /// </summary>
        private ContextMenu notificationMenu;
        /** <summary>
        /// 初始化托盘
        /// </summary>
        public void NotificationIcon()
        {
            notifyIcon = new NotifyIcon();
            notificationMenu = new ContextMenu(InitializeMenu());
            notifyIcon.DoubleClick += IconDoubleClick;
            notifyIcon.Icon = this.Icon;
            notifyIcon.ContextMenu = notificationMenu;
            notifyIcon.Visible = true;
        }
        /** <summary>
        /// 托盘菜单
        /// </summary>
        /// <returns></returns>
        private MenuItem[] InitializeMenu()
        {
            //加载主题菜单
            MenuItem SkinMenu = new MenuItem("主题");
            DirectoryInfo dir = new DirectoryInfo(Application.StartupPath + "//Skin");
            foreach (FileInfo skinfile in dir.GetFiles())
            {
                string skinname = skinfile.Name.Substring(0, (int)skinfile.Name.Length - 4);
                SkinMenu.MenuItems.Add(new MenuItem(skinname, ChangeSkin));
            }
            //
            //
            MenuItem[] menu = new MenuItem[]
            {
                new MenuItem("显示主窗口", IconDoubleClick),
                new MenuItem("隐藏主窗口", HideMainForm),
                SkinMenu,
    new MenuItem("关于", menuAboutClick),
    new MenuItem("退出", menuExitClick)
   };
            return menu;
        }
                    托盘事件#region 托盘事件
                    /** <summary>
                    /// 托盘关于菜单
                    /// </summary>
                    /// <param name="sender"></param>
                    /// <param name="e"></param>
                    private void menuAboutClick(object sender, EventArgs e)
                    {

                        if (about == null || about.IsDisposed)
                            about = new About();
                        about.Show();
                    }
                    /** <summary>
                    /// 托盘退出菜单
                    /// </summary>
                    /// <param name="sender"></param>
                    /// <param name="e"></param>
                    private void menuExitClick(object sender, EventArgs e)
                    {
                        this.notifyIcon.Visible = false;
                        Application.Exit();
                    }
                    /** <summary>
                    /// 双击托盘图标显示主窗口
                    /// </summary>
                    /// <param name="sender"></param>
                    /// <param name="e"></param>
                    private void IconDoubleClick(object sender, EventArgs e)
                    {
                        this.Visible = true;
                        this.WindowState = FormWindowState.Normal;
                    }
                    /** <summary>
                    /// 隐藏主窗口
                    /// </summary>
                    /// <param name="sender"></param>
                    /// <param name="e"></param>
                    private void HideMainForm(object sender, EventArgs e)
                    {
                        this.WindowState = FormWindowState.Minimized;
                        this.Visible = false;
                    }
                    /** <summary>
                    /// 改变风格
                    /// </summary>
                    /// <param name="sender"></param>
                    /// <param name="e"></param>
                    private void ChangeSkin(object sender, EventArgs e)
                    {
                        string skinname = ((MenuItem)sender).Text;
                        SetSkin(skinname);
                        ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
                        appseting.UpdateKey("skin", skinname);
                    }
                    #endregion
        #endregion

        Win32#region Win32
        [DllImport("user32")]
        static extern IntPtr SetCapture(IntPtr hwnd);
        [DllImport("user32")]
        static extern IntPtr ReleaseCapture();
        [DllImport("user32.dll")]
        static extern IntPtr WindowFromPoint(IntPtr xPoint, IntPtr yPoint);
        [DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hWnd);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
            public int Width() { return right - left; }
            public int Height() { return bottom - top; }
        }

        [DllImport("user32.dll")]
        // 注意,运行时知道如何列集一个矩形
        static extern IntPtr GetWindowRect(IntPtr hwnd, ref RECT rc);
        [DllImport("user32.dll")]
        static extern IntPtr PostMessage(IntPtr hWnd, IntPtr iMsg, IntPtr wParam, IntPtr lParam);
        #endregion

        成员#region 成员
        private WMEncoder enc;
        IWMEncSourcePluginInfoManager wspim;
        Rectangle lastrect = new Rectangle(0, 0, 0, 0);
        private About about;
        public fScreen screen;
        private Thread th;
        private delegate void VoidDelegate();
        #endregion

        /**
        /// <summary>
        /// 程序初始化
        /// </summary>
        private void AppInit()
        {
            enc = new WMEncoderClass();
            LoadSeting();
        }
        /** <summary>
        /// 设置皮肤
        /// </summary>
        /// <param name="SkinName"></param>
        private void SetSkin(string SkinName)
        {
            this.skin.SerialNumber = "";
            this.skin.SkinFile = "Skin//" + SkinName + ".ssk";
        }
        /** <summary>
        /// 初始压缩选项列表
        /// </summary>
        private void InitCompression()
        {
            //
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            string Compression = appseting.ReadKeyValue("Compression");
            //
            enc = new WMEncoderClass();
            wspim = enc.SourcePluginInfoManager;
            wspim.Refresh();
            IWMEncProfileCollection wpfc = enc.ProfileCollection;
            IWMEncProfile wp;
            this.CompressionOptionListBox.Items.Clear();
            for (int i = 0; i < wpfc.Count; i++)
            {
                wp = wpfc.Item(i);
                this.CompressionOptionListBox.Items.Add(wp.Name);
                if (wp.Name == Compression)
                    this.CompressionOptionListBox.SelectedIndex = i;
            }

        }
        /** <summary>
        /// 加载设置
        /// </summary>
        private void LoadSeting()
        {
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            //是否录制声音
           this.ChkSound.Checked =Convert.ToBoolean(appseting.ReadKeyValue("ChkSound"));
            //是否隐藏主窗体
           this.ChkHideMainForm.Checked = Convert.ToBoolean(appseting.ReadKeyValue("ChkHideMainForm"));
            //快捷键设置
           this.SkStartAndPause.Text = appseting.ReadKeyValue("SKey_StartAndPause");
           this.SkStop.Text = appseting.ReadKeyValue("SKey_Stop");
           this.SkShowAndHide.Text = appseting.ReadKeyValue("SKey_ShowAndHide");
            //录制区域
           int rect = Convert.ToInt32(appseting.ReadKeyValue("CameraRect"));
           if (rect == 1)
               this.RWindow.Checked = true;
           else
               this.RScreen.Checked = true;
            //
           Size sz = MainForm.GetScreenSize();
           this.rw.Text  = sz.Width.ToString();
           this.rh.Text = sz.Height.ToString();
        }
        /** <summary>
        /// 取得选择的压缩选项
        /// </summary>
        /// <returns></returns>
        private IWMEncProfile2 GetSelectCompressionOption()
        {
            IWMEncProfileCollection wpfc = enc.ProfileCollection;
            IWMEncProfile wp;
            IWMEncProfile2 wp2 = new WMEncProfile2Class();
            if (this.CompressionOptionListBox.SelectedIndex == -1)
            {
                return null;
            }
            for (int i = 0; i < wpfc.Count; i++)
            {
                wp = wpfc.Item(i);

                if (this.CompressionOptionListBox.SelectedItem.ToString() == wp.Name)
                {
                    wp2.LoadFromIWMProfile(wp);
                    return wp2;
                }
            }
            return null;
        }
        /** <summary>
        /// 开始录制
        /// </summary>
        private void StartCamera()
        {
            IWMEncSourceGroupCollection SrcGrpColl;
            IWMEncSourceGroup2 SrcGrp;
            IWMEncAudioSource SrcAud;
            IWMEncVideoSource2 SrcVid;
            IWMEncProfile2 Pro;
            enc = new WMEncoderClass();
            //-------------------------------------------
            try
            {
                SrcGrpColl = enc.SourceGroupCollection;
                SrcGrp = (IWMEncSourceGroup2)SrcGrpColl.Add("SG_1");
                SrcVid = (IWMEncVideoSource2)SrcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_VIDEO);

                //是否录制声音
                if (this.ChkSound.Checked)
                {
                    SrcAud = (IWMEncAudioSource)SrcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
                    SrcAud.SetInput("Default_Audio_Device", "DEVICE", "");
                }
                SrcVid.SetInput("ScreenCapture1", "ScreenCap", "");

                指定屏幕区域录制#region 指定屏幕区域录制
                if (this.RectCustom.Checked)
                {
                    Size priScreen = SystemInformation.PrimaryMonitorSize;

                    float xx = (float)SrcVid.Height / (float)priScreen.Height;
                    float yy = (float)SrcVid.Width / (float)priScreen.Width;

                    int ix = Convert.ToInt32(this.rx.Text);
                    int iy = Convert.ToInt32(this.ry.Text);
                    int ih = Convert.ToInt32(this.rh.Text);
                    int iw = Convert.ToInt32(this.rw.Text);
     
                    SrcVid.CroppingLeftMargin = (int)((float)ix * yy);
                    SrcVid.CroppingTopMargin = (int)((float)iy * xx);

                    if (SrcVid.CroppingLeftMargin >= priScreen.Width)
                    {
                        MessageBox.Show("屏幕区域外!");
                        return;
                    }

                    if (SrcVid.CroppingTopMargin >= priScreen.Height)
                    {
                        MessageBox.Show("屏幕区域外!");
                        return;
                    }

                    int ibm = priScreen.Height - ih - iy;

                    if (ibm <= 0)
                    {
                        MessageBox.Show("屏幕区域外!");
                        return;
                    }

                    int irm = priScreen.Width - iw - ix;

                    if (irm <= 0)
                    {
                        MessageBox.Show("屏幕区域外!");
                        return;
                    }
                    SrcVid.CroppingRightMargin = (int)((float)irm * yy);
                    SrcVid.CroppingBottomMargin = (int)((float)ibm * xx);
                }

                #endregion

                //确定压缩方式
                Pro = GetSelectCompressionOption();
                if (Pro == null)
                {
                    MessageBox.Show("错误!请选中 视频压缩模板!");
                    return;
                }
                SrcGrp.set_Profile(Pro);

                //检查输出文件名是否为空
                if (this.OutFilePathTextBox.Text.Length < 1)
                {
                    MessageBox.Show("请指定保存路径!");
                    return;
                }

                输出文件名#region 输出文件名
                string sFile = this.OutFilePathTextBox.Text;
                string sExt = sFile.Substring(sFile.LastIndexOf("."));
                string[] sFileAr = sFile.Split(new char[] { //, / });
                StringBuilder sb = new StringBuilder();
                int i = 0;
                for (i = 0; i < sFileAr.Length - 1; i++)
                {
                    sb.Append(sFileAr[i]);
                    sb.Append("//");
                }
                string sPath = sb.ToString();
                sFile = sFileAr[sFileAr.Length - 1];
                sFile = sFile.Substring(0, sFile.LastIndexOf(.));
                this.OutFilePathTextBox.Text = sPath + sFile + sExt;

                enc.File.LocalFileName = this.OutFilePathTextBox.Text;
                #endregion

                enc.Start();
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }

        }
        /**
        /// <summary>
        /// 构造
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
            //Control.CheckForIllegalCrossThreadCalls = false;
            //加载皮肤
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            string skin = appseting.ReadKeyValue("skin");
            this.SetSkin(skin);
            //
            //初始托盘
            NotificationIcon();
            //
            //窗体大小固定
            this.MinimumSize=this.Size;
            this.MaximumSize = this.Size;
        }
        /** <summary>
        /// 主窗体加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            AppInit();
            InitCompression();
        }
        /** <summary>
        /// 选择输出文件保存路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectOutPathButton_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "WMV文件(*.wmv)|*.wmv";
            sfd.RestoreDirectory = true;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                this.OutFilePathTextBox.Text = sfd.FileName;
                if(File.Exists(sfd.FileName))
                    File.Delete(sfd.FileName);
            }
        }
        /** <summary>
        /// 开始录制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartButton_Click(object sender, EventArgs e)
        {
            if (this.CompressionOptionListBox.SelectedIndex > -1 && this.OutFilePathTextBox.Text.Trim() != "")
            {
               
                th = new Thread( new ThreadStart(start));
                th.IsBackground = true;
                th.Start();
                //将开始按钮不可用
                this.StartButton.Enabled = false;
                //暂停按钮可用
                this.PauseButton.Enabled = true;
                //
                //窗体隐藏
                if (this.ChkHideMainForm.Checked)
                {
                    this.WindowState = FormWindowState.Minimized;
                    this.Visible = false;
                }
            }
            else
            {
                if (this.OutFilePathTextBox.Text.Trim() == "")
                    MessageBox.Show("请选择录像文件保存位置");
                if (this.CompressionOptionListBox.SelectedIndex == -1)
                    MessageBox.Show("请选择一种压缩方案");
            }
        }
        private void start()
        {
            VoidDelegate dstart = new VoidDelegate(StartCamera);
            this.Invoke(dstart);
        }
        /** <summary>
        /// 停止录制按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StopButton_Click(object sender, EventArgs e)
        {
            th.Abort();
            enc.Stop();
            this.StartButton.Enabled = true;
            this.PauseButton.Enabled = false;
           
        }
        /** <summary>
        /// 暂停录制按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PauseButton_Click(object sender, EventArgs e)
        {
            if (this.PauseButton.Text != "继续录制")
            {
                enc.Pause();
                this.PauseButton.Text = "继续录制";
            }
            else
            {
                enc.Start();
                this.PauseButton.Text = "暂停录制";
            }
        }
        /** <summary>
        /// 单击主窗体关闭按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason != CloseReason.ApplicationExitCall && e.CloseReason != CloseReason.WindowsShutDown)
            {
                e.Cancel = true;
                this.WindowState = FormWindowState.Minimized;
                this.Visible= false;
            }
            else
            {
                //none
            }
        }
        /** <summary>
        /// 压缩选项更改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CompressionOptionListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            ListBox lb = (ListBox)sender;
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("Compression", lb.Items[lb.SelectedIndex].ToString());
        }
        /** <summary>
        /// 压缩选项更改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CompressionOptionListBox_MouseClick(object sender, MouseEventArgs e)
        {
            ListBox lb = (ListBox)sender;
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("Compression", lb.Items[lb.SelectedIndex].ToString());
        }

        快捷键#region 快捷键
        /** <summary>
        /// 快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SkStartAndPause_TextChanged(object sender, EventArgs e)
        {
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("SKey_StartAndPause", this.SkStartAndPause.Text);
        }
        //
        private void SkStop_TextChanged(object sender, EventArgs e)
        {
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("SKey_Stop", this.SkStartAndPause.Text);
        }
        //
        private void SkShowAndHide_TextChanged(object sender, EventArgs e)
        {

            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("SKey_ShowAndHide", this.SkShowAndHide.Text);
        }
        #endregion

        #region 录制区域
        private void RScreen_CheckedChanged(object sender, EventArgs e)
        {
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("CameraRect", "0");
        }
        private void RWindow_CheckedChanged(object sender, EventArgs e)
        {
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("CameraRect", "1");
        }
        /** <summary>
        /// 指定屏幕区域
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RectCustom_Click(object sender, EventArgs e)
        {
            if (this.RectCustom.Checked)
            {
                screen = new fScreen();
                this.Hide();
                this.WindowState = FormWindowState.Minimized;
                System.Threading.Thread.Sleep(220);

                //创建一个和屏幕一样大的Bitmap
                Size size = MainForm.GetScreenSize();
                Image myImage = new Bitmap(size.Width, size.Height);
                //从一个继承自Image类的对象中创建Graphics对象
                Graphics gc = Graphics.FromImage(myImage);
                gc.SmoothingMode = SmoothingMode.HighQuality;
                //抓屏并拷贝到myimage里
                gc.CopyFromScreen(new Point(0, 0), new Point(0, 0), size);
                //保存为文件
                screen.BackgroundImage = myImage;
                screen.WindowState = FormWindowState.Maximized;
                screen.TopMost = true;
                screen.ShowDialog();
                screen.Focus();
                screen.TopMost = false;
                screen.Refresh();

                myImage.Dispose();
                gc.Dispose();
            }
            //
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("CameraRect", "2");
        }
        #endregion
        /** <summary>
        /// 是否录声音
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ChkSound_CheckedChanged(object sender, EventArgs e)
        {
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("ChkSound", this.ChkSound.Checked.ToString());
        }
        //是否隐藏主窗体
        private void ChkHideMainForm_CheckedChanged(object sender, EventArgs e)
        {
            ConfigManager.AppSetings appseting = new ConfigManager.AppSetings();
            appseting.UpdateKey("ChkHideMainForm", this.ChkHideMainForm.Checked.ToString());
        }

        /**///
        /// <summary>
        /// 取得屏幕大小
        /// </summary>
        /// <returns></returns>
        public static Size GetScreenSize()
        {
            //获得当前屏幕的分辨率
            Screen scr = Screen.PrimaryScreen;
            Rectangle rc = scr.Bounds;
            Size size = new Size(rc.Width, rc.Height);
            return size;
        }

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值