/// <summary> /// Handles the video view layout updates. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void HandleVideoViewLayoutUpdates(object sender, EventArgs e) { if (ContentGrid.Children.IndexOf(VideoView) < 0 || VideoView.Element == null) { return; } // Compute the position offset of the video var videoPosition = VideoView.HasOwnDispatcher ? VideoView.TransformToAncestor(ContentGrid).Transform(new Point(0, 0)) : VideoView.Element.TransformToAncestor(ContentGrid).Transform(new Point(0, 0)); // Compute the dimensions of the video var videoSize = VideoView.HasOwnDispatcher ? VideoView.RenderSize : VideoView.Element.DesiredSize; // Validate the dimensions; avoid layout operations with invalid values if (videoSize.Width <= 0 || double.IsNaN(videoSize.Width) || videoSize.Height <= 0 || double.IsNaN(videoSize.Height)) { return; } if (HasVideo || Library.IsInDesignMode) { // Position and Size the Captions View CaptionsView.Width = Math.Floor(videoSize.Width); CaptionsView.Height = Math.Floor(videoSize.Height * .80); // FCC Safe Caption Area Dimensions CaptionsView.Margin = new Thickness( Math.Floor(videoPosition.X + ((videoSize.Width - CaptionsView.RenderSize.Width) / 2d)), Math.Floor(videoPosition.Y + ((videoSize.Height - CaptionsView.RenderSize.Height) / 2d)), 0, 0); CaptionsView.Visibility = Visibility.Visible; // Position and Size the Subtitles View SubtitlesView.Width = Math.Floor(videoSize.Width * 0.9d); SubtitlesView.Height = Math.Floor(videoSize.Height / 8d); SubtitlesView.Margin = new Thickness( Math.Floor(videoPosition.X + ((videoSize.Width - SubtitlesView.RenderSize.Width) / 2d)), Math.Floor(videoPosition.Y + videoSize.Height - (1.8 * SubtitlesView.RenderSize.Height)), 0, 0); SubtitlesView.Visibility = Visibility.Visible; } else { CaptionsView.Width = 0; CaptionsView.Height = 0; CaptionsView.Visibility = Visibility.Collapsed; SubtitlesView.Width = 0; SubtitlesView.Height = 0; SubtitlesView.Visibility = Visibility.Collapsed; } }
/// <summary> /// Initializes a new instance of the <see cref="MediaElement" /> class. /// </summary> public MediaElement() : base() { ContentGrid = new Grid { Name = nameof(ContentGrid) }; Content = ContentGrid; ContentGrid.HorizontalAlignment = HorizontalAlignment.Stretch; ContentGrid.VerticalAlignment = VerticalAlignment.Stretch; Stretch = VideoView.Stretch; StretchDirection = VideoView.StretchDirection; // Add the child controls ContentGrid.Children.Add(VideoView); ContentGrid.Children.Add(SubtitleView); SubtitleView.Padding = new Thickness(5, 0, 5, 0); SubtitleView.FontSize = 60; SubtitleView.FontFamily = new System.Windows.Media.FontFamily("Arial Rounded MT Bold"); SubtitleView.FontWeight = FontWeights.Normal; SubtitleView.TextOutlineWidth = new Thickness(4); SubtitleView.TextForeground = System.Windows.Media.Brushes.LightYellow; // Update as the VideoView updates but check if there are valid dimensions and it actually has video VideoView.LayoutUpdated += (s, e) => { // When video dimensions are invalid, let's not do any layout. if (VideoView.ActualWidth <= 0 || VideoView.ActualHeight <= 0) { return; } // Position the Subtitles var videoViewPosition = VideoView.TransformToAncestor(ContentGrid).Transform(new Point(0, 0)); var targetHeight = VideoView.ActualHeight / 5d; var targetWidth = VideoView.ActualWidth; if (SubtitleView.Height != targetHeight) { SubtitleView.Height = targetHeight; } if (SubtitleView.Width != targetWidth) { SubtitleView.Width = targetWidth; } var verticalOffset = ContentGrid.ActualHeight - (videoViewPosition.Y + VideoView.ActualHeight); var verticalOffsetPadding = VideoView.ActualHeight / 20; var marginBottom = verticalOffset + verticalOffsetPadding; if (SubtitleView.Margin.Bottom != marginBottom) { SubtitleView.Margin = new Thickness(0, 0, 0, marginBottom); } }; // Display the control (or not) if (WindowsPlatform.Instance.IsInDesignTime) { // Shows an FFmpeg image if we are in design-time var bitmap = Properties.Resources.FFmpegMediaElementBackground; var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap( bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var controlBitmap = new WriteableBitmap(bitmapSource); VideoView.Source = controlBitmap; } else { // Setup the media engine MediaCore = new MediaEngine(this, new WindowsMediaConnector(this)); } }