title: C#: is it possible to generate or fake a visual tree in a service?
body: <p>I have a windowsservice that is supposed to generate thumbprints of videos.
  To achieve this i am trying to use the MediaElement-class (<a href="https://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement(v=vs.110).aspx" rel="nofollow noreferrer">https://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement(v=vs.110).aspx</a>). To fire events when opening medias this element has to be in a visualtree. Is it possible to simulate or fake a visual tree ?</p>
  
  <p>Edit: I now use MediaPlayer instead of MediaElements but can't rely on the events because they are not thrown.</p>
  
  <p>Updated code</p>
  
  <pre><code>        public class Mp4ThumbnailExtractor : IDisposable
  {
      private ManualResetEvent waitHandle;
      private TimeSpan mediaOpenTimeout;
  
      public TimeSpan Time { get; set; }
          = TimeSpan.Parse("00:00:30");
  
      public TimeSpan FallbackTime { get; set; }
          = TimeSpan.Parse("00:00:10");
  
      public int Height { get; set; }
          = 400;
  
      public int Width { get; set; }
          = 400;
  
      public int Dpi { get; set; }
          = 96;
  
      public Mp4ThumbnailExtractor()
      {
          waitHandle = new ManualResetEvent(false);
          mediaOpenTimeout = TimeSpan.Parse("00:00:15");
      }
  
      public MemoryStream CreateThumbnail(string videoPath)
      {
          MemoryStream memory = new MemoryStream();
          Uri sourceUri = new Uri(videoPath);
  
          MediaPlayer media = new MediaPlayer();
          media.MediaOpened += Media_MediaOpened;
          media.ScrubbingEnabled = true;
  
          try
          {
              media.Open(new Uri(videoPath));
  
              //TODO: media.opened event will not get fired
              Thread.Sleep(mediaOpenTimeout);
              waitHandle.Set();
  
              //15sec timeout for loading the media
              if (waitHandle.WaitOne(mediaOpenTimeout))
              {
                  SetPosition(media);
  
                  //TODO: this is bad...
                  Thread.Sleep(2000);
  
                  DrawingVisual dv = new DrawingVisual();
                  DrawingContext dc = dv.RenderOpen();
                  dc.DrawVideo(media, new Rect(0, 0, Width, Height));
                  dc.Close();
                  RenderTargetBitmap bmp = new RenderTargetBitmap(Width, Height, Dpi, Dpi, PixelFormats.Pbgra32);
                  bmp.Render(dv);
  
                  JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                  encoder.Frames.Add(BitmapFrame.Create(bmp));
                  encoder.Save(memory);
  
                  memory.Seek(0, SeekOrigin.Begin);
              }
              else
              {
                  throw new Exception($"Unable to open media '{videoPath}' in '{mediaOpenTimeout}'");
              }
          }
          finally
          {
              media.Close();
          }
          return memory;
      }
  
      private void SetPosition(MediaPlayer player)
      {
          if (player.NaturalDuration.HasTimeSpan)
          {
              TimeSpan naturalTime = player.NaturalDuration.TimeSpan;
              if (naturalTime &lt; Time)
              {
                  if (naturalTime &gt; FallbackTime)
                  {
                      player.Position = FallbackTime;
                  }
              }
              else
              {
                  player.Position = Time;
              }
          }
      }
  
      private void Media_MediaOpened(object sender, EventArgs e)
      {
          waitHandle.Set();
      }
  
      public void Dispose()
      {
          waitHandle.Dispose();
      }
  }
  </code></pre>