Mirror video control in WPF

Guitarmonster

Member
Joined
Mar 24, 2023
Messages
19
Programming Experience
10+
I’m developing a desktop app and want to be able to “mirror” or copy a media element while playing video. The simplest example would be a video playing on the left and right next to it the same video playing as well. A long time ago I thought I learned about something with visual effects that allowed me to create a mirrored reflection below a video. I was thinking the same would apply. I’m not looking for anyone to write code for me, just to point me in the right direction. I keep trying to google “reflection” but this only brings up things that have nothing to do with video.

The project is an application that simulates a vintage analog cable box when flipping channels. As some may remember, flipping analog channels usually resulted in a temporary loss of vertical hold causing the feed to quickly scroll upwards. This effect can be reproduced on my end but I would need to create duplicate copies just above and below the actual video for it to work.

Here is a video of what the effect would look like. Although it happens very fast, after each channel change the vertical hold scrolls up and automatically aligns the picture. I would facilitate this animation in my code, yet I need the missing piece.

Before anyone suggests, playing the same video in three separate media elements would not be sufficient. Doing so would cause too much of a performance hit and would just be a quick fix when a better solution exists.
 
Unfortunately the way modern video playback works with WPF is that DirectShow actually just renders unto the screen rather than on some other surface from which you can easily grab pixels and duplicate elsewhere. I'm not sure if you can set things up for the render surface to be split. Eg. top half is on one surface, while the other half is on another surface. If it's doable, then it's a matter of animating the position and size of those surfaces to get that settle into the channel scrolling effect.
 
A long time ago when I started learning wpf I seem to remember a project where a video was displayed along with a slick looking reflection of that video just below. I have a feeling that whatever was used to do that is my answer. Perhaps bindings of some sort?

I have been trying to find it but unfortunately searching anything with the word reflection brings tons of content related to code reflection, not a visual effect. I know this can be done because I saw it. I remember being in awe at how smooth the reflection was with no latency at all.
 
I figured it out, I knew it was simple!! So simple I couldn't find the answer, which is a typical problem I have.

Bindings!!!

I just created a little WPF test app with a MediaElement on top and a Rectangle below, and tied them together using bindings and it works perfectly with no lag or anything. This is because newer frameworks rely on more advanced OS handling of video and display, giving them the ability to pull off tricks like this without having to actually write code that copies every little pixel one by one with lag. A good example is when Windows 7 first came out where they had Aero, with the ability to preview windows from the Taskbar.

I found the example I was looking for online which demonstrates how to create a slick looking reflection below a control. The code involved flipping the image and applying a gradient to create that fade out effect. I stripped all of that out and just focused on the bindings part which worked perfectly.

XAML:
<Window x:Class="WpfCableTVReceiver.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfCableTVReceiver"
        mc:Ignorable="d"
        Title="MainWindow" Height="538" Width="360">
    <Grid>
        <MediaElement x:Name="MainVideoWindow" HorizontalAlignment="Left" MediaOpened="MainVideoWindow_MediaOpened" Height="240" Margin="10,10,0,0" VerticalAlignment="Top" Width="320" LoadedBehavior="Play" UnloadedBehavior="Manual">

        </MediaElement>
        <Rectangle DataContext="{Binding ElementName=MainVideoWindow}" HorizontalAlignment="Left" Height="240" Margin="10,250,0,0" VerticalAlignment="Top" Width="320">
            <Rectangle.Fill>
                <VisualBrush Visual="{Binding}">
                </VisualBrush>
            </Rectangle.Fill>
        </Rectangle>

    </Grid>
</Window>


Code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfCableTVReceiver
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MainVideoWindow.Source = new Uri(@"\\LIVINGROOM-TV\Media\TvShows\ALF (1986)\Season 1\ALF - S01E02.avi");

        }

        private void MainVideoWindow_MediaOpened(object sender, RoutedEventArgs e)
        {

            MainVideoWindow.Play();

        }

    }
}
 
Back
Top Bottom