private void PlayMovieInWindow(string filename) { fps = 0; 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.None); MFError.ThrowExceptionForHR(hr); } // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(filename, null); DsError.ThrowExceptionForHR(hr); if (EVRControl == null) { //Ищем рендерер и отключаем соблюдение аспекта (аспект будет определяться размерами видео-окна) 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.None)); } 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.None)); } } } // QueryInterface for DirectShow interfaces this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaEventEx = (IMediaEventEx)this.graphBuilder; this.mediaSeeking = (IMediaSeeking)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; // Query for video interfaces, which may not be relevant for audio files this.videoWindow = (EVRControl == null) ? this.graphBuilder as IVideoWindow : null; this.basicVideo = (EVRControl == null) ? this.graphBuilder as IBasicVideo : null; // Query for audio interfaces, which may not be relevant for video-only files this.basicAudio = this.graphBuilder as IBasicAudio; basicAudio.put_Volume(VolumeSet); //Ввод в ДиректШоу значения VolumeSet для установки громкости // Is this an audio-only file (no video component)? CheckIsAudioOnly(); if (!this.IsAudioOnly) { if (videoWindow != null) { // Setup the video window 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); //Определяем fps double AvgTimePerFrame; hr = basicVideo.get_AvgTimePerFrame(out AvgTimePerFrame); DsError.ThrowExceptionForHR(hr); fps = (1.0 / AvgTimePerFrame); } else if (EVRControl != null) { //Определяем fps DetermineEVRFPS(); } //Ловим ошибку Ависинта IsAviSynthError = false; if (NaturalDuration.TotalMilliseconds == 10000.0) { //Признаки ошибки: duration=10000.0 и fps=24 (округлённо) if ((int)fps == 24 || fps == 0) IsAviSynthError = true; } MoveVideoWindow(); } else { if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; VHostElement.Visibility = Visibility.Collapsed; VHostElement.Width = VHostElement.Height = 0; VHostElement.Margin = new Thickness(0); } //Ловим ошибку Ависинта 2 (когда нет видео окна) IsAviSynthError = (NaturalDuration.TotalMilliseconds == 10000.0); if (m.isvideo) { //Видео должно было быть.. PreviewError("NO VIDEO", Brushes.Gainsboro); } } //Если выше не удалось определить fps - берём значение из массива if (fps == 0) fps = Calculate.ConvertStringToDouble(m.outframerate); // Have the graph signal event via window callbacks for performance hr = this.mediaEventEx.SetNotifyWindow(this.source.Handle, WMGraphNotify, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); if (mediaload == MediaLoad.update) //Перенесено из HandleGraphEvent, теперь позиция устанавливается до начала воспроизведения, т.е. за один заход, а не за два { if (NaturalDuration >= oldpos) //Позиционируем только если нужная позиция укладывается в допустимый диапазон mediaPosition.put_CurrentPosition(oldpos.TotalSeconds); //else // mediaPosition.put_CurrentPosition(NaturalDuration.TotalSeconds); //Ограничиваем позицию длиной клипа } // Run the graph to play the media file if (currentState == PlayState.Running) { //Продолжение воспроизведения, если статус до обновления был Running DsError.ThrowExceptionForHR(this.mediaControl.Run()); SetPauseIcon(); } else { //Запуск с паузы, если была пауза или это новое открытие файла DsError.ThrowExceptionForHR(this.mediaControl.Pause()); this.currentState = PlayState.Paused; SetPlayIcon(); } }
private void PlayMovieInWindow(string filename) { if (filename == string.Empty) return; 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.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.None); MFError.ThrowExceptionForHR(hr); } // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(filename, null); DsError.ThrowExceptionForHR(hr); if (EVRControl == null) { //Ищем рендерер и отключаем соблюдение аспекта (аспект будет определяться размерами видео-окна) 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.None)); } 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.None)); } } } // QueryInterface for DirectShow interfaces this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaEventEx = (IMediaEventEx)this.graphBuilder; this.mediaSeeking = (IMediaSeeking)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; // Query for video interfaces, which may not be relevant for audio files this.videoWindow = (EVRControl == null) ? this.graphBuilder as IVideoWindow : null; this.basicVideo = (EVRControl == null) ? this.graphBuilder as IBasicVideo : null; // Query for audio interfaces, which may not be relevant for video-only files this.basicAudio = this.graphBuilder as IBasicAudio; basicAudio.put_Volume(-(int)(10000 - Math.Pow(Settings.VolumeLevel, 1.0 / 5) * 10000)); //Громкость для ДиректШоу // Is this an audio-only file (no video component)? CheckIsAudioOnly(); if (!this.isAudioOnly) { //Определяем аспект, если он нам не известен if (in_ar == 0) { MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(filepath); in_ar = media.Aspect; media.Close(); } if (videoWindow != null) { // Setup the video window hr = this.videoWindow.put_Owner(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_WindowStyle(DirectShowLib.WindowStyle.Child | DirectShowLib.WindowStyle.ClipSiblings | DirectShowLib.WindowStyle.ClipChildren); DsError.ThrowExceptionForHR(hr); } MoveVideoWindow(); } else { if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; } } // Have the graph signal event via window callbacks for performance hr = this.mediaEventEx.SetNotifyWindow(this.source.Handle, WMGraphNotify, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); this.Focus(); // Run the graph to play the media file hr = this.mediaControl.Run(); DsError.ThrowExceptionForHR(hr); this.currentState = PlayState.Running; SetPauseIcon(); double duration = 0.0; hr = mediaPosition.get_Duration(out duration); DsError.ThrowExceptionForHR(hr); slider_pos.Maximum = duration; //Запускаем таймер обновления позиции if (timer != null) timer.Start(); }
private void CloseClip() { try { //Останавливаем таймер обновления позиции if (timer != null) timer.Stop(); //DirectShow if (this.graphBuilder != null && this.VideoElement.Source == null) { int hr = 0; // Stop media playback if (this.mediaControl != null) hr = this.mediaControl.Stop(); // Free DirectShow interfaces CloseInterfaces(); //EVR if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; VHostElement.Visibility = Visibility.Collapsed; VHostElement.Width = VHostElement.Height = 0; VHostElement.Margin = new Thickness(0); } // No current media state if (mediaload != MediaLoad.update) this.currentState = PlayState.Init; } //MediaBridge if (this.VideoElement.Source != null) { VideoElement.Stop(); VideoElement.Close(); VideoElement.Source = null; VideoElement.Visibility = Visibility.Collapsed; VideoElement.Width = VideoElement.Height = 0; VideoElement.Margin = new Thickness(0); if (mediaload != MediaLoad.update) this.currentState = PlayState.Init; 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; } //Marshal.ReleaseComObject(this.graphBuilder); //this.graphBuilder = null; //Marshal.ReleaseComObject(this.graph); //this.graph = null; GC.Collect(); } Thread.Sleep(100); string url = "MediaBridge://MyDataString"; MediaBridge.MediaBridgeManager.UnregisterCallback(url); } //ScriptView if (script_box.Visibility != Visibility.Collapsed) { script_box.Clear(); script_box.Visibility = Visibility.Collapsed; this.currentState = PlayState.Init; } //AviSynthPlayer (PictureView) if (avsPlayer != null) { avsPlayer.Abort(); avsPlayer.Close(); avsPlayer = null; Pic.Source = null; Pic.Visibility = Visibility.Collapsed; Pic.Margin = new Thickness(0); Pic.Width = Pic.Height = 0; if (mediaload != MediaLoad.update) this.currentState = PlayState.Init; } //Окно ошибок if (ErrBox.Visibility != Visibility.Collapsed) { ErrBox.Child = null; ErrBox.Visibility = Visibility.Collapsed; } } catch (Exception ex) { ErrorException("CloseClip: " + ex.Message, ex.StackTrace); } //update titles textbox_name.Text = textbox_frame.Text = ""; textbox_time.Text = textbox_duration.Text = "00:00:00"; progress_top.Width = slider_pos.Value = 0.0; SetPlayIcon(); }
private void CloseClip() { try { //Останавливаем таймер обновления позиции if (timer != null) timer.Stop(); if (this.graphBuilder != null && this.VideoElement.Source == null) { int hr = 0; // Stop media playback if (this.mediaControl != null) hr = this.mediaControl.Stop(); // Clear global flags this.currentState = PlayState.Stopped; // Free DirectShow interfaces CloseInterfaces(); this.isAudioOnly = true; //Перенесено сюда if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; } // No current media state this.currentState = PlayState.Init; } else if (this.VideoElement.Source != null) { VideoElement.Stop(); VideoElement.Source = null; this.currentState = PlayState.Init; 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; } //Marshal.ReleaseComObject(this.graphBuilder); //this.graphBuilder = null; //Marshal.ReleaseComObject(this.graph); //this.graph = null; GC.Collect(); } Thread.Sleep(100); string url = "MediaBridge://MyDataString"; MediaBridge.MediaBridgeManager.UnregisterCallback(url); } } catch (Exception ex) { ErrorException("CloseClip: " + ex.Message, ex.StackTrace); } //update titles textbox_time.Text = "00:00:00"; progress_top.Width = 0.0; slider_pos.Value = 0.0; in_ar = 0; }