C# Windows form application 播放小视频

1. 下载direcly-show lib DLL
点击打开链接

2. DxPlay.cs (可以在下载的例子中找到):

 public class DxPlay : IDisposable
    {
        enum GraphState
        {
            Stopped,
            Paused,
            Running,
            Exiting
        }

        #region Member variables

        // File name we are playing
        private string m_sFileName;

        // graph builder interfaces
        private IFilterGraph2 m_FilterGraph;
        private IMediaControl m_mediaCtrl;
        private IMediaEvent m_mediaEvent;

        // Used to grab current snapshots
        ISampleGrabber m_sampGrabber = null;

        // Grab once.  Used to create bitmap
        private int m_videoWidth;
        private int m_videoHeight;
        private int m_stride;
        private int m_ImageSize; // In bytes

        // Event used by Media Event thread
        private ManualResetEvent m_mre;

        // Current state of the graph (can change async)
        volatile private GraphState m_State = GraphState.Stopped;

#if DEBUG
        // Allow you to "Connect to remote graph" from GraphEdit
        DsROTEntry m_DsRot;
#endif

        #endregion

        // Release everything.
        public void Dispose()
        {
            CloseInterfaces();
        }
        ~DxPlay()
        {
            CloseInterfaces();
        }

        // Event that is called when a clip finishs playing
        public event DxPlayEvent StopPlay;
        public delegate void DxPlayEvent(Object sender);

        // Play an avi file into a window.  Allow for snapshots.
        // (Control to show video in, Avi file to play
        public DxPlay(Control hWin, string FileName)
        {
            try
            {
                int hr;
                IntPtr hEvent;

                // Save off the file name
                m_sFileName = FileName;

                // Set up the graph
                SetupGraph(hWin, FileName);

                // Get the event handle the graph will use to signal
                // when events occur
                hr = m_mediaEvent.GetEventHandle(out hEvent);
                DsError.ThrowExceptionForHR(hr);

                // Wrap the graph event with a ManualResetEvent
                m_mre = new ManualResetEvent(false);
#if USING_NET11
                m_mre.Handle = hEvent;
#else
                m_mre.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(hEvent, true);
#endif

                // Create a new thread to wait for events
                Thread t = new Thread(new ThreadStart(this.EventWait));
                t.Name = "Media Event Thread";
                t.Start();
            }
            catch
            {
                Dispose();
                throw;
            }
        }

        // Wait for events to happen.  This approach uses waiting on an event handle.
        // The nice thing about doing it this way is that you aren‘t in the windows message
        // loop, and don‘t have to worry about re-entrency or taking too long.  Plus, being
        // in a class as we are, we don‘t have access to the message loop.
        // Alternately, you can receive your events as windows messages.  See
        // IMediaEventEx.SetNotifyWindow.
        private void EventWait()
        {
            // Returned when GetEvent is called but there are no events
            const int E_ABORT = unchecked((int)0x80004004);

            int hr;
            IntPtr p1, p2;
            EventCode ec;

            do
            {
                // Wait for an event
                m_mre.WaitOne(-1, true);

                // Avoid contention for m_State
                lock (this)
                {
                    // If we are not shutting down
                    if (m_State != GraphState.Exiting)
                    {
                        // Read the event
                        for (
                            hr = m_mediaEvent.GetEvent(out ec, out p1, out p2, 0);
                            hr >= 0;
                            hr = m_mediaEvent.GetEvent(out ec, out p1, out p2, 0)
                            )
                        {
                            // Write the event name to the debug window
                            Debug.WriteLine(ec.ToString());

                            // If the clip is finished playing
                            if (ec == EventCode.Complete)
                            {
                                // Call Stop() to set state
                                Stop();

                                // Throw event
                                if (StopPlay != null)
                                {
                                    StopPlay(this);
                                }
                            }

                            // Release any resources the message allocated
                            hr = m_mediaEvent.FreeEventParams(ec, p1, p2);
                            DsError.ThrowExceptionForHR(hr);
                        }

                        // If the error that exited the loop wasn‘t due to running out of events
                        if (hr != E_ABORT)
                        {
                            DsError.ThrowExceptionForHR(hr);
                        }
                    }
                    else
                    {
                        // We are shutting down
                        break;
                    }
                }
            } while (true);
        }

        // Return the currently playing file name
        public string FileName
        {
            get
            {
                return m_sFileName;
            }
        }

        // start playing
        public void Start()
        {
            // If we aren‘t already playing (or shutting down)
            if (m_State == GraphState.Stopped || m_State == GraphState.Paused)
            {
                int hr = m_mediaCtrl.Run();
                DsError.ThrowExceptionForHR(hr);

                m_State = GraphState.Running;
            }
        }

        // Pause the capture graph.
        public void Pause()
        {
            // If we are playing
            if (m_State == GraphState.Running)
            {
                int hr = m_mediaCtrl.Pause();
                DsError.ThrowExceptionForHR(hr);

                m_State = GraphState.Paused;
            }
        }
        // Pause the capture graph.
        public void Stop()
        {
            // Can only Stop when playing or paused
            if (m_State == GraphState.Running || m_State == GraphState.Paused)
            {
                int hr = m_mediaCtrl.Stop();
                DsError.ThrowExceptionForHR(hr);

                m_State = GraphState.Stopped;
            }
        }

        // Reset the clip back to the beginning
        public void Rewind()
        {
            int hr;

            IMediaPosition imp = m_FilterGraph as IMediaPosition;
            hr = imp.put_CurrentPosition(0);
        }

        // Grab a snapshot of the most recent image played.
        // Returns A pointer to the raw pixel data. Caller must release this memory with
        // Marshal.FreeCoTaskMem when it is no longer needed.
        public IntPtr SnapShot()
        {
            int hr;
            IntPtr ip = IntPtr.Zero;
            int iBuffSize = 0;

            // Read the buffer size
            hr = m_sampGrabber.GetCurrentBuffer(ref iBuffSize, ip);
            DsError.ThrowExceptionForHR(hr);

            Debug.Assert(iBuffSize == m_ImageSize, "Unexpected buffer size");

            // Allocate the buffer and read it
            ip = Marshal.AllocCoTaskMem(iBuffSize);

            hr = m_sampGrabber.GetCurrentBuffer(ref iBuffSize, ip);
            DsError.ThrowExceptionForHR(hr);

            return ip;
        }

        // Convert a point to the raw pixel data to a .NET bitmap
        public Bitmap IPToBmp(IntPtr ip)
        {
            // We know the Bits Per Pixel is 24 (3 bytes) because we forced it
            // to be with sampGrabber.SetMediaType()
            int iBufSize = m_videoWidth * m_videoHeight * 3;

            return new Bitmap(
                m_videoWidth,
                m_videoHeight,
                -m_stride,
                PixelFormat.Format24bppRgb,
                (IntPtr)(ip.ToInt32() + iBufSize - m_stride)
                );
        }

        // Build the capture graph for grabber and renderer.</summary>
        // (Control to show video in, Filename to play)
        private void SetupGraph(Control hWin, string FileName)
        {
            int hr;

            // Get the graphbuilder object
            m_FilterGraph = new FilterGraph() as IFilterGraph2;

            // Get a ICaptureGraphBuilder2 to help build the graph
            ICaptureGraphBuilder2 icgb2 = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;

            try
            {
                // Link the ICaptureGraphBuilder2 to the IFilterGraph2
                hr = icgb2.SetFiltergraph(m_FilterGraph);
                DsError.ThrowExceptionForHR(hr);

#if DEBUG
                // Allows you to view the graph with GraphEdit File/Connect
                m_DsRot = new DsROTEntry(m_FilterGraph);
#endif
                // Add the filters necessary to render the file.  This function will
                // work with a number of different file types.
                IBaseFilter sourceFilter = null;
                hr = m_FilterGraph.AddSourceFilter(FileName, FileName, out sourceFilter);
                DsError.ThrowExceptionForHR(hr);

                // Get the SampleGrabber interface
                m_sampGrabber = (ISampleGrabber)new SampleGrabber();
                IBaseFilter baseGrabFlt = (IBaseFilter)m_sampGrabber;

                // Configure the Sample Grabber
                ConfigureSampleGrabber(m_sampGrabber);

                // Add it to the filter
                hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
                DsError.ThrowExceptionForHR(hr);

                // Connect the pieces together, use the default renderer
                hr = icgb2.RenderStream(null, null, sourceFilter, baseGrabFlt, null);
                DsError.ThrowExceptionForHR(hr);

                // Now that the graph is built, read the dimensions of the bitmaps we‘ll be getting
                SaveSizeInfo(m_sampGrabber);

                // Configure the Video Window
                IVideoWindow videoWindow = m_FilterGraph as IVideoWindow;
                ConfigureVideoWindow(videoWindow, hWin);

                // Grab some other interfaces
                m_mediaEvent = m_FilterGraph as IMediaEvent;
                m_mediaCtrl = m_FilterGraph as IMediaControl;
            }
            finally
            {
                if (icgb2 != null)
                {
                    Marshal.ReleaseComObject(icgb2);
                    icgb2 = null;
                }
            }
#if DEBUG
            // Double check to make sure we aren‘t releasing something
            // important.
            GC.Collect();
            GC.WaitForPendingFinalizers();
#endif
        }

        // Configure the video window
        private void ConfigureVideoWindow(IVideoWindow videoWindow, Control hWin)
        {
            int hr;

            // Set the output window
            hr = videoWindow.put_Owner(hWin.Handle);
            DsError.ThrowExceptionForHR(hr);

            // Set the window style
            hr = videoWindow.put_WindowStyle((WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings));
            DsError.ThrowExceptionForHR(hr);

            // Make the window visible
            hr = videoWindow.put_Visible(OABool.True);
            DsError.ThrowExceptionForHR(hr);

            // Position the playing location
            Rectangle rc = hWin.ClientRectangle;
            hr = videoWindow.SetWindowPosition(0, 0, rc.Right, rc.Bottom);
            DsError.ThrowExceptionForHR(hr);
        }

        // Set the options on the sample grabber
        private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
        {
            AMMediaType media;
            int hr;

            // Set the media type to Video/RBG24
            media = new AMMediaType();
            media.majorType = MediaType.Video;
            media.subType = MediaSubType.RGB24;
            media.formatType = FormatType.VideoInfo;
            hr = sampGrabber.SetMediaType(media);
            DsError.ThrowExceptionForHR(hr);

            DsUtils.FreeAMMediaType(media);
            media = null;

            // Configure the samplegrabber
            hr = sampGrabber.SetBufferSamples(true);
            DsError.ThrowExceptionForHR(hr);
        }

        // Save the size parameters for use in SnapShot
        private void SaveSizeInfo(ISampleGrabber sampGrabber)
        {
            int hr;

            // Get the media type from the SampleGrabber
            AMMediaType media = new AMMediaType();

            hr = sampGrabber.GetConnectedMediaType(media);
            DsError.ThrowExceptionForHR(hr);

            try
            {

                if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
                {
                    throw new NotSupportedException("Unknown Grabber Media Format");
                }

                // Get the struct
                VideoInfoHeader videoInfoHeader = new VideoInfoHeader();
                Marshal.PtrToStructure(media.formatPtr, videoInfoHeader);

                // Grab the size info
                m_videoWidth = videoInfoHeader.BmiHeader.Width;
                m_videoHeight = videoInfoHeader.BmiHeader.Height;
                m_stride = videoInfoHeader.BmiHeader.ImageSize / m_videoHeight;
                m_ImageSize = videoInfoHeader.BmiHeader.ImageSize;
            }
            finally
            {
                DsUtils.FreeAMMediaType(media);
                media = null;
            }
        }

        // Shut down capture
        private void CloseInterfaces()
        {
            int hr;

            lock (this)
            {
                if (m_State != GraphState.Exiting)
                {
                    m_State = GraphState.Exiting;

                    // Release the thread (if the thread was started)
                    if (m_mre != null)
                    {
                        m_mre.Set();
                    }
                }

                if (m_mediaCtrl != null)
                {
                    // Stop the graph
                    hr = m_mediaCtrl.Stop();
                    m_mediaCtrl = null;
                }

                if (m_sampGrabber != null)
                {
                    Marshal.ReleaseComObject(m_sampGrabber);
                    m_sampGrabber = null;
                }

#if DEBUG
                if (m_DsRot != null)
                {
                    m_DsRot.Dispose();
                }
#endif

                if (m_FilterGraph != null)
                {
                    Marshal.ReleaseComObject(m_FilterGraph);
                    m_FilterGraph = null;
                }
            }
            GC.Collect();
        }
    }

3. 将Player加载到指定的panel中,本例需要循环播放,因此在stopplay中自动start()

private DxPlay m_play;
        private void LoadVideoIntoPanel()
        {
            try
            {
                var pathBase = Path.GetDirectoryName(Application.ExecutablePath);
                var path = Path.Combine(pathBase, bgVideo);
                // Open the file, provide a handle to play it in
                m_play = new DxPlay(_videoBackground, path);
                m_play.Start();

                // Let us know when the file is finished playing
                m_play.StopPlay += sender =>
                {
                    // Rewind clip to beginning to allow DxPlay.Start to work again.
                    m_play.Rewind();
                    m_play.Start();
                };

            }
            catch (Exception ex)
            {
                _log.Error("Video Playing Error ==> " + ex.Message + "\r\n" + ex.StackTrace);
            }
        }
时间: 2024-12-18 03:56:20

C# Windows form application 播放小视频的相关文章

在.NET Windows Form Application中统一处理未处理的异常总结

在Windows Form Application中,异常若最终得不到处理,则会触发AppDomain.CurrentDomain.UnhandledException事件进行以进行最终的异常记录(使用此事件无法避免应用程序的终结).在此事件被触发之前,分以下情况可决定是否将异常继续传播. 主线程 使用Application.SetUnhandledExceptionMode(bool)方法预先设置处理模式: 若为UnhandledExceptionMode.ThrowException,则表示

C#之Windows Form Application与attribute

1. WPF是什么: Windows Presentation Foundation, 它提供了统一的编程模型.语言和框架,真正做到了分离界面设计人员与开发人员的工作, WPF由XAML( eXtensible Application Markup Language )语言编写. 2. Windows Form Project是由几个文件构成的:它们有不同的功能划分 3. 对于一个应用,最重要的就是对用户的各种events做出反应,那么监听器的实现就非常重要,而VS将监听器的设计界面化,我们只需

c#学习笔记之WPF Application和Windows Form Applications

一.WPF Application WPF使用XAML(extensible application markup language)可扩展应用程序标记语言,来进行页面的操纵,非常简便易懂. 下面一段代码,就是使用xaml语言对页面进行布局 <Window x:Class="WpfApplication1.Window1"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

微信电脑版微信1.1 for Windows更新 可@人/转发撤回消息/可播小视频

微信电脑版微信1.1 for Windows发布更新了,版本号为1.1.0.18,群聊可@人/可转发撤回消息/可播小视频,功能越来越接近微信手机版了. 本次更新的一些新特点: 群聊中可以@人. 消息可以转发. 2分钟内发出的消息可以撤回. 可播放收到的小视频. 微信电脑版微信1.1 for Windows这次更新幅度不小,可以更愉快地在电脑上聊天了 查看之前版本有什么特性:微信电脑版-微信for windows客户端发布

如何在asp.net中如何在线播放各类视频文件

一.后台拼字符串动态加载写法 前台调用代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < html xmlns="http://www.w3.org/1999/xhtml" > < head id="Head

android webview 通过html5播放在线视频 切换大屏

1.添加网络访问权限 <uses-permission android:name="android.permission.INTERNET" /> 2.webview添加全屏支持 developer官方文档关于html5支持视频播放描述如下:In order to support inline HTML5 video in your application, you need to have hardware acceleration turned on, and set

Liam的C# 学习历程(七):WPF(Windows Presentation Foundation)、Windows Form Applications

在今天的课堂中,老师向我们讲述了关于一些WPF(Windows Presentation Foundation)和Windows Form Applications的内容,接下来就让我们一起来复习一下: (一).WPF(Windows Presentation Foundation): WPF是一个重要运用于desktop手机开发方面.它使用到了一种XML的变形语言——XAML的语言(eXtensible Application Markup Language). 使用XAML开发人员可以对WP

VLC播放RTSP视频延迟问题 (转)

原帖地址:http://blog.chinaunix.net/uid-26611383-id-3755283.html ================================================================================ 之前写过一篇关于在Linux平台上编译android平台上VLC播放器源代码的文章,vlc这款播放器非常优秀而且是开源的,它的核心是开源视频编解码库ffmpeg.而且这款播放器还支持RTSP协议,这个主要是用开源的li

小视频-上传视频

为什么做小视频? 快手,抖音,小红书都是我们熟知的小视频.小视频的诞生 可以获取更多的流量. .py class Upload_img(APIView): #kindeditor上传方法 def post(self,request): item = {} file = request.FILES.get('file') orderno = datetime.datetime.now() orderno = str(orderno).replace('-','').replace(' ','').