private void CloseClip() { if (!Application.Current.Dispatcher.CheckAccess()) Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new CloseClipDelegate(CloseClip)); else { try { //Останавливаем таймер обновления позиции if (timer != null) timer.Stop(); if ((this.graphBuilder != null) && (this.VideoElement.Source == null)) { if (this.mediaControl != null) this.mediaControl.Stop(); this.CloseInterfaces(); this.isAudioOnly = true; if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; VHostElement.Visibility = Visibility.Collapsed; } } if (this.VideoElement.Source != null) { VideoElement.Stop(); VideoElement.Close(); VideoElement.Source = null; VideoElement.Visibility = Visibility.Collapsed; if (this.graphBuilder != null) { while (Marshal.ReleaseComObject(this.graphBuilder) > 0) ; this.graphBuilder = null; if (this.graph != null) { while (Marshal.ReleaseComObject(this.graph) > 0) ; this.graph = null; } GC.Collect(); } string mediaUrl = "MediaBridge://MyDataString"; MediaBridgeManager.UnregisterCallback(mediaUrl); } } catch (Exception ex) { System.Windows.MessageBox.Show("CloseClip: " + ex.Message, Languages.Translate("Error"), MessageBoxButton.OK, MessageBoxImage.Error); } SetPlayIcon(); ClearFiltersMenu(); this.Title = "WPF Video Player"; this.currentState = PlayState.Init; this.textbox_time.Text = textbox_duration.Text = "00:00:00"; this.slider_pos.Value = 0.0; Win7Taskbar.SetProgressState(this.Handle, TBPF.NOPROGRESS); } }
private void PlayMovieInWindow() { int hr = 0; this.graphBuilder = (IGraphBuilder)new FilterGraph(); //Добавляем в граф нужный рендерер (Auto - graphBuilder сам выберет рендерер) Settings.VRenderers renderer = Settings.VideoRenderer; if (renderer == Settings.VRenderers.Overlay) { IBaseFilter add_vr = (IBaseFilter)new VideoRenderer(); hr = graphBuilder.AddFilter(add_vr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR7) { IBaseFilter add_vmr = (IBaseFilter)new VideoMixingRenderer(); hr = graphBuilder.AddFilter(add_vmr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR9) { IBaseFilter add_vmr9 = (IBaseFilter)new VideoMixingRenderer9(); hr = graphBuilder.AddFilter(add_vmr9, "Video Mixing Renderer 9"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.EVR) { //Создаём Win32-окно, т.к. использовать WPF-поверхность не получится VHost = new VideoHwndHost(); VHost.RepaintRequired += new EventHandler(VHost_RepaintRequired); VHostElement.Visibility = Visibility.Visible; VHostElement.Child = VHost; VHandle = VHost.Handle; //Добавляем и настраиваем EVR IBaseFilter add_evr = (IBaseFilter)new EnhancedVideoRenderer(); hr = graphBuilder.AddFilter(add_evr, "Enhanced Video Renderer"); DsError.ThrowExceptionForHR(hr); object obj; IMFGetService pGetService = null; pGetService = (IMFGetService)add_evr; hr = pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out obj); MFError.ThrowExceptionForHR(hr); try { EVRControl = (IMFVideoDisplayControl)obj; } catch { Marshal.ReleaseComObject(obj); throw; } //Указываем поверхность hr = EVRControl.SetVideoWindow(VHandle); MFError.ThrowExceptionForHR(hr); //Сохраняем аспект hr = EVRControl.SetAspectRatioMode(MFVideoAspectRatioMode.PreservePicture); MFError.ThrowExceptionForHR(hr); } // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(this.filepath, null); DsError.ThrowExceptionForHR(hr); if (EVRControl == null) { //Ищем рендерер и ВКЛЮЧАЕМ соблюдение аспекта (рендерер сам подгонит картинку под размер окна, с учетом аспекта) IsRendererARFixed = false; IBaseFilter filter = null; graphBuilder.FindFilterByName("Video Renderer", out filter); if (filter != null) { IVMRAspectRatioControl vmr = filter as IVMRAspectRatioControl; if (vmr != null) { DsError.ThrowExceptionForHR(vmr.SetAspectRatioMode(VMRAspectRatioMode.LetterBox)); IsRendererARFixed = true; } } else { graphBuilder.FindFilterByName("Video Mixing Renderer 9", out filter); if (filter != null) { IVMRAspectRatioControl9 vmr9 = filter as IVMRAspectRatioControl9; if (vmr9 != null) { DsError.ThrowExceptionForHR(vmr9.SetAspectRatioMode(VMRAspectRatioMode.LetterBox)); IsRendererARFixed = true; } } } } else IsRendererARFixed = true; this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaEventEx = (IMediaEventEx)this.graphBuilder; this.mediaSeeking = (IMediaSeeking)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; this.videoWindow = (EVRControl == null) ? this.graphBuilder as IVideoWindow : null; this.basicVideo = (EVRControl == null) ? this.graphBuilder as IBasicVideo : null; this.basicAudio = this.graphBuilder as IBasicAudio; this.basicAudio.put_Volume(VolumeSet); this.CheckIsAudioOnly(); if (!this.isAudioOnly) { if (videoWindow != null) { hr = this.videoWindow.put_Owner(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_MessageDrain(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_WindowStyle(DirectShowLib.WindowStyle.Child | DirectShowLib.WindowStyle.ClipSiblings | DirectShowLib.WindowStyle.ClipChildren); DsError.ThrowExceptionForHR(hr); } this.MoveVideoWindow(); } else { if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; VHostElement.Visibility = Visibility.Collapsed; } } hr = this.mediaEventEx.SetNotifyWindow(this.source.Handle, WMGraphNotify, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); //Восстанавливаем старую позицию if (mediaload == MediaLoad.Update && oldpos != TimeSpan.Zero) { if (NaturalDuration >= oldpos) { hr = mediaPosition.put_CurrentPosition(oldpos.TotalSeconds); DsError.ThrowExceptionForHR(hr); } } //Восстанавливаем старый PlayState if (mediaload == MediaLoad.Update && (oldplaystate == PlayState.Paused || oldplaystate == PlayState.Stopped)) { hr = this.mediaControl.Pause(); DsError.ThrowExceptionForHR(hr); this.currentState = PlayState.Paused; this.SetPlayIcon(); } else { hr = this.mediaControl.Run(); DsError.ThrowExceptionForHR(hr); this.currentState = PlayState.Running; this.SetPauseIcon(); } AddFiltersToMenu(); }